Разобрать файл GeoJSON с помощью Java Topology Suite или GeoTools

Например, если у вас есть такой файл GeoJSON с полигоном (простой файл для теста)

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -4.658203125,
              41.343824581185686
            ],
            [
              -5.6689453125,
              39.13006024213511
            ],
            [
              -1.9335937499999998,
              39.16414104768742
            ],
            [
              -1.3623046875,
              41.21172151054787
            ],
            [
              -4.658203125,
              41.343824581185686
            ]
          ]
        ]
      }
    }
  ]
}

Точка:

Geometry point2 = new WKTReader().read("POINT (-3.2958984375 40.44694705960048)");

И вы хотите загрузить файл geoJSON в свою программу для проверки того, что этот многоугольник содержит точку, как вы могли бы сделать это на Java с помощью JTS?


Другим вариантом может быть использование GeoTools с плагином GeoJson, но я не способен анализировать файл GeoJson


Что я пробовал

Использование GEOTOOLS, например этого.

String content = new String(Files.readAllBytes(Paths.get("file.geojson")), "UTF-8");
GeometryJSON gjson = new GeometryJSON();
Reader reader = new StringReader(content);
Polygon p = gjson.readPolygon(reader);
System.out.println("polygon: " + p);

Проблема здесь в том, что многоугольник p содержит только последний многоугольник файла geojson. Если в этом файле много полигонов, как мне его разобрать?

Используя JTS2GEOJSON, например это

String content = new String(Files.readAllBytes(Paths.get("file.geojson")), "UTF-8");
System.out.println("content: " + content);
GeoJSONReader reader1 = new GeoJSONReader();
Geometry geometry = reader1.read(content);

Этот код не работает в этой строке:

Geometry geometry = reader1.read(content);

С этой ошибкой:

Exception in thread "main" java.lang.UnsupportedOperationException
    at org.wololo.jts2geojson.GeoJSONReader.read(GeoJSONReader.java:51)
    at org.wololo.jts2geojson.GeoJSONReader.read(GeoJSONReader.java:21)
    at org.wololo.jts2geojson.GeoJSONReader.read(GeoJSONReader.java:16)

Эта ошибка связана с тем, что я пытаюсь прочитать FeatureCollections из файла GeoJson. Это работает, если я попробовал эту простую строку:

   String content = "{\n" +
                "        \"type\": \"Polygon\",\n" +
                "        \"coordinates\": [\n" +
                "          [\n" +
                "            [\n" +
                "              -4.141845703125,\n" +
                "              40.9218144123785\n" +
                "            ],\n" +
                "            [\n" +
                "              -4.603271484375,\n" +
                "              40.002371935876475\n" +
                "            ],\n" +
                "            [\n" +
                "              -3.5595703125,\n" +
                "              39.757879992021756\n" +
                "            ],\n" +
                "            [\n" +
                "              -2.548828125,\n" +
                "              40.43858586704331\n" +
                "            ],\n" +
                "            [\n" +
                "              -3.2080078125,\n" +
                "              41.12074559016745\n" +
                "            ],\n" +
                "            [\n" +
                "              -4.141845703125,\n" +
                "              40.9218144123785\n" +
                "            ]\n" +
                "          ]\n" +
                "        ]\n" +
                "      }";

person IoT user    schedule 28.12.2018    source источник
comment
что ты уже испробовал?   -  person Ian Turton    schedule 28.12.2018
comment
Я добавил больше деталей в основной пост @IanTurton   -  person IoT user    schedule 08.01.2019


Ответы (2)


Если вы используете GeoTools, вам нужно начать думать с точки зрения Хранилища данных и Коллекции объектов. Существует множество встроенных интеллектуальных функций (большая часть которых использует JTS) для обработки фильтрации. и т. д., что значительно убережет вас от потенциальных проблем.

File inFile = new File("/home/ian/Data/states/states.geojson");
Map<String, Object> params = new HashMap<>();
params.put(GeoJSONDataStoreFactory.URLP.key, URLs.fileToUrl(inFile));
DataStore newDataStore = DataStoreFinder.getDataStore(params);
String pt = "POINT (-107 42)";

FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
SimpleFeatureSource featureSource = newDataStore.getFeatureSource(newDataStore.getTypeNames()[0]);
Filter f = ff.contains(ff.property(featureSource.getSchema().getGeometryDescriptor().getLocalName()),
    ff.literal(pt));
SimpleFeatureCollection collection = featureSource.getFeatures(f);
if (collection.size() > 0) {
  try (SimpleFeatureIterator itr = collection.features()) {
    while (itr.hasNext()) {
      System.out.println(itr.next());
    }
  }
}

Для этого в вашем pom.xml потребуется следующее:

<dependency>
   <groupId>org.geotools</groupId>
   <artifactId>gt-geojsondatastore</artifactId>
   <version>${geotools.version}</version>
</dependency>
<dependency>
   <groupId>org.geotools</groupId>
   <artifactId>gt-shapefile</artifactId>
   <version>${geotools.version}</version>
 </dependency>
person Ian Turton    schedule 08.01.2019
comment
можно ли это сделать, используя InputStream inFile вместо File inFile? Я пробовал, но здесь это не работает: URLs.fileToUrl(inFile) То, как я это сделал, читается из InputStream, создается временный файл и копируется в него, но если я запускаю этот код в AWS, он терпит неудачу, и я думаю, что это связано с созданием файл (т.к. в локальном запускается без проблем) - person IoT user; 14.01.2019
comment
Нет, вам нужен либо настоящий URL-адрес, либо файл, преобразованный в URL-адрес. Может быть, использование java.tempfile может помочь? - person Ian Turton; 14.01.2019
comment
Это то, что мы используем: File tempFile = File.createTempFile("prefix-", ".geojson"); tempFile.deleteOnExit(); и если я запускаю его локально с apache Flink, все работает хорошо. Проблема в том, что когда я запускаю его в Kinesis Data Analytics, ошибки не отображаются, но метод не работает, потому что у меня нет результата. - person IoT user; 14.01.2019
comment
Я думаю, что это, вероятно, станет новым вопросом для экспертов AWS — все, что я могу предложить, это проверить, существует ли файл в коде? - person Ian Turton; 14.01.2019
comment
Привет @IanTurton, не могли бы вы помочь мне с этим вопросом? gis.stackexchange.com/q/330030/146554 - person Felipe; 26.07.2019
comment
GeoJSONDataStoreFactory ‹ — что это? - person Adelin; 26.05.2021
comment
Фабрика по созданию GeoJSONDataStore? - person Ian Turton; 26.05.2021

С помощью класса GeoJsonReader вы можете читать GeoJson Geometry из фрагмента JSON в Geometry:

http://locationtech.github.io/jts/javadoc/org/locationtech/jts/io/geojson/GeoJsonReader.html

Затем проверьте, содержит ли эта геометрия (многоугольник geojson) геометрию аргумента (точку wkt):

http://locationtech.github.io/jts/javadoc/org/locationtech/jts/geom/Geometry.html#contains(org.locationtech.jts.geom.Geometry)

person LuisTavares    schedule 31.12.2018
comment
как мне использовать GeoJSONReader в соответствии с моим кодом, добавленным в основной пост? - person IoT user; 08.01.2019