jts конвертирует один полигон в мультиполигон

Всем привет, я использую JTS 1.15 со снимком 21 геоинструментов:

Я написал метод с коллекцией полигонов в качестве входного параметра, а выходным методом является геометрия MultiPolygon. Это работает нормально без одного исключения: у меня также есть флаг объединения, который будет объединять мои полигоны, если они перекрываются или соприкасаются. Если теперь все полигоны перекрываются, будет возвращен только один полигон. Но тогда будет ClassCastException.

Один полигон не может быть преобразован в MultiPolygon.

Есть ли простой способ превратить один полигон в MultiPolygon? Я не смог найти геометрическую диаграмму jts uml, но, как я узнал, Polygons расширяет класс Geometry с помощью интерфейса Polygonal Multipolygon extends GeometryCollection, который расширяет Geometry и также имеет интерфейс Polygonal.

В JTS Geometry Jacadoc упоминается следующее: : Методы наложения

Методы наложения возвращают наиболее конкретный класс, возможный для представления результата. Если результат однородный, будут возвращены Point, LineString или Polygon, если результат содержит один элемент; в противном случае будет возвращено значение MultiPoint, MultiLineString или MultiPolygon. Если результат неоднороден, будет возвращен GeometryCollection.

Я написал простой метод манипулятора строк, чтобы изменить мою строку wkt, но есть ли другой способ достичь цели?

вот мой метод

public static MultiPolygon createSPMultiPolygon(Collection<Polygon> polygons, boolean dissolveResult) {


    // if emty collection is returned
    if (polygons.size() == 0){
        //emty collection returns emty MultiPolygon

        GeometryFactory geomFactory = new GeometryFactory();
        MultiPolygon fail = geomFactory.createMultiPolygon();

        return fail;
    }

    //it will be assumed that all polygons have the same epsg code

    int epsgCode = polygons.iterator().next().getSRID();
    prec = new PrecisionModel(1000000)
    //creates the factory object
    GeometryFactory geomFactory = new GeometryFactory(prec, epsgCode);

    MultiPolygon result = null;


    // main task

    result = (MultiPolygon) geomFactory.buildGeometry(polygons);


        //mergedOptions
        if (dissolveResult) {

            try {
                result = (MultiPolygon) result.union();
                // there will be an exception if result or merge is a single polygon that polygon cant be cast to Multipolygon
            } catch (ClassCastException e) {

                // DO SOMETHING ELSE
            }

        }

    }

Я использую следующие пакеты maven:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <geotools.version>21-SNAPSHOT</geotools.version>
</properties>
<dependencies>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-geometry</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-epsg-hsql</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-epsg-wkt </artifactId>
  <version>${geotools.version}</version>
</dependency>

I am working with following example data and helper function:

    String touches1_wkt = "POLYGON ((7.896407750956972 49.73405361813658, 8.14886306623246 49.73405361813658, 8.14886306623246 49.73405361813658, 8.14886306623246 49.46768344296402, 7.902371262341433 49.46569560583586, 7.896407750956972 49.73405361813658))";
    String touches2_wkt = "POLYGON ((8.14886306623246 49.61478339044737, 8.39137919586718 49.616771227575526, 8.39137919586718 49.616771227575526, 8.399330544379795 49.35835240091558, 8.14886306623246 49.35835240091558, 8.14886306623246 49.46768344296402, 8.14886306623246 49.61478339044737))";


    Polygon touch1 = (Polygon) createSPGeom(touches1_wkt, 4326);
    Polygon touch2 = (Polygon) createSPGeom(touches2_wkt, 4326);

    Collection<Polygon> polyCollection = new ArrayList<>();
    polyCollection.add(touch1);
    polyCollection.add(touch2);

    MultiPolygon multi = createSPMultiPolygon(polyCollection, true);

со следующим вспомогательным методом для чтения wkt:

     public static Geometry createSPGeom(String wktString, Integer epsgCode){

    Geometry returnedGeom =null;
    prec = new PrecisionModel(1000000);

    GeometryFactory geomFactory = new GeometryFactory(prec, epsgCode);
    WKTReader wktReader = new WKTReader(geomFactory);

    try {
        returnedGeom = wktReader.read(wktString);
    } catch (ParseException e) {
        // if wktString is invalid, an emty point geometry is used
        returnedGeom = geomFactory.createPoint();
    }

    return returnedGeom;
}

Спасибо за любую помощь заранее


person F.M.    schedule 01.03.2019    source источник


Ответы (2)


Как говорит GeoMesaJim, это простая проблема, просто превратите многоугольник в мультиполигон.

GeometryFactory gf = new GeometryFactory();
MultiPolygon mPoly;
if (p instanceOf Polygon){
  Polygon[] polys = new Polygon[1];
  polys[0] = p;
  mPoly = gf.createMultiPolygon(polys);
} else {
   mPoly = p;
}
System.out.println(mPoly);
person Ian Turton    schedule 04.03.2019

Похоже, что ваше ClassCastException можно обработать, проверив, возвращает ли вызов union() Polygon. Если это так, вы можете вызвать метод createMultiPolygon от GeometryFactory с массивом, содержащим только этот полигон.[1]

  1. https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/geom/GeometryFactory.java#L326
person GeoMesaJim    schedule 01.03.2019