Проблема при создании полилиний с точками в ArcGIS - PullRequest
0 голосов
/ 05 декабря 2018

Мне было поручено создать маршрут в приложении с использованием ArcGIS .net SDK. Я занимаюсь добавлением точек в список, а также на карту, когда пользователь нажимает на MapView и создает линию на курсореположение от последней входной точки, теперь я, если мне нужно отредактировать точку между двумя другими точками, необходимо провести линии от этих двух точек до положения курсора при движении, эти линии хорошо рисуются, но проблема в том, что вторая линия рисуется изотредактированная точка, я уже пробовал отладку, и ломаная получает правильные точки, т.е. предыдущую и следующую отредактированную точку,

UserControl window Вот что я сделал

Пользовательский элемент управления

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;
    }
...