ArcGisRuntime100.14绘制曲线
有时,在地图上显示为曲线的形状实际上是一系列连接的线性段,它们近似于曲线。对于许多用例(并且取决于您对数据所需的准确性),这是表示弯曲特征的可接受方式。ArcGIS 还可以使用准确表示曲线几何的线段来存储和显示几何。EllipticArcSegment在 ArcGIS Runtime 中,曲线段由或CubicBezierSegment类的实例表示。这些线段称为 真曲线。
您可以将曲线段添加到aMultipartBuilder中,如果几何体具有曲线,则曲线段会在适用的情况下从构成多部分几何体的集合中返回。曲线和线性段可以在同一个多部分几何图形中混合在一起。
您可以使用GeometryEngine.Densify()基于多个线性段的真实曲线创建近似曲线。这样的曲线通常被称为致密曲线。默认情况下,不会从支持曲线的服务中获取曲线几何图形,这意味着将返回真实曲线几何图形的致密版本。用于ServiceCurveGeometryMode更改此默认行为。
OnlyAllowTrueCurveUpdatesByTrueCurveClients默认情况下,无法更新存储在服务中的曲线几何图形为 true。要更新此类几何图形,请确保您的应用在整个工作流程中正确处理几何图形中的曲线段并设置ServiceCurveGeometryMode为TrueCurveClient
. 您必须在对服务进行任何调用之前执行此操作,因为在发出第一个请求后无法更改它。
效果图
源代码
<esri:MapView Map="{Binding Map, Source={StaticResource MapViewModel}}" GraphicsOverlays="{Binding GraphicsOverlay,Source={StaticResource MapViewModel}}" >
/esri:MapView>
public class MapViewModel : INotifyPropertyChanged
{
public MapViewModel()
{
_map = new Map(SpatialReferences.WebMercator);
GraphicsOverlay graphicsOverlay = MakeCurvedGraphicsOverlay();
this.graphicsOverlay = new GraphicsOverlayCollection();
this.graphicsOverlay.Add(graphicsOverlay);
}
private GraphicsOverlayCollection graphicsOverlay;
public GraphicsOverlayCollection GraphicsOverlay
{
get { return graphicsOverlay; }
set { graphicsOverlay = value; OnPropertyChanged(); }
}
private Map _map;
/// <summary>
/// Gets or sets the map
/// </summary>
public Map Map
{
get => _map;
set { _map = value; OnPropertyChanged(); }
}
/// <summary>
/// Raises the <see cref="MapViewModel.PropertyChanged" /> event
/// </summary>
/// <param name="propertyName">The name of the property that has changed</param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler PropertyChanged;
private GraphicsOverlay MakeCurvedGraphicsOverlay()
{
// Create a simple fill symbol with outline.
SimpleLineSymbol curvedLineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Black, 1);
SimpleFillSymbol curvedFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.Red, curvedLineSymbol);
// Create a graphics overlay for the polygons with curve segments.
GraphicsOverlay curvedGraphicsOverlay = new GraphicsOverlay();
// Create and assign a simple renderer to the graphics overlay.
curvedGraphicsOverlay.Renderer = new SimpleRenderer(curvedFillSymbol);
// Create a heart-shaped graphic.
MapPoint origin = new MapPoint(x: 40e5, y: 5e5, SpatialReferences.WebMercator);
Geometry heartGeometry = MakeHeartGeometry(origin, 10e5);
Graphic heartGraphic = new Graphic(heartGeometry);
curvedGraphicsOverlay.Graphics.Add(heartGraphic);
return curvedGraphicsOverlay;
}
private Geometry MakeHeartGeometry(MapPoint center, double sideLength)
{
if (sideLength <= 0) return null;
SpatialReference spatialReference = center.SpatialReference;
// The x and y coordinates to simplify the calculation.
double minX = center.X - 0.5 * sideLength;
double minY = center.Y - 0.5 * sideLength;
// The radius of the arcs.
double arcRadius = sideLength * 0.25;
// Bottom left curve.
MapPoint leftCurveStart = new MapPoint(center.X, minY, spatialReference);
MapPoint leftCurveEnd = new MapPoint(minX, minY + 0.75 * sideLength, spatialReference);
MapPoint leftControlMapPoint1 = new MapPoint(center.X, minY + 0.25 * sideLength, spatialReference);
MapPoint leftControlMapPoint2 = new MapPoint(minX, center.Y, spatialReference: spatialReference);
CubicBezierSegment leftCurve = new CubicBezierSegment(leftCurveStart, leftControlMapPoint1, leftControlMapPoint2, leftCurveEnd, spatialReference);
// Top left arc.
MapPoint leftArcCenter = new MapPoint(minX + 0.25 * sideLength, minY + 0.75 * sideLength, spatialReference);
EllipticArcSegment leftArc = EllipticArcSegment.CreateCircularEllipticArc(leftArcCenter, arcRadius, Math.PI, centralAngle: -Math.PI, spatialReference);
// Top right arc.
MapPoint rightArcCenter = new MapPoint(minX + 0.75 * sideLength, minY + 0.75 * sideLength, spatialReference);
EllipticArcSegment rightArc = EllipticArcSegment.CreateCircularEllipticArc(rightArcCenter, arcRadius, Math.PI, centralAngle: -Math.PI, spatialReference);
// Bottom right curve.
MapPoint rightCurveStart = new MapPoint(minX + sideLength, minY + 0.75 * sideLength, spatialReference);
MapPoint rightCurveEnd = leftCurveStart;
MapPoint rightControlMapPoint1 = new MapPoint(minX + sideLength, center.Y, spatialReference);
MapPoint rightControlMapPoint2 = leftControlMapPoint1;
CubicBezierSegment rightCurve = new CubicBezierSegment(rightCurveStart, rightControlMapPoint1, rightControlMapPoint2, rightCurveEnd, spatialReference);
// Create the heart polygon.
Part newPart = new Part(new Segment[]
{
leftCurve,
leftArc,
rightArc,
rightCurve
}, spatialReference);
PolygonBuilder builder = new PolygonBuilder(spatialReference);
builder.AddPart(newPart);
return builder.ToGeometry();
}
}