GeoToolsの紹介

1概要

この記事では、地理空間データを扱うための** GeoTools オープンソースJavaライブラリーの基本について説明します。このライブラリは、地理情報システム(GIS)を実装するための準拠メソッドを提供し、多くのOpen Geospatial Consortium(OGC)標準を実装およびサポートします。

OGCが新しい標準を開発するにつれて、それらはGeoToolsによって実装され、地理空間作業に非常に便利になります。

2依存関係

GeoToolsの依存関係を pom.xml ファイルに追加する必要があります。これらの依存関係はMaven Centralでホストされていないので、Mavenがそれらをダウンロードできるように、それらのリポジトリを宣言する必要もあります。

<repositories>
    <repository>
        <id>osgeo</id>
        <name>Open Source Geospatial Foundation Repository</name>
        <url>http://download.osgeo.org/webdav/geotools/</url>
    </repository>
    <repository>
        <id>opengeo</id>
        <name>OpenGeo Maven Repository</name>
        <url>http://repo.opengeo.org</url>
    </repository>
</repositories>

その後、依存関係を追加することができます。

<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-shapefile</artifactId>
    <version>15.2</version>
</dependency>
<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-epsg-hsql</artifactId>
    <version>15.2</version>
</dependency>

3 GISとシェープファイル

GeoToolsライブラリを実用的に使用するには、地理情報システムと shapefiles についていくつか知っておく必要があります。

3.1. GIS

地理データを使用したい場合は、地理情報システム(GIS)が必要です。このシステムは、地理データの表示、取得、保存、操作、分析、管理に使用できます。

地理データの一部は空間的なものです - 地球上の具体的な場所を参照しています。空間データには通常、属性データが伴います。属性データは、空間的特徴のそれぞれについての任意の追加情報であり得る。

地理データの例は都市です。都市の実際の場所は空間データです。都市名や人口などの追加データが属性データを構成します。

3.2. シェープファイル

地理空間データを操作するためのさまざまな形式があります。ラスターとベクトルは、2つの主要なデータ型です。

この記事では、 e のようなベクトルデータを扱う方法を説明します。このデータ型は、ポイント、ライン、またはポリゴンとして表すことができます。

ベクトルデータをファイルに保存するために、 shapefile を使います。このファイル形式は、地理空間ベクトルデータ型を扱うときに使用されます。また、幅広いGISソフトウェアと互換性があります。

GeoToolsを使用して、都市、学校、ランドマークなどの機能を shapefiles に追加できます。

4フィーチャーを作成する

GeoTools のドキュメントでは、都市やランドマークのように、地物は地図上に描くことができるものであると指定されています。そして、すでに述べたように、作成したフィーチャーは shapefiles というファイルに保存できます。

4.1. 地理空間データの保持

  • フィーチャを作成する前に、その地理空間データまたは地球上の位置の経度と緯度座標を知る必要があります** 属性データに関しては、作成したいフィーチャの名前を知る必要があります。

この情報はWeb上にあります。 simplemaps.com やhttps://www.maxmind.com/en/free-world-cities-database[maxmind.com]のようないくつかのサイトは、地理空間データ

都市の経度と緯度がわかれば、簡単にそれらを何らかのオブジェクトに格納できます。都市名とその座標のリストを保持する Map オブジェクトを使用できます。

Map オブジェクト内にデータを簡単に格納できるように、ヘルパーメソッドを作成しましょう。

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

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

それでは、 Map オブジェクトに記入しましょう。

Map<String, List<Double>> 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);

このデータを含むCSVデータベースをダウンロードすれば、このようなオブジェクトに保存するのではなく、データを取得するリーダーを簡単に作成できます。

4.2. フィーチャタイプの定義

だから、今私たちは都市の地図を持っています。 このデータを使用してフィーチャを作成できるようにするには、まずそのタイプを定義する必要があります。 GeoToolsには、フィーチャタイプを定義する2つの方法があります。

1つの方法は、 DataUtilites クラスの createType メソッドを使用することです。

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

