JMap Tools
Dernière mise à jour
Dernière mise à jour
K2 Geospatial 2022
A JMap tool provides interaction between the user and the map using the mouse. For example, when the user activates the selection tool and clicks on the map to select an item, it is the selection tool class that performs the work. This tool is programmed to make a selection at the location that is clicked on the map. Similarly, when the distance measurement tool is used, the tool class calculates and displays the distance between the 2 points clicked by the user. Thus, developing a JMap tool allows you to implement custom actions.
In general, only one tool at a time can be enabled. In order to be enabled, a tool must be the active tool in a JMap view. To do so, you must use the method setCureentTool(Tool) of the View or ViewManager class. Note that the method used to activate the tool, such as a button or a menu item, has no connection with the operation of the tool itself.
When the user changes the active the tool (e.g. by pressing a button), the code will essentially be as follows:
JMapApplicationContext.getInstance().getViewManager().setCurrentTool(new MyTool());
When a tool is active, it receives all the mouse events that are generated by the active view. The Tool class is responsible for processing these events and taking the appropriate actions.
To develop a new tool, you must program a class derived from the abstract class Tool and implement only the methods needed to perform the tool’s function. For example, if the tool must perform an action when the user clicks the mouse, you must implement the onToolClicked() method.
Tool class methods:
The following code example shows a simple tool that displays the properties of the first element found at the coordinates of the mouse cursor when the user presses and releases the left mouse button on the map. Only vector layers are considered and the search is performed from the highest layer to the lowest layer, in the layer display order. Other methods of the Tool class are not implemented because they are not required for the operation of this tool.
public class ElementInfoTool extends Tool
{
public void onToolReleased(MouseEvent e)
{
super.onToolReleased(e);
System.out.println("ElementInfoTool.onToolReleased");
// Obtain array of layers to cycle them in reverse order
final Layer aLayers[] = this.view.getLayerManager().getAllLayers();
// Get the layer visibility status from the layer manager (also includes the hierarchy visibility)
final LayerVisibilitySet layersVisibility = this.view.getLayerManager().getLayerTreeVisibility();
// Transform mouse x,y coordinate to WC coordinate
// Point wcCoord = view.getTransform().transformInv(new Point.Double(e.getX(), e.getY())); final Point wcCoord = toWCPoint(e); // method inherited from class Tool
final ViewState viewState = this.view.getViewState();
// Cycle through every layer in reverse order (from top position to bottom position) looking for an element under the x,y position.
for (int i = aLayers.length - 1; i >= 0; i--)
{
// Consider only vector layers
if (!(aLayers[i] instanceof VectorLayer))
continue;
final VectorLayer vectorLayer = (VectorLayer) aLayers[i];
// Layer must be visible, selectable and displayed at the current scale
if (layersVisibility.isVisible(vectorLayer.getId()) && vectorLayer.isSelectable() && vectorLayer.isDrawable(viewState.getScale()))
{
final K2DElement elem = vectorLayer.getElementAtPoint(wcCoord, viewState, true);
if (elem != null)
{
String message = "Selected element on layer " + vectorLayer.getName() + ":\n\n"
+ "Class:" + elem.getClass().getName() + '\n'
+ "Id: " + elem.getId() + '\n'
+ "Geometry: " + elem.getGeometry().getClass() + '\n'
+ "Display bounds: " + elem.getDisplayBounds(viewState, vectorLayer.getStyle(elem, viewState.getScale())) + '\n'
+ "Attributes:\n";
final Object[] attribs = elem.getAttributes();
final Attribute[] attribDefinitions = vectorLayer.getAttributeMetaData();
for (int j = 0; j < attribs.length; j++)
{
message += " " + attribDefinitions[j].getName() + " : " + attribs[j] + '\n';
}
JOptionPane.showMessageDialog(this.view, message);
break;
}
}
}
}
}
You can implement tools to draw on the map simply by deriving them from existing JMap classes for drawing tools.
By deriving from these classes, all the basic operations are inherited. The following options are available:
Persistent and volatile modes (determines whether items are created);
Select the layer that will receive the items drawn;
Style parameters of drawn elements (colors, line types, etc.);
Display dimensions on the map while drawing.
The following table lists the classes for drawing tools available in JMap. All these classes are derived from the ToolDraw class.
The following table lists the most commonly used methods of the ToolDraw class.
The following code example shows a tool derived from ToolDrawPolygon that inherits all of its drawing capabilities.
public class CreatePolygonTool extends ToolDrawPolygon
{ private final static String LAYER_NAME = "Zones";
private VectorLayer targetLayer; // The layer that will hold the polygons
public void init(View view)
{
super.init(view);
// Make sure the layer exists. If not create it and register it in the layer manager of the view.
final LayerManager layerMgr = view.getLayerManager();
this.targetLayer = (VectorLayer)layerMgr.getLayer(LAYER_NAME);
if (this.targetLayer == null)
{
// The layer does not exist, create it
this.targetLayer = new VectorLayer(Layer.getNextUserLayerId(), // avoid id conflict with other layers
LAYER_NAME,
ElementTypes.TYPE_POLYGON);
// Tell JMap that information on this layer does not come from the server
this.targetLayer.setLocal(true);
// Set the mouse-over text for the layer. It will be displayed when the user stops the mouse pointer over an element.
this.targetLayer.setMouseOverConfiguration(new MouseOverConfiguration("This is a zone."));
// Add the layer to the layer manager list. All layers need to be registered in the layer manager in order to be displayed in the view. The layer is added to the top.
layerMgr.addLayer(this.targetLayer);
}
// Tell the superclass that the resulting elements should be persisted when completed. That means that they will be placed on a layer. Otherwise, they would be deleted as soon as they are completed.
setPersistent(true);
// Tell the superclass to place the resulting elements on the target layer. Otherwise, they would be placed on the default drawing layer
// (id = LayerManager.LAYER_ID_USER_DRAWINGS).
setDrawLayer(this.targetLayer);
// Modify the style of the surface elements (polygons).
final Style surfaceStyle = getStyleContainer().getSurfaceStyle();
surfaceStyle.setFillColor(Color.GREEN);
surfaceStyle.setTransparency(.50f);
// To have the valid drawing style displayed in the layer bar, make the layer default style identical to the drawing style.
this.targetLayer.setStyle(surfaceStyle, 0.);
}
}
This method is called when the tool becomes the active tool of a view. The code for this method should be used as necessary to prepare the work of the tool. The view is passed as a parameter to this method.
This method is called by the view when the tool becomes active to allow your tool to provide its own mouse cursor. The cursor will be visible on the view as long as your tool remains the active tool.
This method is called when the user presses on one of the mouse buttons within the view.
This method is called when the user releases a mouse button within the view.
This method is called after the user has completed a mouse click within the view.
This method is called repeatedly when the user moves the mouse inside the view.
This method is called repeatedly when the user moves the mouse inside the view while keeping a button pressed.
This method is called when the tool becomes inactive, i.e. when another tool is activated on the screen. The code for this method could be used, as needed, to perform a termination action or to free up resources.
Returns the StyleContainer object that contains the styles of the various types of elements (polygons, lines, etc.) that can be drawn. This method is called to change the style of the elements that will be drawn by the tool.
Specifies the layer that will receive the items drawn by the tool, if the elements are persistent (see setPersistent(boolean) method below). If no layer is specified, a system layer is used by default.
Determines whether the items will be stored on a layer or not (see setDrawLayer(VectorLayer) method above). If they are not stored, the elements disappear immediately after the drawing operation is completed.