Introduction à GeoTools

Introduction à GeoTools

1. Vue d'ensemble

Dans cet article, nous allons passer en revue les bases desGeoTools open source Java library – for working with geospatial data. Cette bibliothèque fournit des méthodes conformes pour la mise en œuvre de systèmes d'information géographique (SIG) et implémente et prend en charge de nombreuses normes du consortium Open Geospatial Consortium (OGC).

Au fur et à mesure que l'OGC développe de nouvelles normes, elles sont mises en œuvre par les GeoTools, ce qui le rend très pratique pour les travaux géospatiaux.

2. Les dépendances

Nous devrons ajouter les dépendances GeoTools à notre fichierpom.xml. Étant donné que ces dépendances ne sont pas hébergées sur Maven Central, nous devons également déclarer leurs référentiels afin que Maven puisse les télécharger:


    
        osgeo
        Open Source Geospatial Foundation Repository
        http://download.osgeo.org/webdav/geotools/
    
    
        opengeo
        OpenGeo Maven Repository
        http://repo.opengeo.org
    

Après cela, nous pouvons ajouter nos dépendances:


    org.geotools
    gt-shapefile
    15.2


    org.geotools
    gt-epsg-hsql
    15.2

3. SIG et Shapefiles

Pour avoir une utilisation pratique de la bibliothèque GeoTools, nous aurons besoin de quelques informations sur les systèmes d'information géographique et lesshapefiles.

3.1. GIS

Si nous voulons travailler avec des données géographiques, nous aurons besoin d’un système d’information géographique (SIG). Ce système peut être utiliséto present, capture, store, manipulate, analyze, or manage geographical data.

Une partie des données géographiques est spatiale - elle fait référence à des emplacements concrets sur la Terre. Les données spatiales sont généralement accompagnées des données d'attribut. Les données d'attributs peuvent être des informations supplémentaires sur chacune des entités spatiales.

Un exemple de données géographiques serait les villes. La localisation réelle des villes correspond aux données spatiales. Des données supplémentaires telles que le nom de la ville et la population constitueraient les données d'attribut.

3.2. Fichiers de formes

Différents formats sont disponibles pour travailler avec des données géospatiales. Le raster et le vecteur sont les deux principaux types de données.

Dans cet article, nous allons voir comment travailler avec le type de données vectoriellese. Ce type de données peut être représenté sous forme de points, de lignes ou de polygones.

Pour stocker des données vectorielles dans un fichier, nous utiliserons unshapefile. Ce format de fichier est utilisé lorsque vous travaillez avec le type de données vectoriel géospatial. En outre, il est compatible avec une large gamme de logiciels SIG.

Nous pouvons utiliser GeoTools pour ajouter des fonctionnalités telles que des villes, des écoles et des points de repère àshapefiles.

4. Créer des fonctionnalités

La documentation deGeoTools spécifie qu'une entité est tout ce qui peut être dessiné sur une carte, comme une ville ou un repère. Et, comme nous l'avons mentionné, une fois créées, les fonctionnalités peuvent être enregistrées dans des fichiers appelésshapefiles.

4.1. Conservation des données géospatiales

Before creating a feature, we need to know its geospatial data or the longitude and latitude coordinates of its location on earth. Comme pour les données d'attributs, nous avons besoin de connaître le nom de l'entité que nous voulons créer.

Cette information peut être trouvée sur le web. Certains sites commesimplemaps.com oumaxmind.com offrent des bases de données gratuites avec des données géospatiales.

Lorsque nous connaissons la longitude et la latitude d'une ville, nous pouvons facilement les stocker dans un objet. Nous pouvons utiliser un objetMap qui contiendra le nom de la ville et une liste de ses coordonnées.

Créons une méthode d'assistance pour faciliter le stockage des données dans notre objetMap:

private static void addToLocationMap(
  String name,
  double lat,
  double lng,
  Map> locations) {
    List coordinates = new ArrayList<>();

    coordinates.add(lat);
    coordinates.add(lng);
    locations.put(name, coordinates);
}

Maintenant, remplissons notre objetMap:

Map> locations = new HashMap<>();

addToLocationMap("Bangkok", 13.752222, 100.493889, locations);
addToLocationMap("New York", 53.083333, -0.15, locations);
addToLocationMap("Cape Town", -33.925278, 18.423889, locations);
addToLocationMap("Sydney", -33.859972, 151.211111, locations);
addToLocationMap("Ottawa", 45.420833, -75.69, locations);
addToLocationMap("Cairo", 30.07708, 31.285909, locations);

Si nous téléchargeons une base de données CSV contenant ces données, nous pouvons facilement créer un lecteur pour récupérer les données au lieu de les conserver dans un objet comme ici.

4.2. Définition des types d'entités

Nous avons maintenant une carte des villes. To be able to create features with this data, we’ll need to define their type first. GeoTools propose deux façons de définir les types d'entités.

Une façon consiste à utiliser la méthodecreateType de la classeDataUtilites:

SimpleFeatureType TYPE = DataUtilities.createType(
  "Location", "location:Point:srid=4326," + "name:String");

Une autre façon est deuse a SimpleFeatureTypeBuilder, which provides more flexibility. Par exemple, nous pouvons définir le système de référence de coordonnées pour le type et définir une longueur maximale pour le champ de nom:

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Location");
builder.setCRS(DefaultGeographicCRS.WGS84);

builder
  .add("Location", Point.class);
  .length(15)
  .add("Name", String.class);

SimpleFeatureType CITY = builder.buildFeatureType();

Both types store the same information. L'emplacement de la ville est stocké en tant quePoint, et le nom de la ville est stocké en tant queString.

Vous avez probablement remarqué que les variables de typeTYPE etCITY sont nommées avec toutes les lettres majuscules, comme des constantes. Type variables should be treated as final variables and should not be changed after they are created, donc cette façon de nommer peut être utilisée pour indiquer cela.

4.3. Création de fonctionnalités et collections de fonctionnalités

Une fois que le type d’entité est défini et que l’objet contient les données nécessaires à la création des entités, nous pouvons commencer à les créer avec leur générateur.

Instancions unSimpleFeatureBuilder en fournissant notre type d'entité:

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY);

Nous aurons également besoin d'une collection pour stocker tous les objets caractéristiques créés:

DefaultFeatureCollection collection = new DefaultFeatureCollection();

Puisque nous avons déclaré dans notre type d'entité contenir unPoint pour l'emplacement, nous aurons besoin decreate points for our cities based on their coordinates. Nous pouvons le faire avec lesGeoTools’s JTSGeometryFactoryFinder:

GeometryFactory geometryFactory
  = JTSFactoryFinder.getGeometryFactory(null);

Notez quewe can also use other Geometry classes like Line and Polygon.

Nous pouvons créer unfunction qui nous aidera à mettre des fonctionnalités dans la collection:

private static Function>, SimpleFeature>
  toFeature(SimpleFeatureType CITY, GeometryFactory geometryFactory) {
    return location -> {
        Point point = geometryFactory.createPoint(
           new Coordinate(location.getValue()
             .get(0), location.getValue().get(1)));

        SimpleFeatureBuilder featureBuilder
          = new SimpleFeatureBuilder(CITY);
        featureBuilder.add(point);
        featureBuilder.add(location.getKey());
        return featureBuilder.buildFeature(null);
    };
}

Une fois que nous avons le constructeur et la collection, en utilisant lesfunction précédemment créés, nous pouvonscreate features and store them in our collection:

locations.entrySet().stream()
  .map(toFeature(CITY, geometryFactory))
  .forEach(collection::add);

La collection contient désormais toutes les entités créées à partir de notre objetMap qui contenait les données géospatiales.

5. Créer un DataStore

GeoTools contient unDataStore API qui est utilisé pour représenter une source de données géospatiales. Cette source peut être un fichier, une base de données ou un service qui renvoie des données. Nous pouvons utiliser unDataStoreFactory pour créer nosDataStore, qui contiendront nos fonctionnalités.

Définissons le fichier qui contiendra les fonctionnalités:

File shapeFile = new File(
  new File(".").getAbsolutePath() + "shapefile.shp");

Maintenant, définissons les paramètres que nous allons utiliser pour indiquer auxDataStoreFactory quel fichier utiliser et indiquer que nous devons stocker un index spatial lorsque nous créons nosDataStore:

Map params = new HashMap<>();
params.put("url", shapeFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);

Créons lesDataStoreFactory en utilisant les paramètres que nous venons de créer, et utilisons cette fabrique pour créer lesDataStore:

ShapefileDataStoreFactory dataStoreFactory
  = new ShapefileDataStoreFactory();

ShapefileDataStore dataStore
  = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
dataStore.createSchema(CITY);

6. Ecrire dans un Shapefile

La dernière étape que nous devons faire est d'écrire nos données dans unshapefile. Pour faire cela en toute sécurité, nous allons versuse the Transaction interface qui fait partie de l'APIGeoTools.

Cette interface nous donne la possibilité deeasily commit our the changes to the file. Il fournit également un moyen deperform a rollback of the unsuccessful changes if some problem occurs lors de l'écriture dans le fichier:

Transaction transaction = new DefaultTransaction("create");

String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource
  = dataStore.getFeatureSource(typeName);

if (featureSource instanceof SimpleFeatureStore) {
    SimpleFeatureStore featureStore
      = (SimpleFeatureStore) featureSource;

    featureStore.setTransaction(transaction);
    try {
        featureStore.addFeatures(collection);
        transaction.commit();

    } catch (Exception problem) {
        transaction.rollback();
    } finally {
        transaction.close();
    }
}

LeSimpleFeatureSource est utilisé pour lire les caractéristiques, et leSimpleFeatureStore est utilisé pour l'accès en lecture / écriture. Il est spécifié dans la documentation deGeoTools que l'utilisation de la méthodeinstanceof pour vérifier si nous pouvons écrire dans le fichier est la bonne façon de le faire.

Ceshapefile peut être ouvert ultérieurement avec n'importe quel visualiseur SIG prenant en chargeshapefile.

7. Conclusion

Dans cet article, nous avons vu comment nous pouvons utiliser la bibliothèqueGeoTools pour effectuer un travail géospatial très intéressant.

Bien que l'exemple soit simple, il peut être étendu et utilisé pour créer desshapefilesriches à diverses fins.

Nous devons garder à l'esprit queGeoTools est une bibliothèque dynamique, et cet article sert simplement d'introduction de base à la bibliothèque. De plus,GeoTools ne se limite pas à la création de types de données vectorielles uniquement - il peut également être utilisé pour créer ou travailler avec des types de données raster.

Vous pouvez trouver l'exemple de code complet utilisé dans cet article dans nosGitHub project. Ceci est un projet Maven, vous devriez donc pouvoir l’importer et le lancer tel quel.