Can I draw different geometry types with a MapTool?

544
4
Jump to solution
08-02-2023 01:43 AM
ViktorSafar
Occasional Contributor II

I need to draw different geometry types, eg. point and polyline, depending on the state of the CTRL key. I created a MapTool and am overriding HandleKeyDownAsync/HandleKeyUpAsync but it appears the MapTool.SketchType property has no effect once the tool is activated.

 

        public DrawFireTargetMapTool()
        {
            IsSketchTool = true;
            SketchOutputMode = SketchOutputMode.Map;
            SketchType = Module1.SelectedFireGeometryType;       
        }

        protected override Task HandleKeyUpAsync(MapViewKeyEventArgs args)
        {
            if (args.Key == System.Windows.Input.Key.LeftCtrl)
            {
                SketchType = Module1.SelectedFireGeometryType;
            }

            return base.HandleKeyUpAsync(args);
        }

        protected override Task HandleKeyDownAsync(MapViewKeyEventArgs args)
        {
            if (args.Key == System.Windows.Input.Key.LeftCtrl)
            {
                SketchType = Module1.SelectedTargetGeometryType;
            }

            return base.HandleKeyDownAsync(args);
        }
Tags (2)
1 Solution

Accepted Solutions
ViktorSafar
Occasional Contributor II

It actually works out of the box! I am not sure what I did wrong in the beginning, but changing the SketchType after the tool has been activated indeed has an effect on the geometry being drawn. 

public DrawFireTargetMapTool()
{
	IsSketchTool = true;
	SketchType = SketchGeometryType.Rectangle;
	SketchOutputMode = SketchOutputMode.Map;
}

protected override Task OnToolActivateAsync(bool active)
{
	SketchType = <some other SketchType>;
	return Task.CompletedTask;
}

/// <summary>
/// This is used only to trigger OnToolKeyUp
/// </summary>        
protected override Task HandleKeyUpAsync(MapViewKeyEventArgs args)
{
	args.Handled = true;
	return base.HandleKeyUpAsync(args);
}

protected override void OnToolKeyUp(MapViewKeyEventArgs args)
{
	if (_handledKeys.Contains(args.Key))
	{
		SketchType = <yet another SketchType>;
	}
	else
	{
		base.OnToolKeyUp(args);
	}
}

 

View solution in original post

0 Kudos
4 Replies
CharlesMacleod
Esri Regular Contributor

tools can only have one sketch type. consider implementing a tool palette. This is how the Pro selection tool is implemented. Read: https://github.com/Esri/arcgis-pro-sdk/wiki/ProGuide-Palettes-and-Split-Buttons#how-to-declare-a-too...

Pro selection tool declaration:

<!-- from ADmapping.daml -->

<toolPalette id="esri_mapping_selectToolPalette" itemsInRow="1" showItemCaption="true" caption="Select" extendedCaption="Open select tool palette" keytip="SE">
          <tool refID="esri_mapping_selectByRectangleTool" />
          <tool refID="esri_mapping_selectByPolygonTool" />
          <tool refID="esri_mapping_selectByLassoTool" />
          <tool refID="esri_mapping_selectByCircleTool" />
          <tool refID="esri_mapping_selectByLineTool" />
          <tool refID="esri_mapping_selectByTraceTool"/>
          <tool refID="esri_mapping_selectByBoxTool" />
          <tool refID="esri_mapping_selectBySphereTool"/>
          <tool refID="esri_mapping_selectByCylinderTool"/>
        </toolPalette>

 

0 Kudos
ViktorSafar
Occasional Contributor II

Thanks for the reply, @CharlesMacleod. The tool activation is done from custom code, not from Pro  buttons.

I have changed approach and am now attempting to activate 2 separate tools from each other's HandleKeyDownAsync methods (aka DrawFireMapTool activates DrawTargetMapTool and vice versa).

I have put breakpoints into OnToolDeactivateAsync and see that it is not being called on the 1st tool when the 1st tool activates the 2nd tool. So I am assuming this approach won't work either?

How does the palette switch tools? Can I deactivate a tool from within itself?

 

// DrawFireMapTool.cs
        protected override async Task HandleKeyDownAsync(MapViewKeyEventArgs args)
        {
            if (args.Key == System.Windows.Input.Key.LeftCtrl)
            {
                // activate Target tool
                await FrameworkApplication.SetCurrentToolAsync(DrawTargetMapTool.DamlId);
            }
            else
            {
                await base.HandleKeyDownAsync(args);
            }
        }



// DrawTargetMapTool.cs
        protected override async Task HandleKeyUpAsync(MapViewKeyEventArgs args)
        {
            if (args.Key == System.Windows.Input.Key.LeftCtrl)
            {
                // activate Fire tool             
                await FrameworkApplication.SetCurrentToolAsync(DrawFireMapTool.DamlId);
            }
            else
            {
                await base.HandleKeyUpAsync(args);
            }   
        }

 

0 Kudos
NarelleChedzey
Esri Contributor

Go back to your first approach and try calling base.StartSketchAsync() after you've changed the SketchType.   

Internally the sketch is started on tool activation with the current SketchType.  If you change the SketchType after this moment, you need to tell the tool to re-initialize the sketch.   This is accomplished by the StartSketchAsync method. 

Narelle

ViktorSafar
Occasional Contributor II

It actually works out of the box! I am not sure what I did wrong in the beginning, but changing the SketchType after the tool has been activated indeed has an effect on the geometry being drawn. 

public DrawFireTargetMapTool()
{
	IsSketchTool = true;
	SketchType = SketchGeometryType.Rectangle;
	SketchOutputMode = SketchOutputMode.Map;
}

protected override Task OnToolActivateAsync(bool active)
{
	SketchType = <some other SketchType>;
	return Task.CompletedTask;
}

/// <summary>
/// This is used only to trigger OnToolKeyUp
/// </summary>        
protected override Task HandleKeyUpAsync(MapViewKeyEventArgs args)
{
	args.Handled = true;
	return base.HandleKeyUpAsync(args);
}

protected override void OnToolKeyUp(MapViewKeyEventArgs args)
{
	if (_handledKeys.Contains(args.Key))
	{
		SketchType = <yet another SketchType>;
	}
	else
	{
		base.OnToolKeyUp(args);
	}
}

 

0 Kudos