Outils JMap

 

Un outil JMap permet de fournir une interaction entre l'utilisateur et la carte au moyen de la souris. Par exemple, lors que l'utilisateur active l'outil de sélection et clique sur la carte pour sélectionner un élément, c'est la classe de l'outil de sélection qui effectue le travail. Cet outil est programmé pour effectuer une sélection à l'endroit cliqué. De même, lorsque l'utilisateur utilise l'outil de mesure de distance, c'est la classe de l'outil qui calcule et affiche la distance entre 2 points cliqués par l'utilisateur. Le développement d'outils JMap vous permet donc d'implémenter des actions personnalisées.

En général, un seul outil à la fois peut être en fonction. Pour qu'un outil devienne en fonction, il doit devenir l'outil actif d'une vue JMap. Pour se faire, il faut utiliser la méthode setCurrentTool(Tool) de la classe View ou de la classe ViewManager. Notez que le moyen utilisé pour rendre l'outil actif, tel qu'un bouton ou un item de menu, n'a aucun lien avec le fonctionnement de l'outil lui-même.

Lorsque l'utilisateur change l'outil actif (par exemple en appuyant sur un bouton), voici essentiellement le code qui est appelé.

 

  JMapApplicationContext.getInstance().getViewManager().setCurrentTool(new MyTool());

 

 

Quand un outil est actif, il reçoit tous les événements de souris qui sont générés par la vue active. C'est la responsabilité de la classe de l'outil de traiter ces événements et de prendre les actions voulues.

Pour développer un nouvel outil, vous devez programmer une classe dérivée de la classe abstraite Tool et implémenter uniquement les méthodes dont vous avez besoin pour faire le travail de l'outil. Par exemple, si l'outil doit faire une action lorsque l'utilisateur effectue un clic de souris, vous devez implémenter la méthode onToolClicked().

Méthodes de la classe Tool

init()

Cette méthode est appelée lorsque l'outil devient l'outil actif d'une vue. Le code de cette méthode devrait servir, au besoin, à préparer le travail de l'outil. La vue en question est passée en paramètre à cette méthode.

getCursor()

Cette méthode est appelée par la vue quand l'outil devient actif afin de permettre à votre outil de fournir son propre curseur de souris. Ce curseur sera visible sur la vue tant que votre outil restera l'outil actif.

onToolPressed()

Cette méthode est appelée quand l'utilisateur enfonce l'un des boutons de la souris à l'intérieur de la vue.

onToolReleased()

Cette méthode est appelée quand l'utilisateur relâche l'un des boutons de la souris à l'intérieur de la vue.

onToolClicked()

Cette méthode est appelée après que l'utilisateur ait complété un clic de souris à l'intérieur de la vue.

onToolMoved()

Cette méthode est appelée à répétition lorsque l'utilisateur déplace la souris à l'intérieur de la vue.

onToolDragged()

Cette méthode est appelée à répétition lorsque l'utilisateur déplace la souris à l'intérieur de la vue, tout en maintenant un bouton enfoncé.

terminate()

Cette méthode est appelée lorsque l'outil devient inactif, c'est-à-dire lorsqu'un autre outil devient actif sur la vue. Le code de cette méthode pourrait servir, au besoin, à faire un travail de fermeture ou de libération de ressources.

 

L'exemple de code suivant montre un outil simple qui, lorsque l'utilisateur appuie et relâche le bouton gauche de la souris sur la carte, affiche les propriétés du premier élément trouvé à la coordonnée du curseur de la souris. Seules les couches vectorielles sont considérées et la recherche se fait de la couche la plus haute vers la couche la plus basse, dans l'ordre d'affichage des couches. Notez que les autres méthodes de la classe Tool ne sont pas implémentées puisqu'elles ne sont pas requises pour le fonctionnement de l'outil.

 
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;
        }
      }
    }
  }
}

Outils de dessin

Il est simple d'implémenter des outils qui dessinent sur la carte en dérivant simplement des classes des outils de dessin existantes de JMap.

En dérivant de ces classes, tout le fonctionnement de base est hérité. Les options suivantes sont disponibles:

Modes persistent et volatile (détermine si des éléments sont créés);

Sélection de la couche qui recevra les éléments dessinés;

Paramètres du style des éléments dessinés (couleurs, types de trait, etc.);

Affichage des dimensions sur la carte pendant le dessin.

 

Le tableau suivant présente la liste des classes des outils de dessin disponibles dans JMap. Toutes ces classes sont elles-mêmes dérivées de la classe ToolDraw.

Classes de dessin dérivées de ToolDraw

ToolDrawBox

Dessine une boîte (rectangle) sue la carte.

ToolDrawCircle

Dessine un cercle sur la carte.

ToolDrawLine

Dessine une ligne simple sur la carte.

ToolDrawMultiLine

Dessine une multiligne sur la carte.

ToolDrawPolygon

Dessine un polygone sur la carte.

 

Le tableau suivant présente la liste des méthodes les plus couramment utilisées de la classe ToolDraw.

Méthodes de la classe ToolDraw

getStyleContainer()

Retourne l'objet de type StyleContainer qui contient les styles des différents types d'éléments (polygones, lignes, etc.) qu'il est possible de dessiner. C'est la méthode à appeler pour modifier le style des éléments qui seront dessinés par l'outil.

setDrawLayer(VectorLayer)

Spécifie la couche qui va recevoir les éléments dessinés par l'outil, si les éléments sont persistants (voir méthode setPersistant(boolean) plus bas). Si aucun couche n'est spécifiée, une couche système est utilisée par défaut.

setPersistant(boolean)

Détermine si les éléments seront stockés sur une couche ou non (voir méthode setDrawLayer(VectorLayer) plus haut). S'ils ne sont pas stockés, les éléments disparaissent aussitôt l'opération de dessin terminée.

 

L'exemple de code suivant montre un outil qui dérive de ToolDrawPolygon et qui hérite de toutes les capacités de dessin de celle-ci.

 
  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.);
    }
  }