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.
Solved! Go to Solution.
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));
}
}
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.
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.
Do you have an example code using IntractionConfiguration.AllowVertexCreation? Or any example with other flags?
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.
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));
}
}