Is there a way where we can select the geometry itself instead of the envelope to edit the geometry?
I am trying to let user draw only rectangle with SketchEditor. I want to allow resizing of length and width separately so, i have to use stretch resize mode. But, with that and rotation, one can make it a parallelogram since it selects the envelope and not the geometry itself.
Any help is appreciated.
Thanks!
Bikesh
You can pass SketchEditConfiguration to SketchEditor.StartAsync. Without this optional parameter, sketch editor will enable/disable certain editing capabilities based on the SketchCreationMode or geometry. While you've created a rectangle shape, it's still treated according to its type (Polygon) so all vertex editing and rotate which you may not want for your rectangle shape will be enabled by default.
xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
<Grid>
<esri:MapView x:Name="MyMapView" GeoViewTapped="MyMapView_GeoViewTapped" />
<StackPanel VerticalAlignment="Top"
HorizontalAlignment="Right">
<Button Content="Draw"
Click="OnDraw" />
<Button Content="Complete"
Command="{Binding ElementName=MyMapView, Path=SketchEditor.CompleteCommand}" />
</StackPanel>
</Grid>
public MainWindow()
{
InitializeComponent();
MyMapView.Map = new Map(Basemap.CreateTopographic());
MyMapView.GraphicsOverlays.Add(new GraphicsOverlay() { Renderer = new SimpleRenderer(new SimpleFillSymbol(SimpleFillSymbolStyle.Cross, Colors.DarkGreen, null)) });
}
private async void OnDraw(object sender, RoutedEventArgs e)
{
try
{
var config = new SketchEditConfiguration()
{
AllowRotate = false,
AllowMove = false,
AllowVertexEditing = false,
ResizeMode = SketchResizeMode.Stretch
};
var geometry = await MyMapView.SketchEditor.StartAsync(SketchCreationMode.Rectangle, config);
MyMapView.GraphicsOverlays.FirstOrDefault()?.Graphics?.Add(new Graphic(geometry));
}
catch (TaskCanceledException) { }
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().Name);
}
}
private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.UI.Controls.GeoViewInputEventArgs e)
{
Graphic graphic = null;
try
{
if (MyMapView.SketchEditor.CancelCommand.CanExecute(null))
return;
var result = await MyMapView.IdentifyGraphicsOverlaysAsync(e.Position, 2, false);
graphic = result.FirstOrDefault()?.Graphics?.FirstOrDefault();
if (graphic == null)
return;
graphic.IsVisible = false;
var config = new SketchEditConfiguration()
{
AllowRotate = false,
AllowMove = false,
AllowVertexEditing = false,
ResizeMode = SketchResizeMode.Stretch
};
var geometry = await MyMapView.SketchEditor.StartAsync(graphic.Geometry, SketchCreationMode.Rectangle, config);
graphic.Geometry = geometry;
}
catch (TaskCanceledException) { }
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().Name);
}
finally
{
if (graphic != null)
graphic.IsVisible = true;
}
}
Hi Jennifer,
Thank you for the response. I want to let the user rotate and resize but when resizing a rotated rectangle in stretch mode, it turns into a parallelogram. Is there a way for user to resize each side of rectangle, which might have been rotated, without making it lose its rectangle shape?
Thanks,
Bikesh
Oh I see, sorry I misunderstood. Rotate with scale cannot keep the rectangle shape but you can probably add your logic in SketchEditor.GeometryChanged event handler, perhaps? You have access to e.NewGeometry then and can do a check whether it's still rectangle shape and maybe call SketchEditor.ReplaceGeometry with the closest rectangle shape. I am not sure if there are any GeometryEngine methods (if any) that can help with those calculations, but I hope that helps.
MyMapView.SketchEditor.GeometryChanged += SketchEditor_GeometryChanged;
}
private void SketchEditor_GeometryChanged(object sender, GeometryChangedEventArgs e)
{
var geometry = e.NewGeometry;
if(!IsRectangle(geometry))
MyMapView.SketchEditor.ReplaceGeometry(ToRectangle(geometry));
}