Expand JTS Geometry over north/south poles

52 Views Asked by At

I'm working on a project where I need to expand an arbitrary geometry by an arbitrary number of meters. I've based the solution off of the answer for Geotools: bounding box for a buffer in wgs84. It's worked well except for geometries which would be expanded over the poles. When I try those sorts of geometries they do not expand right. I believe it's because the geometry is transformed into WGS84.

For example, when I attempt to expand over the north pole. The original geometry

POLYGON ((-119.67774694525636 80.37445153512789, -119.67774694525636 88.85624864362437, -92.01074221005827 88.85624864362437, -92.01074221005827 80.37445153512789, -119.67774694525636 80.37445153512789))

results in

POLYGON ((-119.55257624947963 80.28744411777537, -119.65814347054986 80.28500161369493, -119.76447712889755 80.28613664783931, -119.86739993993893 80.29080449554324, -119.96285816866265 80.29882150830288, -120.04706960992401 80.3098717917805, -120.1166650856837 80.3235187633621, -120.16881949162571 80.3392213016671, -120.20136796158704 80.3563540602452, -120.21290227443447 80.3742313628052, -124.15475233860748 88.85263605573168, -124.14126324286381 88.86963400856264, -123.96241179725793 88.88626922229325, -123.61768091729581 88.90191266863626, -123.11386648703106 88.91594632209528, -122.4658992603797 88.92779235841586, -121.69707374945384 88.9369447058929, -120.83845159310151 88.94300026164407, -90.84999117562393 88.94300044247781, -89.99142129012581 88.93694561607559, -89.22261804630503 88.92779455542474, -88.57463779931913 88.91595022725265, -88.07077605279002 88.9019185390308, -87.72596967454402 88.88627713741018, -87.54702303857012 88.86964386779418, -87.5334268757033 88.85264758335717, -91.47545228015971 80.37421056485957, -91.48701040052279 80.35633253328805, -91.51958070268685 80.3391997037143, -91.57175443294304 80.32349758227612, -91.64136646933562 80.30985134031737, -91.72559172072657 80.29880193070304, -91.8210612719182 80.29078578493424, -91.92399339943785 80.28611867341851, -92.0303350262948 80.28498415631333, -92.13590964833129 80.28742691213384, -119.55257624947963 80.28744411777537))

And with the south pole, I just get an exception when transforming into the AUTO2 CRS.

Here is the exact code I'm using.

    private List<Geometry> expandGeometry(Geometry geometry, CoordinateReferenceSystem originalCrs)
            throws FactoryException, TransformException {

        Point centroid = geometry.getCentroid();
        CoordinateReferenceSystem autoCrs =
                CRS.decode("AUTO2:42001," + centroid.getCoordinate().x + "," + centroid.getCoordinate().y);

        MathTransform toAutoTransform = CRS.findMathTransform(originalCrs, autoCrs);
        MathTransform fromAutoTransform = CRS.findMathTransform(autoCrs, originalCrs);

        Geometry geometryUsingMeters = JTS.transform(geometry, toAutoTransform);
        Geometry bufferedGeometry = geometryUsingMeters.buffer(expansionInMeters);
        bufferedGeometry = JTS.transform(bufferedGeometry, fromAutoTransform);

        Geometry splitGeometry = new JtsGeometry(bufferedGeometry, JtsSpatialContext.GEO, true, false)
                .getGeom();

        return IntStream.range(0, splitGeometry.getNumGeometries())
                .mapToObj(splitGeometry::getGeometryN)
                .collect(Collectors.toList());
    }

The originalCrs is always WGS:84. I'm using JtsGeometry to handle splitting the expanded geometry if it crosses the anti-meridian.

Ideally what I'd like is to split the expanded geometries into multiple equivalent geometries like JtsGeometry does for the anti-meridian. I've spent days Googling this and I haven't found any solution. Is there a library function(s) to handle this? If there isn't a good way to do this, is there a reliable way to detect if the original geometry would cross the poles (or if the expanded geometry has crossed the poles)?

1

There are 1 best solutions below

2
Ian Turton On

Your problem is that you've chosen to use AUTO2:42001 which is a transverse Mercator projection so the nearer the poles you get the worse it will perform until it becomes infinitely wide at the actual pole. I would try with AUTO2:97002 which is stereographic and should handle being near the pole much better.

From the manual:

Supported AUTO codes are:

  • 42001, Universal Transverse Mercator
  • 42002, Transverse Mercator
  • 42003, Orthographic
  • 42004, Equidistant Cylindrical
  • 97001, Gnonomic (GeoTools extension)
  • 97002, Stereographic (GeoTools extension)
  • 97003, Azimuthal Equidistant (GeoTools extension)

Related Questions in SPATIAL4J