如何居中/设置地图缩放以覆盖Xamarin.Forms上可见的所有标记
本文关键字:Forms Xamarin 设置 何居中 地图 缩放 覆盖 | 更新日期: 2023-09-27 18:01:09
我正在为我的地图设置多个标记
我可以静态设置缩放级别和中心
但我想要的是居中到所有的标记和缩放级别来填充所有可见的标记
我可以使用Gmaps.MoveToRegion方法来接收MapSpan。问题是,我不知道如何计算显示所有标记所需的MapSpan。
我正在使用Xamarin.Forms.Maps和Xam.Plugin.MapExtend.Abstractions
提前感谢!
首先,您需要将自定义地图渲染添加到您的android项目中,该项目将继承MapRenderer、GoogleMap.IInfoWindowAdapter
public class MyMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter
我添加了2个专用字段
private GoogleMap _map;
private LatLngBounds.Builder _builder;
在构造函数中初始化您的_builder:
public MyMapRenderer(Context context) : base(context)
{
_builder = new LatLngBounds.Builder();
}
当覆盖OnMapReady方法时,将GoogleMap属性设置为:
protected override void OnMapReady(GoogleMap map)
{
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
if (_map == null)
{
_map = map;
}
}
你需要覆盖CreateMarker方法,这样你就可以更改你的缩放级别
protected override MarkerOptions CreateMarker(Pin pin)
{
var p = (THHPin)pin;
var marker = new MarkerOptions();
LatLng position = new LatLng(pin.Position.Latitude, pin.Position.Longitude);
marker.SetPosition(position);
marker.SetTitle(pin.Label);
marker.SetSnippet(pin.Address);
_builder.Include(position);
LatLngBounds bounds = _builder.Build();
CameraUpdate cu = CameraUpdateFactory.NewLatLngBounds(bounds, 20);
_map.MoveCamera(cu);
return marker;
}
我用在这里找到的算法解决了这个该死的问题:http://www.movable-type.co.uk/scripts/latlong.html
在Xamarin是这样的smth:
var radioTierra = 6371000; //metros
var latitud1Radianes = pos1.Latitude * (Math.PI / 180.0);
var latitud2Radianes = pos2.Latitude * (Math.PI / 180.0);
var longitud1Radianes = pos1.Longitude * (Math.PI / 180.0);
var deltaLatitud = (pos2.Latitude - pos1.Latitude) * (Math.PI / 180.0);
var deltaLongitud = (pos2.Longitude - pos1.Longitude) * (Math.PI / 180.0);
var sumando1 = Math.Sin(deltaLatitud / 2) * Math.Sin(deltaLatitud / 2);
var sumando2 = Math.Cos(latitud1Radianes) * Math.Cos(latitud2Radianes) * Math.Sin(deltaLongitud / 2) * Math.Sin(deltaLongitud / 2);
List<double> sumandos = new List<double>();
sumandos.Add(sumando1);
sumandos.Add(sumando2);
var a = sumandos.Sum();
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var distance = radioTierra * c;
/* Δφ es deltaLatitud
* Δλ es deltaLongitud*/
var Bx = Math.Cos(latitud2Radianes) * Math.Cos(deltaLongitud);
var By = Math.Cos(latitud2Radianes) * Math.Sin(deltaLongitud);
var φ3 = Math.Atan2(Math.Sin(latitud1Radianes) + Math.Sin(latitud2Radianes),
Math.Sqrt((Math.Cos(latitud1Radianes) + Bx) * (Math.Cos(latitud2Radianes) + Bx) + By * By));//Latitud del punto medio
var λ3 = longitud1Radianes + Math.Atan2(By, Math.Cos(longitud1Radianes) + Bx);//Longitud del punto medio
var centro = new Xamarin.Forms.Maps.Position(φ3, λ3);
Distance distancia = new Xamarin.Forms.Maps.Distance(distance + 0.2);
Gmaps.MoveToRegion(MapSpan.FromCenterAndRadius(centro, distancia));
我成功地使用了下面的c#代码。只需将每个标记的位置记录为LatLng对象即可。
locationManager = (LocationManager)GetSystemService(Context.LocationService);
Criteria criteria = new Criteria();
criteria.Accuracy = Accuracy.Fine;
criteria.PowerRequirement = Power.Low;
provider = locationManager.GetBestProvider(criteria, true);
location = locationManager.GetLastKnownLocation(provider);
marker1lat = location.Latitude;
marker1lng = location.Longitude;
marker2lat = location.Latitude;
marker2lng = location.Longitude;
LatLng marker1LatLng = new LatLng(marker1lat, marker1lng);
Latlng marker2LatLng = new LatLng(marker2lat, marker2lng);
LatLngBounds.Builder b = new LatLngBounds.Builder()
.Include(marker1LatLng)
.Include(marker2LatLng);
mMap.MoveCamera(CameraUpdateFactory.NewLatLngBounds(b.Build(), 120));