Мне было поручено создать маршрут в приложении с использованием 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;
}