Create multi segment lines in WPF

206
3
a month ago
Labels (2)
ThomasZanis
New Contributor

Hello Thank you for any help.

To get right to it:

Summary:

I am trying to figure out the work flow on creating and editing a multi segment line in esri .net for wpf:

Esri Version: 100.15.0

.Net Framework 4.7.2

Details:

We are using the Sketcheditor to create/edit our geometry for our Features in our end user application. We received a request to add the ability to create and edit multi segment polylines. I have been digging through Documentation trying to see if there is a pre-built solution or workflow. I have included out Sketch editor code. Not sure what other information i need to include. Let me know Thank you

public partial class SketchControl : UserControl, INotifyPropertyChanged
{
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var propertyChangedHandler = PropertyChanged;
        if (propertyChangedHandler != null)
            propertyChangedHandler(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private ALViewModel _vm;


    private bool _selectFromMapEnabled = true;
    public bool selectFromMapEnabled
    {
        get { return _selectFromMapEnabled; }
        set
        {
            _selectFromMapEnabled = value;
            OnPropertyChanged();
        }
    }
    private PolygonBuilder _PolygonBuilder;
    public PolygonBuilder PolygonBuilder
    {
        get { return _PolygonBuilder; }
        set
        {
            _PolygonBuilder = value;
            OnPropertyChanged();
        }
    }

    private bool _selectingFromMap = false;
    public bool selectingFromMap
    {
        get { return _selectingFromMap; }
        set
        {
            _selectingFromMap = value;
            OnPropertyChanged();
        }
    }

    private double _animateTo = 1.0;
    public double animateTo
    {
        get { return _animateTo; }
        set
        {
            _animateTo = value;
            OnPropertyChanged();
        }
    }

    public PolylineBuilder lineBuilder;
    // Need dependency objects

    public static readonly DependencyProperty SelectFromLayerProperty =
        DependencyProperty.Register("SelectFromLayer", typeof(string), typeof(SketchControl), new FrameworkPropertyMetadata(null));

    public string SelectFromLayer
    {
        get { return (string)GetValue(SelectFromLayerProperty); }
        set { SetValue(SelectFromLayerProperty, value); }
    }

    public static readonly DependencyProperty AllowSelectFromMapProperty =
       DependencyProperty.Register("AllowSelectFromMap", typeof(bool), typeof(SketchControl), new FrameworkPropertyMetadata(null));

    public bool AllowSelectFromMap
    {
        get { return (bool)GetValue(AllowSelectFromMapProperty); }
        set { SetValue(AllowSelectFromMapProperty, value); }
    }



    public SketchControl()
    {
        //var sketchEditor = _vm.MapControlMap.SketchEditor;
        _vm = FindResource("ALvm") as ALViewModel;

        InitializeComponent();
        // Set the sketch editor as the page's data context
        DataContext = _vm.MapControlMap.SketchEditor;

        _vm.MapControlMap.SketchEditor.CompleteCommand.CanExecuteChanged += CanExecuteChanged;
        _vm.MapControlMap.SketchEditor.GeometryChanged += SEGeometryChanged;

        _vm.MapControlMap.SketchEditor.CancelCommand.CanExecuteChanged += cancelSketch;
    }

    private void cancelSketch(object sender, EventArgs e)
    {
        ICommand command = (ICommand)sender;
        if (command == _vm.MapControlMap.SketchEditor.CancelCommand)
        {
            //_vm.WaitIndicatorText = "Feature added";
            //_vm.WaitIndicatorVisible = false;
            //var sketchEditor = _vm.MapControlMap.SketchEditor;
            //sketchEditor.CancelCommand.Execute(null);
            selectFromMapEnabled = true;
            selectingFromMap = false;
        }

    }

    private async void Sb_Start_Click(object sender, RoutedEventArgs e)
    {
        if (_vm.Current_Feature.Geometry == null)
        {
            // Create Geometry
        }
        else
        {
            // Edit Geometry
            SketchEditConfiguration sem = new SketchEditConfiguration();
            sem.AllowMove = true;
            sem.AllowRotate = true;
            sem.AllowVertexEditing = true;
            sem.ResizeMode = SketchResizeMode.Uniform;
            sem.VertexEditMode = SketchVertexEditMode.InteractionEdit;
            sem.
            


            Geometry geometry = _vm.Current_Feature.Geometry;
            SketchCreationMode sm = ALViewModel.geometrytype2SketchCreationMode(geometry.GeometryType);

            try
            {
                _vm.MapControlMap.Cursor = Cursors.Pen;

                // If the map has a different spatial reference than the feature layer, we must reproject the feature layer to match.
                // Otherwise, the SketchEditor will fail.

                SpatialReference old_sr = geometry.SpatialReference;
                geometry = GeometryEngine.Project(geometry, _vm.MapControlMap.SpatialReference);
                _vm.MapControlMap.SketchEditor.IsVisible = true;
             
                geometry = await _vm.MapControlMap.SketchEditor.StartAsync(geometry, sm, sem);
                _vm.MapControlMap.SketchEditor.IsVisible = false;
                // Reproject the edited geometry back to the original spatial reference.
                _vm.Current_Feature.Geometry = GeometryEngine.Project(geometry, old_sr);
            }

            catch (TaskCanceledException)
            {
                // Ignore ... let the user cancel drawing
            }
            catch (Exception ex)
            {
                // Report exceptions
                MessageBox.Show("Error drawing graphic shape: " + ex.Message);
            }
        }
    }

    private void CanExecuteChanged(object sender, EventArgs e)
    {
        ICommand command = (ICommand)sender;

        if (command == _vm.MapControlMap.SketchEditor.UndoCommand)
        {

        }
        else if (command == _vm.MapControlMap.SketchEditor.RedoCommand)
        {

        }
        else if (command == _vm.MapControlMap.SketchEditor.CompleteCommand)
        {
            if (_vm.MapControlMap.SketchEditor.CompleteCommand.CanExecute(null))
            {
                // Editing

            }
            else
            {
                // Not Editing

            }

        }


    }

    private void SEGeometryChanged(object sender, EventArgs e)
    {
        GeometryChangedEventArgs geo = e as GeometryChangedEventArgs;
        if (selectFromMapEnabled && selectingFromMap && geo.OldGeometry == null)
        {
            // We attempted to select some geometry.  Is it valid?
            if (geo.NewGeometry != null)
            {
                MapPoint queryPoint = ((GeometryChangedEventArgs)e).NewGeometry.Extent.GetCenter();

                Geometry gm = Esri.ArcGISRuntime.Geometry.GeometryEngine.Buffer(queryPoint, 2);

                FeatureLayer layer = (FeatureLayer)_vm.MapControlMap.Map.OperationalLayers.FirstOrDefault(x => x.Name == SelectFromLayer);
                //FeatureLayer layer = (FeatureLayer)_vm.MapControlMap.Map.OperationalLayers.Where(x => x.Name == "TITLES").FirstOrDefault();
                var query = new QueryParameters();

                //query.Geometry = queryPoint;
                query.Geometry = gm;
                query.MaxFeatures = 1;
                query.SpatialRelationship = SpatialRelationship.Intersects;
                query.WhereClause = layer.DefinitionExpression;

                Feature selectedfeature = layer.FeatureTable.QueryFeaturesAsync(query).Result.FirstOrDefault();
                Feature f = selectedfeature;

                if (f != null)
                {
                    _vm.MapControlMap.SketchEditor.GeometryChanged -= SEGeometryChanged;
                    _vm.MapControlMap.SketchEditor.ReplaceGeometry(f.Geometry);
                    _vm.MapControlMap.SketchEditor.GeometryChanged += SEGeometryChanged;

                    // Need to populate NOTIFICATION values from TITLES 
                    _vm.Sketch_Selection = f;




                    selectFromMapEnabled = false;
                }
                else
                {
                    // REMOVE or RECREATE the NOTIFICATION to erase the values added when we selected a TITLE

                    _vm.MapControlMap.SketchEditor.UndoCommand.Execute(null);
                }

            }
        }
        else
        {
            if (geo.NewGeometry != null)
            {
                selectFromMapEnabled = false;
            }
            else
            {
                selectFromMapEnabled = true;
                _vm.Sketch_Selection = null;
            }
        }
    }
    private async Task NewSegment()
    {

    }
    private async void Sb_Complete_Click(object sender, RoutedEventArgs e)
    {
        var sketchEditor = _vm.MapControlMap.SketchEditor;

        //Need to check for valid geometry!
        bool iv = false;    // assume bad geometry
        if (_vm.MapControlMap.SketchEditor.Geometry != null)
        {
            switch (_vm.MapControlMap.SketchEditor.Geometry.GetType().ToString())
            {
                case "Esri.ArcGISRuntime.Geometry.MapPoint":
                    {
                        // Well, if the geometry is not null, it must be valid.  :)
                        iv = true;
                        break;
                    }
                case "Esri.ArcGISRuntime.Geometry.Polyline":
                    {
                        Geometry pl_test = (_vm.MapControlMap.SketchEditor.Geometry);                                                                          

                        PolylineBuilder pl_pb = new PolylineBuilder(_vm.Map.SpatialReference);
                        pl_pb.ReplaceGeometry((Polyline)pl_test);
                        iv = pl_pb.IsSketchValid;
                        break;
                    }
                case "Esri.ArcGISRuntime.Geometry.Polygon":
                    {
                        Geometry pl_test = (_vm.MapControlMap.SketchEditor.Geometry);
                        PolygonBuilder pl_pb = new PolygonBuilder(_vm.Map.SpatialReference);
                        pl_pb.ReplaceGeometry((Polygon)pl_test);
                        iv = pl_pb.IsSketchValid;
                        break;
                    }
                default:
                    break;
            }
        }
        if (_vm.Current_Feature == null && iv)
        {
            try
            {

                _vm.WaitIndicatorText = "Adding Feature";
                _vm.WaitIndicatorVisible = true;



                await _vm.AddFeature(_vm.MapControlMap.SketchEditor.Geometry, _vm.FeatureLayerToCreate, _vm.Sketch_Selection, _vm.Sketch_Clone, true);


                // Populate LANDOWNER data from PARCEL_INFO if needed
                if (_vm.FeatureLayerToCreate.Name == "LANDOWNER")
                {
                    ALViewModel.Changed_By oldChangedBy = _vm.Current_Changed_By;
                    _vm.Current_Changed_By = ALViewModel.Changed_By.Map_Selection;
                    //await add_landowners(geometry);
                    // update the PARCEL_ID and CONTACT_STATUS fields at a minimum
                    update_LANDOWNERS(_vm.Current_Feature);
                    _vm.Current_Changed_By = oldChangedBy;
                }

                //string[] array = { "POINT_WORK", "LINE_WORK", "POLY_WORK" };
                //if (array.Contains(_vm.FeatureLayerToCreate.Name.ToUpper()))
                //{
                //    ALViewModel.Changed_By oldChangedBy = _vm.Current_Changed_By;
                //    _vm.Current_Changed_By = ALViewModel.Changed_By.Map_Selection;

                //    _vm.Current_Feature.Attributes["REMOVE_QTY"] = 1;
                //    _vm.Current_Changed_By = oldChangedBy;
                //}


                _vm.WaitIndicatorText = "Feature added";
                _vm.WaitIndicatorVisible = false;

                sketchEditor.CompleteCommand.Execute(null);
                //_vm.MapControlMap.SketchEditor.Stop();
            }
            catch (Exception ex)
            {
                _vm.WaitIndicatorText = "Feature added";
                _vm.WaitIndicatorVisible = false;
                sketchEditor.CancelCommand.Execute(null);
                selectFromMapEnabled = true;
                selectingFromMap = false;

            }
        }
        else
        {
            if (_vm.Current_Feature != null)
            {
                _vm.Current_Feature.Geometry = _vm.MapControlMap.SketchEditor.Geometry;
            }
            //await _vm.Save_CurrentFeature();
            else
            {
                // No valid geometry.  Keep editing graphic.
                MessageBox.Show("No valid geometry.  Please continue editing.", "Error", MessageBoxButton.OK);
            }
            //sketchEditor.CompleteCommand.Execute(null);
        }
        selectFromMapEnabled = true;
        selectingFromMap = false;
        //sketchEditor.CompleteCommand.Execute(null);
    }

    private async void Sb_Select_Click(object sender, RoutedEventArgs e)
    {
        if (_vm.MapControlMap.SketchEditor.Geometry == null)
        {
            selectingFromMap = !selectingFromMap;

        }
        if (selectingFromMap == true)
            animateTo = .5;
        else
        {
            animateTo = 1;
        }

    }

 

0 Kudos
3 Replies
AndyWeis
Esri Contributor

Hi @ThomasZanis, have you seen our Create and Edit Geometries sample on our Developers site? This lays out a workflow for creating any geometries you'll need, including multi-segment polylines.

0 Kudos
dotMorten_esri
Esri Notable Contributor

Just wanted to add that sample uses the new GeometryEditor introduced in 200.3. The old SketchEditor that was available in 100.15 did not fully support multi-part geometries.

0 Kudos
ThomasZanis
New Contributor

Hello, Thank you for your reply. I have gone through the documentation for 100.15 and did not find anything. Version 200+ would be a perfect solution, but we can not upgrade to 200 just yet. 

0 Kudos