如果您正在寻找完整的折线、图钉、图块、UIOptions(以及很快的 3D 效果)渲染/实现,您应该在我在 GitHub 上创建的公共 github 上进行搜索XamarinByEmixam23/..../地图 https://github.com/Emixam23/XamarinByEmixam23/tree/master/Detailed%20Part/Controls/Map.
我搜索了很多,但仍然遇到同样的问题:
如何更新、刷新或重新加载 Xamarin.Forms.Maps?
在类定义(类 CustomMap : Map)中,没有更新地图的方法。也许 MVVM 逻辑可以解决这个问题,但我在网上找不到它。
我按照这个地图教程进行操作:使用地图 https://developer.xamarin.com/guides/xamarin-forms/working-with/maps/
为了自定义它,我遵循了本教程:在地图上突出显示路线 https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/maps/map-overlay/polyline/
所以,在这些教程之后(我做了同样的事情,没有改变),我尝试使用 2 个路线坐标,这给了我一条直线......然后我制作了一个完美运行的算法。
方向图
public class DirectionMap
{
public Distance distance { get; set; }
public Duration duration { get; set; }
public Address address_start { get; set; }
public Address address_end { get; set; }
public List<Step> steps { get; set; }
public class Distance
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration
{
public string text { get; set; }
public int value { get; set; }
}
public class Address
{
public string text { get; set; }
public Position position { get; set; }
}
public class Step
{
public Position start { get; set; }
public Position end { get; set; }
}
}
响应Http解析器
public static void parseDirectionGoogleMapsResponse(HttpStatusCode httpStatusCode, JObject json, Action<DirectionMap, string> callback)
{
switch (httpStatusCode)
{
case HttpStatusCode.OK:
DirectionMap directionMap = null;
string strException = null;
try
{
directionMap = new DirectionMap()
{
distance = new DirectionMap.Distance()
{
text = (json["routes"][0]["legs"][0]["distance"]["text"]).ToString(),
value = Int32.Parse((json["routes"][0]["legs"][0]["distance"]["value"]).ToString())
},
duration = new DirectionMap.Duration()
{
text = (json["routes"][0]["legs"][0]["duration"]["text"]).ToString(),
value = Int32.Parse((json["routes"][0]["legs"][0]["duration"]["value"]).ToString())
},
address_start = new DirectionMap.Address()
{
text = (json["routes"][0]["legs"][0]["start_address"]).ToString(),
position = new Position(Double.Parse((json["routes"][0]["legs"][0]["start_location"]["lat"]).ToString()), Double.Parse((json["routes"][0]["legs"][0]["start_location"]["lng"]).ToString()))
},
address_end = new DirectionMap.Address()
{
text = (json["routes"][0]["legs"][0]["end_address"]).ToString(),
position = new Position(Double.Parse((json["routes"][0]["legs"][0]["end_location"]["lat"]).ToString()), Double.Parse((json["routes"][0]["legs"][0]["end_location"]["lng"]).ToString()))
}
};
bool finished = false;
directionMap.steps = new List<Step>();
int index = 0;
while (!finished)
{
try
{
Step step = new Step()
{
start = new Position(Double.Parse((json["routes"][0]["legs"][0]["steps"][index]["start_location"]["lat"]).ToString()), Double.Parse((json["routes"][0]["legs"][0]["steps"][index]["start_location"]["lng"]).ToString())),
end = new Position(Double.Parse((json["routes"][0]["legs"][0]["steps"][index]["end_location"]["lat"]).ToString()), Double.Parse((json["routes"][0]["legs"][0]["steps"][index]["end_location"]["lng"]).ToString()))
};
directionMap.steps.Add(step);
index++;
}
catch (Exception e)
{
finished = true;
}
}
}
catch (Exception e)
{
directionMap = null;
strException = e.ToString();
}
finally
{
callback(directionMap, strException);
}
break;
default:
switch (httpStatusCode)
{
}
callback(null, json.ToString());
break;
}
}
我只是获取一些私人计算的距离和持续时间,并获取放入 List 中的每一步;
一切完成后,我使用回调将我们带回控制器(MapPage.xaml.cs XAML 表单页面(Xamarin Portable))
现在,一切都变得奇怪了。就像地图没有意识到所做的更改一样
public partial class MapPage : ContentPage
{
public MapPage()
{
InitializeComponent();
setupMap();
setupMapCustom();
}
public void setupMapCustom()
{
customMap.RouteCoordinates.Add(new Position(37.785559, -122.396728));
customMap.RouteCoordinates.Add(new Position(37.780624, -122.390541));
customMap.RouteCoordinates.Add(new Position(37.777113, -122.394983));
customMap.RouteCoordinates.Add(new Position(37.776831, -122.394627));
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37.79752, -122.40183), Xamarin.Forms.Maps.Distance.FromMiles(1.0)));
}
public async void setupMap()
{
customMap.MapType = MapType.Satellite;
string origin = "72100 Le Mans";
string destination = "75000 Paris";
HttpRequest.getDirections(origin, destination, callbackDirections);
customMap.RouteCoordinates.Add(await MapUtilities.GetMapPointOfStreetAddress(origin));
Position position = await MapUtilities.GetMapPointOfStreetAddress(destination);
//customMap.RouteCoordinates.Add(position);
var pin = new Pin
{
Type = PinType.Place,
Position = position,
Label = "Destination !!",
};
customMap.Pins.Add(pin);
}
private async void callbackDirections(Object obj, string str)
{
if (obj != null)
{
DirectionMap directionMap = obj as DirectionMap;
foreach (Step step in directionMap.steps)
{
customMap.RouteCoordinates.Add(step.start);
System.Diagnostics.Debug.WriteLine("add step");
}
customMap.RouteCoordinates.Add(directionMap.address_end.position);
System.Diagnostics.Debug.WriteLine("add last step");
}
else
{
System.Diagnostics.Debug.WriteLine(str);
}
}
}
我运行我的应用程序,一切正常,直到速度很快,因为我的算法等花费了时间,回调来得太晚了,然后我需要刷新、重新加载或更新我的地图...无论如何,我需要更新我的地图未来的地图,所以...如果有人可以提供帮助,欢迎这个!
EDIT 1我看了你的答案(非常感谢!;))但它不起作用:/
我更新了自定义地图正如你所做的那样
public class CustomMap : Map
{
public static readonly BindableProperty RouteCoordinatesProperty =
BindableProperty.Create<CustomMap, List<Position>>(p => p.RouteCoordinates, new List<Position>());
public List<Position> RouteCoordinates
{
get { return (List<Position>)GetValue(RouteCoordinatesProperty); }
set { SetValue(RouteCoordinatesProperty, value); }
}
public CustomMap()
{
RouteCoordinates = new List<Position>();
}
}
同样适用于自定义地图渲染器 (Droid)
public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback
{
GoogleMap map;
Polyline polyline;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
}
if (e.NewElement != null)
{
((MapView)Control).GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
{
UpdatePolyLine();
}
}
private void UpdatePolyLine()
{
if (polyline != null)
{
polyline.Remove();
polyline.Dispose();
}
var polylineOptions = new PolylineOptions();
polylineOptions.InvokeColor(0x66FF0000);
foreach (var position in ((CustomMap)this.Element).RouteCoordinates)
{
polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
}
polyline = map.AddPolyline(polylineOptions);
}
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
UpdatePolyLine();
}
}
因此,对于最后的更改,在我的 MapPage.xaml.cs 中,我按照您的解释对回调方向进行了更改(我希望我做得很好)
private async void callbackDirections(Object obj, string str)
{
if (obj != null)
{
Device.BeginInvokeOnMainThread(() =>
{
DirectionMap directionMap = obj as DirectionMap;
var list = new List<Position>(customMap.RouteCoordinates);
foreach (Step step in directionMap.steps)
{
list.Add(directionMap.address_end.position);
System.Diagnostics.Debug.WriteLine("add step");
}
System.Diagnostics.Debug.WriteLine("last step");
customMap.RouteCoordinates = list;
System.Diagnostics.Debug.WriteLine("finished?");
});
}
else
{
System.Diagnostics.Debug.WriteLine(str);
}
}
地图仍然不显示折线:/我只做了这些更改,我没有更改以前的代码中的任何其他内容。
我没有告诉你,但我不是 MVVM 绑定方面的专家,所以如果我忘记了什么,我很抱歉:/
EDIT 2因此,在您回答并阅读、阅读和重新阅读您的答案之后,MapPage.xaml.cs 中有我的“测试代码”
public MapPage()
{
InitializeComponent();
//HttpRequest.getDirections(origin, destination, callbackDirections);
Device.BeginInvokeOnMainThread(() =>
{
customMap.RouteCoordinates = new List<Position>
{
new Position (37.797534, -122.401827),
new Position (37.776831, -122.394627)
};
});
//setupMap();
//setupMapCustom();
}
因为它(对我来说)不起作用,所以我查看了我的代码,然后我看到了public static readonly BindableProperty RouteCoordinatesProperty =
BindableProperty.Create<CustomMap, List<Position>>(
p => p.RouteCoordinates, new List<Position>());
已弃用..
所以我对此很红post https://forums.xamarin.com/discussion/59503/xamarin-forms-2-1-0-pre5-released/p3实现此绑定的另一种方式,但它也表示这种方式已被弃用SEE HERE https://developer.xamarin.com/api/member/Xamarin.Forms.BindableProperty.Create%7BTDeclarer,TPropertyType%7D/p/System.Linq.Expressions.Expression%7BSystem.Func%7BTDeclarer,TPropertyType%7D%7D/TPropertyType/Xamarin.Forms.BindingMode/Xamarin.Forms.BindableProperty+ValidateValueDelegate%7BTPropertyType%7D/Xamarin.Forms.BindableProperty+BindingPropertyChangedDelegate%7BTPropertyType%7D/Xamarin.Forms.BindableProperty+BindingPropertyChangingDelegate%7BTPropertyType%7D/Xamarin.Forms.BindableProperty+CoerceValueDelegate%7BTPropertyType%7D/Xamarin.Forms.BindableProperty+CreateDefaultValueDelegate%7BTDeclarer,TPropertyType%7D/...我还看到了一些关于绑定的教程,其中说他们将一些代码放入他们的xaml中,让我记住你我的
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NAMESPACE;assembly=NAMESPACE"
x:Class="NAMESPACE.Controlers.MapPage">
<ContentPage.Content>
<local:CustomMap x:Name="customMap"/>
</ContentPage.Content>
</ContentPage>
我没有使用 ItemSsource="{Polyline Bindable}" 之类的东西