Géométries

 

L'API des géométries de JMap est utilisée pour le développement dans JMap Pro et dans JMap Server.

Les géométries dans JMap sont à la base de tous les éléments vectoriels qui s'affichent sur la carte. Il s'agit de classes simples représentant les types géométriques de base tels que les points, les lignes et les surfaces. Le modèle de classes des géométries utilisé dans JMap est grandement inspiré du modèle de géométries publié par l'Open Geospatial Consortium. Les géométries ne contiennent ni attributs, ni identifiants, ni propriétés d'affichage mais seulement des coordonnées en 2 dimensions (x,y).

Modèle de classes simplifié des géométries de JMap

Modèle de classes simplifié des géométries de JMap

 

Dans JMap, les classes de géométries sont dans le package com.kheops.jmap.spatial. L'interface que toutes les géométries implémentent est Geometry.

Le type de géométrie de base dont toutes les géométries sont composées est le Point. Ce type contient uniquement une coordonnée (x,y). Cette classe est abstraite et il est donc nécessaire d'utiliser ses dérivées Point.Float (simple précision) et Point.Double (double précision).

 

    // Creating a new point specifying coordinates
    Point pt1 = new Point.Double(-73., 45.);
    
    // Creating a new point by cloning an existing point
    Point pt2 = (Point) pt1.clone();
    
    // Changing the location of an existing point
    pt1.setLocation(-74., 45);

 

 

Les principales classes de géométries sont les suivantes :

Classes de géométries

Point

Coordonnée (x,y) dont les autres géométries sont composées.

Curve

Type abstrait dont sont dérivées toutes les géométries linéaires (Line, LineString, etc.).

Line

Ligne simple définie par 2 points.

LineString

Ligne à plusieurs parties. Composée de N noeuds et N-1 segments.

LinearRing

LineString dont le premier noeud et le dernier noeud sont égaux. Forme une boucle fermée.

Surface

Type abstrait dont sont dérivées toutes les géométries surfaciques (Rectangle, Polygon, etc.)..

Polygon

Polygone. Composé d'une LinearRing extérieure et de 0, 1 ou plusieurs LinearRing qui sont des trous.

Rectangle

Surface rectangulaire non orientée (côtés horizontaux et verticaux).

OrientedRectangle

Surface rectangulaire qui peut être orientée.

Ellipse

Ellipse composée d'un point central, d'un rayon a et d'un rayon b.

Annotation

Dérivée d'OrientedRectangle, la classe Annotation définit l'emprise d'un texte à afficher sur la carte.

 

Des versions composites des géométries existent afin de supporter les collections de géométries de même type. Ces classes sont: MultiPoint, MultiCurve, MultiLineString, MultiSurface et MultiPolygon. De plus, la classe Complex est un type spécial de collection de géométries de types variés.

Afin de gérer plus facilement tous ces types de géométries, 3 interfaces sont disponibles : PointTypeGeometry, LineTypeGeometry, PolygonTypeGeometry, AnnotationTypeGeometry et EllipseTypeGeometry. Ces interfaces regroupent respectivement tous les types de géométries, incluant les collections.

Précision des géométries

Les géométries dans JMap peuvent être en double précision ou en simple précision. La simple précision, combinée avec d'autres stratégies, est utilisée principalement dans un but de compression des données, afin d'optimiser les performances du système. Comme programmeur, vous devriez utiliser uniquement la double précision.

 

    // Creating a new point with single precision
    Point pt1 = new Point.Float(-73., 45.);
    
    // Creating a new point with double precision
    Point pt2 = new Point.Double(-73., 45.);
 

Opérations sur les géométries

Opérateurs spatiaux

Les opérateurs spatiaux permettent de faire des calculs géométriques sur les géométries. Ces calculs peuvent donner des résultats de 3 types différents:

résultats numériques (p. e. calculer la distance entre 2 géométries)