もう1つの方法は、** __ SimpleFeatureTypeBuilderを使用することです。たとえば、タイプに座標参照系を設定し、名前フィールドに最大長を設定できます。

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();
  • どちらのタイプも同じ情報を格納します** 都市の場所は Point として格納され、都市の名前は String として格納されます。

型変数 TYPE CITY は、定数のようにすべて大文字で命名されていることにお気づきでしょうか。 型変数は final 変数として扱われるべきであり、それらが作成された後に変更されるべきではありません そのため、この命名方法はそれを示すために使用することができます。

4.3. フィーチャー作成とフィーチャーコレクション

フィーチャタイプを定義し、フィーチャを作成するために必要なデータを持つオブジェクトを作成したら、ビルダーを使用してそれらの作成を開始できます。

機能タイプを指定して SimpleFeatureBuilder をインスタンス化しましょう。

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY);

作成したすべてのフィーチャオブジェクトを格納するためのコレクションも必要です。

DefaultFeatureCollection collection = new DefaultFeatureCollection();

場所の Point を保持するようにフィーチャタイプで宣言したので、それらの座標に基づいて** 都市のポイントを作成する必要があります。これは GeoToolsのJTSGeometryFactoryFinder を使って実行できます。

GeometryFactory geometryFactory
  = JTSFactoryFinder.getGeometryFactory(null);
  • LineやPolygonのような他のGeometryクラスを使うこともできます。

コレクションに機能を追加するのに役立つ function を作成できます。

private static Function<Map.Entry<String, List<Double>>, 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);
    };
}

ビルダーとコレクションを取得したら、以前に作成した function を使用して、機能を作成してコレクションに保存することができます。

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

コレクションには、地理空間データを保持する Map オブジェクトに基づいて作成されたすべての機能が含まれています。

5データストアの作成

GeoTools には、地理空間データのソースを表すために使用される DataStore API が含まれています。このソースは、ファイル、データベース、またはデータを返すサービスです。 DataStoreFactory を使用して DataStore を作成できます。これには機能が含まれます。

機能を含むファイルを設定しましょう。

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

それでは、使用するパラメータを設定して、使用するファイルを DataStoreFactory に設定し、 DataStore を作成するときに空間インデックスを格納する必要があることを示します。

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

今作成したパラメータを使用して DataStoreFactory を作成し、そのファクトリを使用して DataStore を作成しましょう。

ShapefileDataStoreFactory dataStoreFactory
  = new ShapefileDataStoreFactory();

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

6. シェープファイルへの書き込み

最後にする必要があるのは、データを shapefile に書き込むことです。

これを安全に行うために、GeoTools APIの一部であるTransactionインターフェースを使用します。

このインタフェースは、ファイルへの変更を 簡単にコミットする ことを可能にします。また、ファイルへの書き込み中に何らかの問題が発生した場合に、失敗した変更を「ロールバック」する方法もあります。

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

SimpleFeatureSource は機能の読み取りに使用され、 SimpleFeatureStore は読み取り/書き込みアクセスに使用されます。 GeoTools のドキュメントでは、ファイルに書き込むことができるかどうかをチェックするために instanceof メソッドを使用するのが正しい方法であると指定されています。

この shapefile は、 shapefile をサポートしているGISビューアで後で開くことができます。

7. 結論

この記事では、 GeoTools ライブラリーを使用して非常に興味深い地理空間作業を行う方法を説明しました。

例は簡単でしたが、さまざまな目的のために豊富な shapefiles を作成するために拡張して使用することができます。

GeoTools は活気のあるライブラリであり、この記事は単にライブラリの基本的な紹介としての役割を果たすことに留意する必要があります。また、 GeoTools はベクトルデータ型の作成だけに限定されているわけではありません。ラスタデータ型の作成や使用にも使用できます。

この記事で使用されている完全なサンプルコードはhttps://github.com/eugenp/tutorials/tree/master/geotools[GitHubプロジェクト]にあります。これはMavenプロジェクトなので、インポートしてそのまま実行できるはずです。