JTS конвертировать один полигон в мультиполигон - PullRequest
0 голосов
/ 01 марта 2019

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

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

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

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

В JTSГеометрия 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>

Я работаю со следующими примерами данных и вспомогательной функцией:

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

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

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Как 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);
0 голосов
/ 01 марта 2019

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

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