Select to view content in your preferred language

Is there any way to restrict Polyline to be just a single line in GeometryEditor?

858
5
Jump to solution
11-06-2023 07:12 AM
noodle
by
Occasional Contributor

I want to have a subclass of Polyline so that I can draw only a line.   That is, when you click two, no more clicking is allowed in GemetryEditor.

0 Kudos
1 Solution

Accepted Solutions
JenniferNery
Esri Regular Contributor

You can try the following simplified sample that contains the MapView with GraphicsOverlay for displaying the new geometry and some buttons that Start/Stop/DeleteVertex on GeometryEditor.

Using the PropertyChanged event of the GeometryEditor, you can check its Geometry and update its VertexTool properties. The PolylineBuilder's IsSketchValid currently checks the minimum required number of points for a polyline so having two unique points is considered valid. 

Per Shelly's recommendation, if you want to continue to edit the geometry, you can use the Tools' InteractionConfiguration to enable/disable which vertex editing is allowed. For example, disable new vertex creation.

 

<esri:MapView x:Name="MyMapView" />
<StackPanel VerticalAlignment="Top"
            HorizontalAlignment="Right">
    <Button Content="Line Segment"
            Click="OnDrawLine" />
    <Button Content="Delete Vertex"
            Click="OnDeleteVertex" />
    <Button Content="Complete Line Segment"
            Click="OnCompleteDraw" />
</StackPanel>

 

 

 

public MainWindow()
{
    InitializeComponent();

    MyMapView.Map = new Map(SpatialReferences.WebMercator);

    MyMapView.GraphicsOverlays.Add(new GraphicsOverlay()
    {
        Renderer = new SimpleRenderer(new SimpleLineSymbol() { Color = Color.Blue, Style = SimpleLineSymbolStyle.Solid, Width = 2 })
    });

    MyMapView.GeometryEditor.PropertyChanged += OnGeometryPropertyChanged;
}

private bool EnsureTwoPoints => MyMapView.GeometryEditor?.Geometry is Polyline polyline &&
            new PolylineBuilder(polyline).IsSketchValid;

private void OnGeometryPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(GeometryEditor.Geometry))
    {
        if (MyMapView.GeometryEditor.Tool is VertexTool vertexTool)
        {
            vertexTool.Configuration.AllowVertexCreation = !EnsureTwoPoints;
        }
    }
}
private void OnDrawLine(object sender, RoutedEventArgs e)
{
    if (MyMapView.GeometryEditor.IsStarted)
    {
        return;
    }

    MyMapView.GeometryEditor.Start(GeometryType.Polyline);
}

private void OnDeleteVertex(object sender, RoutedEventArgs e)
{
    if (!MyMapView.GeometryEditor.IsStarted)
        return;

    if (MyMapView.GeometryEditor.SelectedElement is GeometryEditorVertex)
        MyMapView.GeometryEditor.DeleteSelectedElement();
}

private void OnCompleteDraw(object sender, RoutedEventArgs e)
{
    if (!MyMapView.GeometryEditor.IsStarted || !EnsureTwoPoints)
        return;

    var geometry = MyMapView.GeometryEditor.Stop();

    if (MyMapView.GraphicsOverlays.FirstOrDefault() is GraphicsOverlay overlay)
    {
        overlay.Graphics.Add(new Graphic(geometry));
    }
}

 

draw_edit_line_segment.gif

  1. Click Line Segment button to start drawing
  2. Click Delete Vertex button to remove selected vertex
  3. Click Complete Line Segment button to stop drawing.
  4. Notice in this small sample code, vertex creation is only allowed when you have not met the minimum 2 points.

 

View solution in original post

5 Replies
JenniferNery
Esri Regular Contributor

You can subscribe to `GeometryEditor.PropertyChanged` event and monitor the `GeometryEditor.Geometry` property. If this is a polyline, you can use `PolylineBuilder` it's `IsSketchValid()` method already checks for the minimum set, 2 unique points.

You can check the code-snippet in the Asynchronous start task with geometry result section of this blog post. You can have it throw an error or call `GeometryEditor.Stop()` so drawing is completed once you have at most 2 points.

0 Kudos
ShellyGill1
Esri Contributor

