I want to create a polyline using a Button, not a Tool (see why below ). I use the following code:
protected override async void OnClick()
{
try
{
var spatialRef = GeometryFunctions.CreateLV95SpatialReference();
// Get mouse coordinates
System.Drawing.Point screenPoint = Cursor.Position;
System.Windows.Point winPoint = new System.Windows.Point(screenPoint.X, screenPoint.Y);
var cursorPoint = await QueuedTask.Run(() =>
{
return MapView.Active.ScreenToMap(winPoint);
});
// Get current sketch
Polyline existingWbl = await MapView.Active.GetCurrentSketchAsync() as Polyline;
// Add point to current sketch
var newWbl = AddPointToPolyline(existingWbl, cursorPoint, spatialRef);
await MapView.Active.SetCurrentSketchAsync(newWbl);
}
catch (Exception ex)
{
ProPopupMessage.Error(MiscUtils.GetMethodName(), ex.Message);
}
}
private Polyline AddPointToPolyline(Polyline polyline, MapPoint newPoint, SpatialReference spatialRef)
{
PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(spatialRef);
polylineBuilder.HasZ = true;
// Step through all points
List<MapPoint> newPointList = new List<MapPoint>();
if (polyline != null)
{
foreach (var existingPoint in polyline.Points)
{
newPointList.Add(existingPoint);
}
}
newPointList.Add(newPoint);
// Add polyline part
polylineBuilder.AddPart(newPointList);
return polylineBuilder.ToGeometry();
}
This code works if there already exists a sketch. If I want to add the first point of the polyline, however, it doesn't show on the stereo map. In ArcObjects, this was possible!
Why do I want to create a polyline using a button instead of a tool? I want to use a button on a 3D mouse (https://pro.arcgis.com/en/pro-app/latest/help/analysis/image-analyst/set-up-the-stereo-mapping-steal...
Solved! Go to Solution.
Depending on your testing results I would suggest a little bit to change my first scenario.
Before calling StartSketchAsync execute your dummy tool using FrameworkApplication.SetCurrentToolAsync("<dummy_tool_id>");
I'm curious about any workarounds for this as well. As far as I know, coming from SolidWorks, and now Fusion 360, this isn't possible. I have always had to make sure things that are referenced are put into the design before the sketch you want to reference them with is created. Sometimes in SolidWorks, you could move them ahead in the timeline, but it was limited on how far they would move due to references, etc https://vidmate.bid/ .
There is one way to create sketch. Using MapTool StartSketchAsync.
So my idea is to create dummy MapTool without adding to ribbon. Set loadOnClick="false". Set SketchGeometryType as RegularPolyline.
Then implement idea from thread to get instance of dummy MapTool. If MapView.Active.GetCurrentSketchAsync() returns null, call StartSketchAsync from your dummy MapTool instance and retry to call MapView.Active.GetCurrentSketchAsync().
This is a good idea! I've had the idea with the dummy Map Tool, but I didn't know about the method StartSketchAsync. Unfortunately, after calling StartSketchAsync or StartSketchAsync(editingTemplate), MapView.Active.GetCurrentSketchAsync() still returns null.
I now use the following workaround:
1. Activate my Map Tool using the following code:
await QueuedTask.Run(() =>
{
var layer = LayerUtils.GetFeatureLayerByName(layerName);
EditingTemplate template = layer?.GetTemplate(editTemplateName);
template?.ActivateToolAsync(toolId);
});
2. Click with the left system mouse (is button 4 on Stealth Mouse) on the map to digitize the first point of polyline
3. Use my custom button to digitize the remaining points of the polyline (this custom button would be theoretically assigned to a button on Stealth Mouse. (However, it is not possible yet to assign custom buttons to Stealth Mouse, but I hope it will be in the future)).
Depending on your testing results I would suggest a little bit to change my first scenario.
Before calling StartSketchAsync execute your dummy tool using FrameworkApplication.SetCurrentToolAsync("<dummy_tool_id>");
Thank you Gintautas! Calling FrameworkApplication.SetCurrentToolAsync("<dummy_tool_id>") before calling StartSketchAsync() works.
Calling editingTemplate?.ActivateToolAsync"<dummy_tool_id>") before calling StartSketchAsync() doesn't work, however. Why?
Maybe your editingTemplate is null. I don't like syntax like "?.". It doesn't crash but it could do nothing and you will not be informed about it.
I forgot to await editingTemplate?.ActivateToolAsync"<dummy_tool_id>") . The correct code is:
await QueuedTask.Run(async () =>
{
var layer = LayerUtils.GetFeatureLayerByName(layerName);
EditingTemplate template = layer?.GetTemplate(editTemplateName);
await template?.ActivateToolAsync(toolId);
});