résultats booléens (ex.: tester si 2 géométries s'intersectent)

résultats géométriques (calculer l'union de 2 géométries).

La classe GeometryUtil fournit des méthodes simples pour effectuer des calculs sur les géométries. Les méthodes les plus souvent utilisées sont présentées dans le tableau suivant:

Tests de relations spatiales (booléen)

contains(Geometry, Geometry, PrecisionModel)

Teste si la première géométrie contient la deuxième géométrie. L'ordre des géométries est important.

crosses(Geometry, Geometry, PrecisionModel)

Teste si la première géométrie croise la deuxième géométrie. L'ordre des géométries est important.

disjoint(Geometr, Geometry, PrecisionModel)

Teste si la première géométrie est disjointe de la deuxième géométrie. L'ordre des géométries est important.

intersects(Geometry, Geometry, PrecisionModel)

Teste si les deux géométries s'intersectent. L'ordre des géométries n'a pas d'importance.

overlaps(Geometry, Geometry, PrecisionModel)

Teste si les deux géométries se chevauchent. L'ordre des géométries n'a pas d'importance.

relate(Geometry, Geometry, char[], PrecisionModel)

Teste si les deux géométries possèdent les relations spatiales définies dans la matrice en paramètre. L'ordre des géométries est important. Pour plus d'information, consultez http://en.wikipedia.org/wiki/DE-9IM.

spatiallyEquals(Geometry, Geometry, PrecisionModel)

Teste si les deux géométries sont égales spatialement (toutes les coordonnées sont identiques). L'ordre des géométries n'a pas d'importance.

touches(Geometry, Geometry, PrecisionModel)

Teste si les deux géométries se touchent. L'ordre des géométries n'a pas d'importance.

within(Geometry, Geometry, PrecisionModel)

Teste si la première géométrie est à l'intérieur de la deuxième géométrie. L'ordre des géométries est important.

Opérations géométriques ayant pour résultat des nouvelles géométries

buffer(Geometry, double, double, PrecisionModel)

Retourne une géométrie qui représente la zone tampon autour de la géométrie spécifiée. La grandeur de la zone est spécifiée en paramètre.

convexHull(Geometry, boolean, PrecisionModel)

Retourne la géométrie convexe fabriquée à partir de la géométrie spécifiée.

difference(Geometry, Geometry, PrecisionModel)

Retourne la géométrie résultant de la différence entre la première géométrie et la deuxième géométrie.  L'ordre des paramètres est important.

diffSym(Geometry, Geometry, PrecisionModel)

Retourne la géométrie résultant de la différence symétrique entre les deux géométries.  L'ordre des paramètres n'a pas d'importance.

intersection(Geometry, Geometry, PrecisionModel)

Retourne la géométrie résultant de l'intersection entre les deux géométries. L'ordre des paramètres n'a pas d'importance.

intersectionMultiple (Geometry[], PrecisionModel)

Retourne la géométrie résultant de l'intersection entre toutes les géométries passées en paramètre. L'ordre des paramètres n'a pas d'importance.

union(Geometry, Geometry, PrecisionModel)

Retourne la géométrie résultant de l'union entre les deux géométries.  L'ordre des paramètres n'a pas d'importance.

unionMultiple(Geometry[], PrecisionModel)

Retourne la géométrie résultant de l'union entre toutes les géométries passées en paramètre. L'ordre des paramètres n'a pas d'importance.

Calculs

distance(Geometry, Geometry, PrecisionModel)

Calcule la plus courte distance séparant les deux géométries. L'ordre des paramètres n'a pas d'importance.

Modèles de précision

La classe PrecisionModel permet de définir la tolérance considérée pour effectuer les calculs utilisant les géométries. Le fait d'utiliser un modèle de précision bien adapté aux géométries permet d'obtenir des résultats plus précis lors des calculs.

Le modèle de précision varie en général selon le type d'unité des données (mètres, degrés, etc.). La classe PrecisionModelFactory permet d'obtenir une instance de PrecisionModel pour une unité donnée. Chaque instance de la classe Layer possède aussi sa propre instance de PrecisionModel qu'il est possible d'utiliser. Il est aussi possible de demander à JMap de déterminer le modèle de précision optimal pour une géométrie spécifique.

L'exemple suivant montre comment obtenir un modèle de précision de différentes manières.

 
// Obtain the optimal precision model for data of the current project 

Project project = ...
PrecisionModel precisionModel1 = PrecisionModelFactory.getInstance(project.getMapUnit());
 
// Obtain the optimal precision model for unit Meter
PrecisionModel precisionModel2 = PrecisionModelFactory.METER;
 
// Obtain the optimal precision model of a layer

Layer layer = ...
PrecisionModel precisionModel3 = layer.getPrecisionModel();
 
// Obtain the optimal precision model for the specified geometry
Geometry geometry = ...
PrecisionModel precisionModel4 = PrecisionModelFactory.getInstance(geometry);

 

Transformations

Les transformations permettent d'appliquer des transformations de toute nature sur les géométries. L'interface Geometry contient une méthode transform(Transformation) qui reçoit une instance de Transformation. Cette méthode crée un clone de la géométrie, applique la transformation spécifiée sur celui-ci et retourne la nouvelle géométrie transformée. Les transformations peuvent modifier les coordonnées qui composent la géométrie et même modifier la nature elle-même de la géométrie. Les transformations peuvent par exemple servir à appliquer une projection cartographique sur des géométries ou à effectuer une généralisation sur celles-ci.

Il est aussi possible d'appliquer des transformations en utilisant la méthode transform() de la classe Transformation. Dans ce cas, la géométrie n'est peut-être pas toujours clonée, selon le type de transformation. Consulter la documentation de chaque transformation pour en connaître davantage.

La classe UnaryTransformation est la classe de base des transformations qui ne modifient que les coordonnées qui composent la géométrie. Si vous devez implémenter votre propre classe de transformation, vous devrez probablement dériver de cette classe.

Le tableau suivant montre les transformations qui sont disponibles avec l'API de JMap.

Trnsformations disponibles

ProjectionTransformation

Applique la projection spécifiée en paramètre du constructeur à une géométrie. La projection peut aussi être appliquée en sens inverse.

OffsetTransformation

Applique une translation en x et en y, tel que spécifié en paramètre du constructeur, à une géométrie.

SmoothTransformation

Applique une généralisation, selon la tolérance spécifiée en paramètre du constructeur, à une géométrie.

PrecisionTransformation.TO_FLOAT

Transforme une géométrie double précision en une géométrie simple précision.

PrecisionTransformation.TO_DOUBLE

Transforme une géométrie simple précision en une géométrie double précision.

 

L'exemple de code suivant montre comment utiliser la transformation de changement de précision.

 

Point[] points = new Point[]
{
  new Point.Double(10., 10.),
  new Point.Double(20., 20.),
  new Point.Double(30., 30.)
};
 
LineString doubleLineString = new LineString( points );
 
// The transformation can be done by the geometry. After the execution, doubleLineString
// will still contain single precision coordinates.
LineString singleLineString1 = (LineString)doubleLineString.transform(PrecisionTransformation.TO_FLOAT);
 
// The transformation is made directly on the geometry. After the execution, doubleLineString
// will contain single precision coordinates. Moreover, singleLineString2 refers to the same
// instance as doubleLineString.
LineString singleLineString2 = (LineString)PrecisionTransformation.TO_FLOAT.transform(doubleLineString);
 

 

 

L'exemple de code suivant montre comment utiliser la transformation de changement de projection cartographique.

 

Point[] points = new Point[]
{
  new Point.Double(-73.12345, 45.12345),
  new Point.Double(-73.54321, 45.54321)
};
 
LineString lineString = new LineString( points );
 
// Define the source and the destination projections
Projection fromProjection = new LongitudeLatitude();
 
Projection toProjection = new Mtm();
toProjection.setParams("8"); // zone 8
 
// Create a combined projection object that converts points from one projection
// to the other
final CombinedProjection combinedProj = new CombinedProjection(fromProjection, toProjection);
 
// Apply the projection transformation
lineString = (LineString)lineString.transform(new ProjectionTransformation(combinedProj));
 

 

 

 

L'exemple de code suivant montre comment créer une classe de transformation anonyme en utilisant l'adaptateur TransformationAdapter. La transformation convertit les points en ellipses.

 
Point[] points = new Point[]
{
  new Point.Double(10., 10.),
  new Point.Double(20., 20.),
  new Point.Double(30., 30.)
};
 
// Create a new transformation which creates a new ellipse at the
// specified location.
Transformation tr = new TransformationAdapter()
{
  public Geometry transform(Point point)
  {
    return new Ellipse(
      (Point)point.clone(), new Dimension.Double(5, 3), 0
    );
  }
};
 
// Apply the transformation on all points 
Ellipse[] ellipses = new Ellipse[points.length];
for (int i = 0; i < ellipses.length; i++)
  ellipses[i] = (Ellipse)tr.transform(points[i]);
 

 

Rectangle englobant

Le rectangle englobant (MBR pour Minimum Bounding Rectangle) d'une géométrie est le plus petit rectangle orthogonal qui englobe totalement la géométrie. Le MBR est utilisé dans JMap pour effectuer des analyses spatiales rapides sur une grande quantité de géométries avant d'utiliser des algorithmes plus précis (mais plus lents) sur un nombre plus restreint de géométries. Tel que prescrit par l'interface Geometry de JMap, tous les types de géométries implémentent la méthode getBounds() qui retourne le MBR de la géométrie.

Le MBR d'un point est un rectangle de largeur 0 et de hauteur 0. Le MBR d'une ligne verticale est un rectangle de largeur 0 et le MBR d'une ligne horizontale est un rectangle de hauteur 0.

 

Exemples de rectangles englobants

Exemples de rectangles englobants