Hi @noodle - I'd also add another option, which might be useful if you don't want to stop the GeometryEditor after adding two points, but want you user to be able to continue to move existing points, and to be able to rotate, scale, and move the geometry. As @JenniferNery says you can monitor for the number of points in the polyline geometry. Once you have 2 points, you could get the current tool (I'm assuming you're working with the VertexTool here) and then change it's InteractionConfiguration.allowVertexCreation property to false. If you also want the user to be able to delete an existing vertex and re-add it, then ensure the config property is set back to true when the vertex number is less than 2.

noodle
by
Occasional Contributor

Do you have an example code using IntractionConfiguration.AllowVertexCreation?   Or any example with other flags?

0 Kudos
noodle
by
Occasional Contributor

I must be doing something wrong.  I used AllowVertexCreation = false on GeometryEditor_PropertyChanged but I can still add more vertex.  I really needs a sample code.

0 Kudos
JenniferNery
Esri Regular Contributor

You can try the following simplified sample that contains the MapView with GraphicsOverlay for displaying the new geometry and some buttons that Start/Stop/DeleteVertex on GeometryEditor.

Using the PropertyChanged event of the GeometryEditor, you can check its Geometry and update its VertexTool properties. The PolylineBuilder's IsSketchValid currently checks the minimum required number of points for a polyline so having two unique points is considered valid. 

Per Shelly's recommendation, if you want to continue to edit the geometry, you can use the Tools' InteractionConfiguration to enable/disable which vertex editing is allowed. For example, disable new vertex creation.

 

<esri:MapView x:Name="MyMapView" />
<StackPanel VerticalAlignment="Top"
            HorizontalAlignment="Right">
    <Button Content="Line Segment"
            Click="OnDrawLine" />
    <Button Content="Delete Vertex"
            Click="OnDeleteVertex" />
    <Button Content="Complete Line Segment"
            Click="OnCompleteDraw" />
</StackPanel>

 

 

 

public MainWindow()
{
    InitializeComponent();

    MyMapView.Map = new Map(SpatialReferences.WebMercator);

    MyMapView.GraphicsOverlays.Add(new GraphicsOverlay()
    {
        Renderer = new SimpleRenderer(new SimpleLineSymbol() { Color = Color.Blue, Style = SimpleLineSymbolStyle.Solid, Width = 2 })
    });

    MyMapView.GeometryEditor.PropertyChanged += OnGeometryPropertyChanged;
}

private bool EnsureTwoPoints => MyMapView.GeometryEditor?.Geometry is Polyline polyline &&
            new PolylineBuilder(polyline).IsSketchValid;

private void OnGeometryPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(GeometryEditor.Geometry))
    {
        if (MyMapView.GeometryEditor.Tool is VertexTool vertexTool)
        {
            vertexTool.Configuration.AllowVertexCreation = !EnsureTwoPoints;
        }
    }
}
private void OnDrawLine(object sender, RoutedEventArgs e)
{
    if (MyMapView.GeometryEditor.IsStarted)
    {
        return;
    }

    MyMapView.GeometryEditor.Start(GeometryType.Polyline);
}

private void OnDeleteVertex(object sender, RoutedEventArgs e)
{
    if (!MyMapView.GeometryEditor.IsStarted)
        return;

    if (MyMapView.GeometryEditor.SelectedElement is GeometryEditorVertex)
        MyMapView.GeometryEditor.DeleteSelectedElement();
}

private void OnCompleteDraw(object sender, RoutedEventArgs e)
{
    if (!MyMapView.GeometryEditor.IsStarted || !EnsureTwoPoints)
        return;

    var geometry = MyMapView.GeometryEditor.Stop();

    if (MyMapView.GraphicsOverlays.FirstOrDefault() is GraphicsOverlay overlay)
    {
        overlay.Graphics.Add(new Graphic(geometry));
    }
}

 

draw_edit_line_segment.gif

  1. Click Line Segment button to start drawing
  2. Click Delete Vertex button to remove selected vertex
  3. Click Complete Line Segment button to stop drawing.
  4. Notice in this small sample code, vertex creation is only allowed when you have not met the minimum 2 points.