Введение в GeoTools

Введение в GeoTools

1. обзор

В этой статье мы рассмотрим основыGeoTools open source Java library – for working with geospatial data. Эта библиотека предоставляет совместимые методы для реализации географических информационных систем (ГИС), а также реализует и поддерживает многие стандарты Open Geospatial Consortium (OGC).

По мере того как OGC разрабатывает новые стандарты, они внедряются с помощью GeoTools, что делает его весьма удобным для работы с геопространственными данными.

2. зависимости

Нам нужно будет добавить зависимости GeoTools в наш файлpom.xml. Поскольку эти зависимости не размещаются в Maven Central, нам также необходимо объявить их репозитории, чтобы Maven мог их загрузить:


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

После этого мы можем добавить наши зависимости:


    org.geotools
    gt-shapefile
    15.2


    org.geotools
    gt-epsg-hsql
    15.2

3. ГИС и шейп-файлы

Для практического использования библиотеки GeoTools нам нужно знать кое-что о географических информационных системах иshapefiles.

3.1. GIS

Если мы хотим работать с географическими данными, нам понадобится географическая информационная система (ГИС). Эту систему можно использоватьto present, capture, store, manipulate, analyze, or manage geographical data.

Некоторая часть географических данных является пространственной - она ​​ссылается на конкретные места на земле. Пространственные данные обычно сопровождаются данными атрибута. Атрибут данных может представлять собой любую дополнительную информацию о каждом из пространственных признаков.

Примером географических данных могут быть города. Фактическое местоположение городов - пространственные данные. Дополнительные данные, такие как название города и население, составляют данные атрибута.

3.2. Шейп-файлы

Для работы с геопространственными данными доступны разные форматы. Растр и вектор - это два основных типа данных.

В этой статье мы увидим, как работать с векторными данными типаe. Этот тип данных может быть представлен в виде точек, линий или многоугольников.

Для хранения векторных данных в файле мы будем использоватьshapefile. Этот формат файла используется при работе с типом геопространственных векторных данных. Кроме того, он совместим с широким спектром программного обеспечения ГИС.

Мы можем использовать GeoTools для добавления таких функций, как города, школы и достопримечательности вshapefiles.

4. Создание функций

В документацииGeoTools указано, что объект - это все, что можно нарисовать на карте, например, город или какой-либо ориентир. И, как мы уже упоминали, после создания функции можно сохранять в файлы с именемshapefiles.

4.1. Хранение геопространственных данных

Before creating a feature, we need to know its geospatial data or the longitude and latitude coordinates of its location on earth. Что касается данных атрибутов, нам нужно знать имя объекта, который мы хотим создать.

Эту информацию можно найти в Интернете. Некоторые сайты, такие какsimplemaps.com илиmaxmind.com, предлагают бесплатные базы данных с геопространственными данными.

Когда мы знаем долготу и широту города, мы можем легко сохранить их в каком-либо объекте. Мы можем использовать объектMap, который будет содержать название города и список его координат.

Давайте создадим вспомогательный метод, чтобы упростить хранение данных внутри нашего объекта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);
}

Теперь давайте заполним наш объект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);

Если мы загрузим некоторую базу данных CSV, которая содержит эти данные, мы можем легко создать ридер для извлечения данных вместо того, чтобы хранить их в объекте, как здесь.

4.2. Определение типов функций

Итак, теперь у нас есть карта городов. To be able to create features with this data, we’ll need to define their type first. GeoTools предлагает два способа определения типов объектов.

Один из способов - использовать методcreateType классаDataUtilites:

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

Другой способ -use a SimpleFeatureTypeBuilder, which provides more flexibility. Например, мы можем установить систему координат для типа и установить максимальную длину для поля имени:

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. Местоположение города сохраняется какPoint, а название города сохраняется какString.

Вы, наверное, заметили, что переменные типаTYPE иCITY названы заглавными буквами, как константы. Type variables should be treated as final variables and should not be changed after they are created, поэтому этот способ именования можно использовать для обозначения именно этого.

4.3. Создание функций и коллекции функций

После того, как мы определили тип объекта и у нас есть объект, содержащий данные, необходимые для создания объектов, мы можем начать создавать их с помощью их конструктора.

Давайте создадим экземплярSimpleFeatureBuilder, предоставляющий наш тип функции:

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY);

Также нам понадобится коллекция для хранения всех созданных объектов функций:

DefaultFeatureCollection collection = new DefaultFeatureCollection();

Поскольку мы объявили в нашем типе объекта, чтобы хранитьPoint для местоположения, нам понадобитсяcreate points for our cities based on their coordinates. Мы можем сделать это с помощьюGeoTools’s JTSGeometryFactoryFinder:

GeometryFactory geometryFactory
  = JTSFactoryFinder.getGeometryFactory(null);

Обратите внимание, чтоwe can also use other Geometry classes like Line and Polygon.

Мы можем создатьfunction, который поможет нам поместить функции в коллекцию:

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

Когда у нас есть конструктор и коллекция, используя ранее созданныйfunction, мы можемcreate features and store them in our collection:

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 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. Чтобы сделать это безопасно, мы перейдем кuse the Transaction interface, который является частью APIGeoTools.

Этот интерфейс дает нам возможностьeasily commit our the changes to the file. Он также предоставляет способperform a rollback of the unsuccessful changes if some problem occurs при записи в файл:

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.

7. Заключение

В этой статье мы увидели, как мы можем использовать библиотекуGeoTools для выполнения очень интересной геопространственной работы.

Хотя пример был прост, его можно расширить и использовать для создания расширенныхshapefiles для различных целей.

Мы должны иметь в виду, чтоGeoTools - яркая библиотека, и эта статья служит лишь базовым введением в библиотеку. Кроме того,GeoTools не ограничивается только созданием векторных типов данных - его также можно использовать для создания или работы с растровыми типами данных.

Вы можете найти полный пример кода, использованного в этой статье, в нашемGitHub project. Это проект Maven, поэтому вы можете импортировать его и запустить как есть.