在ArcGIS中用点创建折线时出现问题

时间:2018-12-05 07:26:43

标签: .net wpf arcgis arcgis-runtime

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

0 个答案:

没有答案