Introduction à GeoTools

1. Vue d'ensemble

Dans cet article, nous allons passer en revue les bases de la bibliothèque Java open source GeoTools - pour travailler avec des données géospatiales . Cette bibliothèque fournit des méthodes conformes pour la mise en œuvre de systèmes d'information géographique (SIG) et met en œuvre et prend en charge de nombreuses normes 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. Dépendances

Nous devrons ajouter les dépendances GeoTools à notre fichier pom.xml . Comme 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 //download.osgeo.org/webdav/geotools/   opengeo OpenGeo Maven Repository //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 connaître quelques informations sur les systèmes d'information géographique et les fichiers de formes .

3.1. SIG

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é pour présenter, capturer, stocker, manipuler, analyser ou gérer des données géographiques .

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

Un exemple de données géographiques serait les villes. L'emplacement réel 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 vectorielles e . 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 un fichier de formes . Ce format de fichier est utilisé lorsque vous travaillez avec le type de données vectorielles géospatiales. 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 aux fichiers de formes .

4. Création de fonctionnalités

La documentation GeoTools 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és fichiers de formes .

4.1. Conservation des données géospatiales

Avant de créer une entité, nous devons connaître ses données géospatiales ou les coordonnées de longitude et de latitude de son emplacement sur Terre. En ce qui concerne les données d'attributs, nous devons connaître le nom de l'entité que nous voulons créer.

Ces informations peuvent être trouvées sur le Web. Certains sites comme simplemaps.com ou maxmind.com proposent 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 objet Map 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 objet Map :

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 objet Map :

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

Donc, maintenant nous avons une carte des villes. Pour pouvoir créer des entités avec ces données, nous devons d'abord définir leur type. GeoTools propose deux façons de définir les types d'entités.

Une façon consiste à utiliser la méthode createType de la classe DataUtilites :

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

Une autre façon consiste à utiliser un SimpleFeatureTypeBuilder , qui offre plus de flexibilité . Par exemple, nous pouvons définir le système de référence de coordonnées pour le type, et nous pouvons 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();

Les deux types stockent les mêmes informations. L'emplacement de la ville est stocké sous forme de point et le nom de la ville est stocké sous forme de chaîne .

You probably noticed that the type variables TYPE and CITY are named with all capital letters, like constants. Type variables should be treated as final variables and should not be changed after they are created, so this way of naming can be used to indicate just that.

4.3. Feature Creation and Feature Collections

Once we have the feature type defined and we have an object that has the data needed to create features, we can start creating them with their builder.

Let's instantiate a SimpleFeatureBuilder providing our feature type:

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY);

We'll also need a collection to store all the created feature objects:

DefaultFeatureCollection collection = new DefaultFeatureCollection();

Since we declared in our feature type to hold a Point for the location, we'll need to create points for our cities based on their coordinates. We can do this with the GeoTools's JTSGeometryFactoryFinder:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);

Note that we can also use other Geometry classes like Line and Polygon.

We can create a function that will help us put features in the 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); }; }
    

Once we have the builder and the collection, by using the previously created function, we can create features and store them in our collection:

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

The collection now contains all the features created based on our Map object that held the geospatial data.

5. Creating a DataStore

GeoTools contains a DataStore API that is used to represent a source of geospatial data. This source can be a file, a database, or some service that returns data. We can use a DataStoreFactory to create our DataStore, which will contain our features.

Let's set the file that will contain the features:

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

Now, let's set the parameters that we are going to use to tell the DataStoreFactory which file to use and indicate that we need to store a spatial index when we create our DataStore:

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

Let's create the DataStoreFactory using the parameters we just created, and use that factory to create the DataStore:

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

6. Writing to a Shapefile

The last step that we need to do is to write our data to a shapefile. To do this safely, we are going to use the Transaction interface that is a part of the GeoTools API.

This interface gives us the possibility to easily commit our the changes to the file. It also provides a way to perform a rollback of the unsuccessful changes if some problem occurs while writing to the file:

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

The SimpleFeatureSource is used to read features, and the SimpleFeatureStore is used for read/write access. It is specified in the GeoTools documentation that using the instanceof method for checking if we can write to the file is the right way to do so.

This shapefile can later be opened with any GIS viewer that has shapefile support.

7. Conclusion

In this article, we saw how we can make use of the GeoTools library to do some very interesting geo-spatial work.

Although the example was simple, it can be extended and used for creating rich shapefiles for various purposes.

Nous devons garder à l'esprit que GeoTools est une bibliothèque dynamique, et cet article sert simplement d'introduction de base à la bibliothèque. En outre, 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 notre projet GitHub. Il s'agit d'un projet Maven, vous devriez donc pouvoir l'importer et l'exécuter tel quel.