C# 在运行时使用Xamarin.Forms.Maps创建多段线时,如何附加位置?
我正在运行时创建一个。如果属性是只读的,如何动态追加 在运行时创建多段线 在文档后面创建多段线:。此链接是一个在代码中具有固定位置的教程。如何在运行时动态分配位置C# 在运行时使用Xamarin.Forms.Maps创建多段线时,如何附加位置?,c#,json,xamarin,polyline,xamarin.forms.maps,C#,Json,Xamarin,Polyline,Xamarin.forms.maps,我正在运行时创建一个。如果属性是只读的,如何动态追加 在运行时创建多段线 在文档后面创建多段线:。此链接是一个在代码中具有固定位置的教程。如何在运行时动态分配位置 using Xamarin.Forms.Maps; // ... Map map = new Map { // ... }; 创建一个对象来存储路由数据(从json提取的数据) 将路由对象序列化为JsonString public void RouteAppend(MapRoute route) { JsonString.A
using Xamarin.Forms.Maps;
// ...
Map map = new Map
{
// ...
};
创建一个对象来存储路由数据(从json提取的数据)
将路由对象序列化为JsonString
public void RouteAppend(MapRoute route)
{
JsonString.Append(JsonSerializer.Serialize(route));
JsonString.Append(",");
}
在现实生活中,jsonString中有2个以上的元素(jsonString中存储了1000多个元素)
如何解决此问题?虽然是一个get only属性,但返回的IList
不是只读集合,因此您可以在构建后向其添加位置
对象
因此,您可以创建以下factory方法:
public static class PolylineFactory
{
const string latitudeJsonName = "Lat";
const string longitudeJsonName = "Lng";
public static Polyline FromLatLngJson(string jsonString, float? strokeWidth = default, Color strokeColor = default)
{
using var doc = JsonDocument.Parse(jsonString);
var query = doc.RootElement.EnumerateArray()
// GetProperty performs property name matching as an ordinal, case-sensitive comparison.
.Select(e => new Position(e.GetProperty(latitudeJsonName).GetDouble(), e.GetProperty(longitudeJsonName).GetDouble()));
var polyline = new Polyline();
if (strokeColor != default)
polyline.StrokeColor = strokeColor;
if (strokeWidth != default)
polyline.StrokeWidth = strokeWidth.Value;
foreach (var position in query)
polyline.Geopath.Add(position);
return polyline;
}
}
或者,在.NET 5JsonSerializer
中,支持使用单个参数化构造函数对对象进行反序列化,因此如果您稍微修改MapRoute
类,如下所示,您可以将jsonString
反序列化为列表
:
public class MapRoute
{
public long timestamp { get; set; }
public double lat { get; set; }
public double lng { get; set; }
public MapRoute(long timestamp, double lat, double lng)
{
// The constructor argument names and property names must match for JsonSerializer to bind to the constructor successfully
this.timestamp = timestamp;
this.lat = lat;
this.lng = lng;
}
}
public static class PolylineFactory
{
public static Polyline FromLatLngJson(string jsonString, float? strokeWidth = default, Color strokeColor = default)
{
var routes = JsonSerializer.Deserialize<List<MapRoute>>(jsonString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
var polyline = new Polyline();
if (strokeColor != default)
polyline.StrokeColor = strokeColor;
if (strokeWidth != default)
polyline.StrokeWidth = strokeWidth.Value;
foreach (var route in routes)
polyline.Geopath.Add(new Position(route.lat, route.lng));
return polyline;
}
}
注:
- 将属性名称匹配作为顺序、区分大小写的比较来执行,因此您需要传递
和“Lat”
,而不是“Lng”
和“Lat”
,因为您的“Lng”
是pascal大小写的,而不是驼峰大小写的 如果这是您的问题中的一个错误,并且您的JSON字符串实际上是驼峰大小写的,请适当修改jsonString
和latitudeJsonName
如果在获取属性时需要忽略大小写,请参阅longitudeJsonName
- 使用当前线程区域性的格式约定解释传入值。例如,在许多欧洲地区,在格式化浮点值时,
逗号用作十进制分隔符。由于这与JSON标准不一致,因此最好使用内置方法,该方法将始终使用正确的十进制分隔符,
- 是一次性的:
此类利用池内存中的资源,在高使用率场景中最小化垃圾收集器(GC)的影响。未能正确处理此对象将导致内存无法返回池,这将增加框架各个部分的GC影响
在代码中,您不会处理
,但您应该这样做文档
演示小提琴1使用
JsonDocument
,2使用mapproute
谢谢您的帮助,我将尽快应用您的建议应用您的建议应用您的建议,问题已经解决。非常感谢。
// instantiate a polyline
Polyline polyline = new Polyline
{
StrokeColor = Color.Blue,
StrokeWidth = 12,
Geopath = pos // It is a readonly property, cannot assign pos to Geopath
}
// add the polyline to the map's MapElements collection
map.MapElements.Add(polyline);
public static class PolylineFactory
{
const string latitudeJsonName = "Lat";
const string longitudeJsonName = "Lng";
public static Polyline FromLatLngJson(string jsonString, float? strokeWidth = default, Color strokeColor = default)
{
using var doc = JsonDocument.Parse(jsonString);
var query = doc.RootElement.EnumerateArray()
// GetProperty performs property name matching as an ordinal, case-sensitive comparison.
.Select(e => new Position(e.GetProperty(latitudeJsonName).GetDouble(), e.GetProperty(longitudeJsonName).GetDouble()));
var polyline = new Polyline();
if (strokeColor != default)
polyline.StrokeColor = strokeColor;
if (strokeWidth != default)
polyline.StrokeWidth = strokeWidth.Value;
foreach (var position in query)
polyline.Geopath.Add(position);
return polyline;
}
}
public class MapRoute
{
public long timestamp { get; set; }
public double lat { get; set; }
public double lng { get; set; }
public MapRoute(long timestamp, double lat, double lng)
{
// The constructor argument names and property names must match for JsonSerializer to bind to the constructor successfully
this.timestamp = timestamp;
this.lat = lat;
this.lng = lng;
}
}
public static class PolylineFactory
{
public static Polyline FromLatLngJson(string jsonString, float? strokeWidth = default, Color strokeColor = default)
{
var routes = JsonSerializer.Deserialize<List<MapRoute>>(jsonString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
var polyline = new Polyline();
if (strokeColor != default)
polyline.StrokeColor = strokeColor;
if (strokeWidth != default)
polyline.StrokeWidth = strokeWidth.Value;
foreach (var route in routes)
polyline.Geopath.Add(new Position(route.lat, route.lng));
return polyline;
}
}
var polyline = PolylineFactory.FromLatLngJson(jsonString, 12, Color.Blue);