我被赋予了使用 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;
}