Klaus Native
Klaus Native

Reputation: 3509

Best way to convert JTS Geometry from 3D to 2D

We are importing a Multi-Polygon Shapefile with 3D coordinates into oracle spatial using JTS Geometry Suite, GeoTools (ShapefileDataStore) and Hibernate Spatial. In Oracle Spatial we want them to be stored in 2D.

The onyl (and very slow) approach I found is the following, using WKBWriter and WKBReader:

private static Geometry convert2D(Geometry geometry3D) {
    // create a 2D WKBWriter
    WKBWriter writer = new WKBWriter(2);
    byte[] binary = writer.write(geometry3D);
    WKBReader reader = new WKBReader(factory);
    Geometry geometry2D= null;
    try {
        geometry2D= reader.read(binary);
    } catch (ParseException e) {
        log.error("error reading wkb", e);
    }
    return geometry2D;
}

Does anybody know a more efficient way to convert a geometry from 3D to 2D?

Upvotes: 1

Views: 2542

Answers (2)

Lars
Lars

Reputation: 2485

I did not test the WKBWriter and WKBReader but here is another simple approach:

  • Create a copy of your geometry
  • Set all coordinates to 2D

Simple code:

private static Geometry convert2D(Geometry g3D){
    // copy geometry
    Geometry g2D = (Geometry) g3D.clone();
    // set new 2D coordinates
    for(Coordinate c : g2D.getCoordinates()){
        c.setCoordinate(new Coordinate(c.x, c.y));
    }
    return g2D;
}

Upvotes: 1

jmvivo
jmvivo

Reputation: 2663

I found a way:

  1. Create a new CoordinateArraySequence which forces to use 2D Coordinate instances
  2. Create a new CoordinateArraySequenceFactory which generates the new custom CoodinateArraySequence
  3. Create a new instance of GeometryFactory which uses the new CoordinateFactory and use it to recreate the geometry:

    private static Geometry convert2D(Geometry geometry3D) {
        GeometryFactory geoFactory = new GeometryFactory(
            geometry3d.getPrecisionModel(), geometry3d.getSRID(), CoordinateArraySequence2DFactory.instance());
        if (geometry3D instanceOf Point) {
           return geoFactory.createPoint(geometry3D.getCoordinateSequence());
        } else if (geometry3D instanceOf Point) {
        //...  
        //...
        //...
        throw new IllegalArgumentException("Unsupported geometry type: ".concat(geometry3d.getClass().getName());
    }
    

Good luck!!

Upvotes: 1

Related Questions