Intégration avancée des fonctions géospatiales MySQL avec Java Spring Boot

1. Modélisation géométrique dans MySQL

Pour gérer efficacement des données localisées, MySQL propose des types géométriques natifs tels que POINT, POLYGON ou LINESTRING. Une table typique pourrait être définie ainsi :

CREATE TABLE location_map (
  id INT PRIMARY KEY AUTO_INCREMENT,
  anchor POINT NOT NULL SRID 4326,
  boundary POLYGON NOT NULL SRID 4326,
  INDEX idx_anchor (anchor) USING SPATIAL,
  INDEX idx_boundary (boundary) USING SPATIAL
);

Remarque importante : les index spatiaux exigent que les colonnes soient déclarées NOT NULL et qu’un SRID (système de référence spatiale) soit explicitement spécifié — ici SRID 4326 pour WGS84.

2. Requêtes géospatiales courantes

Les fonctions ST_Within et ST_Intersects permettent de tester des relations topologiques entre géométries. Exemples concrets :

  • Vérifier si un point donné est à l’intérieur d’un polygone :
SELECT id FROM location_map 
WHERE ST_Within(
  ST_GeomFromText('POINT(12.345 45.678)', 4326), 
  boundary
);
  • Détecter l’intersection entre deux polygones (par exemple, zones administratives chevauchantes) :
SELECT a.id AS zone_a, b.id AS zone_b
FROM location_map a, location_map b
WHERE a.id < b.id 
  AND ST_Intersects(a.boundary, b.boundary);

Attention : les polygones doivent être fermés — la première et dernière coordonnée doivent coïncider, sinon ST_GeomFromText() échouera ou produira un comportement imprévisible.

3. Intégration côté Java avec JTS et MyBatis

Pour manipuler des géométries en Java, la bibliothèque JTS Topology Suite (v1.19+) est recommandée. Elle remplace avantageusement la version obsolète com.vividsolutions:jts.

Voici un gestionnaire de type personnalisé compatible avec MyBatis :

@MappedTypes({Point.class})
@Component
public class PointTypeHandler extends BaseTypeHandler<Point> {

  private final GeometryFactory factory = new GeometryFactory(new PrecisionModel(), 4326);

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, Point point, JdbcType jdbcType) 
      throws SQLException {
    if (point == null) {
      ps.setNull(i, Types.BINARY);
      return;
    }
    WKBWriter writer = new WKBWriter(2, true);
    byte[] wkb = writer.write(point);
    ps.setBytes(i, wkb);
  }

  @Override
  public Point getNullableResult(ResultSet rs, String columnName) throws SQLException {
    byte[] data = rs.getBytes(columnName);
    return parseWKB(data);
  }

  private Point parseWKB(byte[] bytes) {
    if (bytes == null) return null;
    try {
      WKBReader reader = new WKBReader(factory);
      return (Point) reader.read(bytes);
    } catch (ParseException e) {
      throw new IllegalArgumentException("Invalid WKB geometry", e);
    }
  }
}

4. Calculs géométriques précis avec GeoTools

Pour obtenir des mesures réelles (surface en m², longueur en mètres), il faut reprojeter les géométries depuis le système géodésique (WGS84) vers un système projeté comme EPSG:3857 ou EPSG:3395. Voici une implémentation robuste utilisant GeoTools 28+ :

public double computeAreaInSquareMeters(Geometry geom) {
  if (geom == null || geom.isEmpty()) return 0.0;

  try {
    CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
    CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3395"); // Mercator sphérique
    MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
    Geometry projected = JTS.transform(geom, transform);
    return projected.getArea();
  } catch (Exception e) {
    throw new IllegalStateException("Failed to project geometry for area calculation", e);
  }
}

Cette approche garantit une précision métrique acceptable pour la plupart des applications cartographiques — contrairement à EPSG:3857, qui distord les surfaces aux hautes latitudes.

5. Dépendances Maven recommandées

<dependency>
  <groupId>org.locationtech.jts</groupId>
  <artifactId>jts-core</artifactId>
  <version>1.19.0</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-main</artifactId>
  <version>28.4</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-referencing</artifactId>
  <version>28.4</version>
</dependency>

Aucune configuration de dépôt supplémentaire n’est requise : GeoTools 28+ est publié sur Maven Central.

Étiquettes: MySQL Java spring-boot jts geotools

Publié le 19 août à 01h48