我被赋予了使用ArcGIS .net SDK在应用程序中创建路线的任务,我正在做的是在用户点击MapView并在光标上创建线时在列表以及地图上添加点从最后一个输入点开始的位置,现在,如果我需要在其他两个点之间编辑一个点,则必须从这两个点绘制线到运动中的光标位置,这些线画得很好,但是问题是第二条线是从编辑点,我已经尝试调试,折线正在接收正确的点,即编辑点的上一个和下一个,
用户控制
public partial class RoutePlanningControl : UserControl
{
private int count = 1;
private MapPoint currentPoint, nextPoint;
private readonly GraphicsOverlay _overlay = new GraphicsOverlay();
private readonly GraphicsOverlay _linesOverlay = new GraphicsOverlay();
private ObservableCollection<RoutePoint> routePoints;
public RoutePlanningControl()
{
InitializeComponent();
Initialize();
}
private async void Initialize()
{
routePoints = new ObservableCollection<RoutePoint>();
// Initialize the map with an oceans basemap
RouteMapView.Map = new Map(Basemap.CreateOpenStreetMap());
RouteMapView.Cursor = ((FrameworkElement)this.Resources["CursorSelect"]).Cursor;
// Add the graphics overlay to the map
RouteMapView.GraphicsOverlays.Add(new GraphicsOverlay());
// Create the starting point
MapPoint startingPoint = new MapPoint(0, 0, SpatialReferences.Wgs84);
// Update the UI with the initial point
UpdateCursorCoordinatesFromMapPoint(startingPoint);
//Add overlay layers to the map.
RouteMapView.GraphicsOverlays.Add(_overlay);
RouteMapView.GraphicsOverlays.Add(_linesOverlay);
//Add datagrid Itemsource
DgRoutePoints.ItemsSource = routePoints;
//Events
RouteMapView.GeoViewTapped += RouteMapView_GeoViewTappedAsync;
RouteMapView.MouseMove += RouteMapView_MouseMove; ;
}
// Problem is here
private void RouteMapView_MouseMove(object sender, MouseEventArgs e)
{
if (RouteMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry) == null)
return;
Point screenPoint = e.GetPosition(RouteMapView);
MapPoint movingMapPoint = RouteMapView.ScreenToLocation(screenPoint);
movingMapPoint = MapGraphicsHelper.GetProjectedMapPoint(movingMapPoint);
if (currentPoint != null)
{
//If there is already a point reference in currentpoint then draw a line from that to cursor position
_linesOverlay.Graphics.Clear();
_linesOverlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(currentPoint, movingMapPoint));
if (nextPoint != null)
{
//If there is already a point reference in nextPoint then also draw a line from that to cursor position
_linesOverlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(movingMapPoint, nextPoint));
}
}
else
{
_linesOverlay.Graphics.Clear();
if (nextPoint != null)
{
_linesOverlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(movingMapPoint, nextPoint));
}
}
}
private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object source = e.OriginalSource;
if (source.GetType() == typeof(Image))
{
DgRoutePoints.IsReadOnly = false;
var cell = (DataGridCell)sender;
if ((cell.Column.Header.ToString().ToUpperInvariant() == "EDIT"))
{
// If Edit Column cell is clicked then get rowindex of that cell
int rowindex = DataGridRow.GetRowContainingElement(cell).GetIndex();
if (rowindex >= 0)
{
//Get previous RoutePoint of edited point in currentRoutePoint
var currentRoutePoint = routePoints.Where(rp => rp.SerialNo == rowindex).FirstOrDefault();
//Get next RoutePoint of edited point in nextRoutePoint.
var nextRoutePoint = routePoints.Where(rp => rp.SerialNo == rowindex + 2).FirstOrDefault();
if (currentRoutePoint != null)
{
//Cast RoutePoint to MapPoint
try
{
var currentMapPoint = new MapPoint(double.Parse(currentRoutePoint.Latitude), double.Parse(currentRoutePoint.Longitude), SpatialReferences.Wgs84);
this.currentPoint = currentMapPoint;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
else
{
currentPoint = null;
}
if (nextRoutePoint != null)
{
//Cast RoutePoint to MapPoint
try
{
var nextMapPoint = new MapPoint(double.Parse(nextRoutePoint.Latitude), double.Parse(nextRoutePoint.Longitude), SpatialReferences.Wgs84);
this.nextPoint = nextMapPoint;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}
}
}
}
private void RouteMapView_GeoViewTappedAsync(object sender, GeoViewInputEventArgs e)
{
//Draw lines and Add points to the RoutePoint List on tap.
if (currentPoint == null && nextPoint == null)
{
currentPoint = MapGraphicsHelper.GetProjectedMapPoint(e.Location);
_overlay.Graphics.Add(MapGraphicsHelper.CreateColouredCircle(currentPoint, System.Drawing.Color.Brown));
MapGraphicsHelper.CreateTextAtPoint(currentPoint, (count).ToString(), Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center,
Esri.ArcGISRuntime.Symbology.VerticalAlignment.Middle);
routePoints.Add(new RoutePoint
{
SerialNo = count,
Name = count.ToString(),
Latitude = currentPoint.X.ToString("0.0000"),
Longitude = currentPoint.Y.ToString("0.0000"),
TotalDistance = 0,
TotalDistanceUnit = ArcGis.Core.DistanceUnit.NM.ToString(),
});
}
else
{
if (nextPoint != null && currentPoint == null)
{
var newPoint = MapGraphicsHelper.GetProjectedMapPoint(e.Location);
_overlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(newPoint, nextPoint));
}
else
{
var newPoint = MapGraphicsHelper.GetProjectedMapPoint(e.Location);
_overlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(currentPoint, newPoint));
var distanceWithUnit = MapGraphicsHelper.CalculateDistance(currentPoint, newPoint, GeodeticCurveType.Loxodrome);
routePoints.Add(new RoutePoint
{
SerialNo = count,
Name = count.ToString(),
Latitude = currentPoint.X.ToString(),
Longitude = currentPoint.Y.ToString(),
TotalDistance = routePoints.Sum(point => point.TotalDistance) + distanceWithUnit.Distance,
TotalDistanceUnit = distanceWithUnit.DistanceUnit.Abbreviation,
});
if (nextPoint != null)
{
_overlay.Graphics.Add(MapGraphicsHelper.CreateLineFromPoints(newPoint, nextPoint));
nextPoint = null;
var lastPoint = routePoints.LastOrDefault();
if (lastPoint != null)
{
currentPoint = new MapPoint(double.Parse(lastPoint.Latitude), double.Parse(lastPoint.Longitude), SpatialReferences.Wgs84);
}
}
else
{
currentPoint = newPoint;
}
_overlay.Graphics.Add(MapGraphicsHelper.CreateColouredCircle(currentPoint, System.Drawing.Color.Brown));
MapGraphicsHelper.CreateTextAtPoint(currentPoint, (count).ToString(), Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center,
Esri.ArcGISRuntime.Symbology.VerticalAlignment.Middle);
}
}
count++;
}
private void NewRoute_Checked(object sender, RoutedEventArgs e)
{
VoyageControlsExpander.IsEnabled = true;
VoyageControlsExpander.IsExpanded = true;
RouteMapView.IsEnabled = true;
saveRoute.IsEnabled = true;
newRoute.IsEnabled = false;
}
private void NewRoute_Unchecked(object sender, RoutedEventArgs e)
{
VoyageControlsExpander.IsEnabled = false;
VoyageControlsExpander.IsExpanded = false;
}
private void UpdateCursorCoordinatesFromMapPoint(MapPoint selectedPoint)
{
try
{
// Check if the selected point can be formatted into coordinates.
CoordinateFormatter.ToLatitudeLongitude(selectedPoint, LatitudeLongitudeFormat.DecimalDegrees, 0);
}
catch (Exception e)
{
// Check if the excpetion is because the coordinates are out of range.
if (e.Message == "Invalid argument: coordinates are out of range")
{
// Clear the selectionss symbol.
RouteMapView.GraphicsOverlays[0].Graphics.Clear();
}
return;
}
}
}
这是CreateLineFromPoints方法
public static Graphic CreateLineFromPoints(MapPoint startPoint, MapPoint endPoint)
{
SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Dash, System.Drawing.Color.Green, 2);
// Create a new point collection for polyline
Esri.ArcGISRuntime.Geometry.PointCollection points = new Esri.ArcGISRuntime.Geometry.PointCollection(SpatialReferences.Wgs84)
{
GetProjectedMapPoint(startPoint),
GetProjectedMapPoint(endPoint)
};
// Create the polyline from the point collection
Esri.ArcGISRuntime.Geometry.Polyline polyline = new Polyline(points);
// Create the graphic with polyline and symbol
Graphic graphic = new Graphic(polyline, lineSymbol);
// Add graphic to the graphics overlay
//_overlay.Graphics.Add(graphic);
return graphic;
}