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)?
Your problem is that you've chosen to use
AUTO2:42001which 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 withAUTO2:97002which is stereographic and should handle being near the pole much better.From the manual: