有两种解决方案:
将半径从米转换为度数,将问题视为平面问题。
将纬度/经度点转换为米,在本地平面投影中计算圆圈,然后重新投影回纬度/经度。
对于第一种方法,你可以做类似这样的事情,适用于赤道附近小半径的情况:
GeodeticCalculator calc = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
calc.setStartingGeographicPoint(point.getX(), point.getY());
calc.setDirection(0.0, 10000);
Point2D p2 = calc.getDestinationGeographicPoint();
calc.setDirection(90.0, 10000);
Point2D p3 = calc.getDestinationGeographicPoint();
double dy = p2.getY() - point.getY();
double dx = p3.getX() - point.getX();
double distance = (dy + dx) / 2.0;
Polygon p1 = (Polygon) point.buffer(distance);
因为第二种方法更通用(即它的适用范围更广,效果也更好),所以我将展示一些代码。
首先,您需要找到一个本地投影,GeoTools提供了一个“伪”投影AUTO42001,x,y
,它是以X,Y为中心的UTM投影:
public SimpleFeature bufferFeature(SimpleFeature feature, Measure<Double, Length> distance) {
GeometryAttribute gProp = feature.getDefaultGeometryProperty();
CoordinateReferenceSystem origCRS = gProp.getDescriptor().getCoordinateReferenceSystem();
Geometry geom = (Geometry) feature.getDefaultGeometry();
Geometry pGeom = geom;
MathTransform toTransform, fromTransform = null;
if (!(origCRS instanceof ProjectedCRS)) {
double x = geom.getCoordinate().x;
double y = geom.getCoordinate().y;
String code = "AUTO:42001," + x + "," + y;
CoordinateReferenceSystem auto;
try {
auto = CRS.decode(code);
toTransform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
fromTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
pGeom = JTS.transform(geom, toTransform);
} catch (MismatchedDimensionException | TransformException | FactoryException e) {
e.printStackTrace();
}
}
所以现在pGeom
是我们的点,单位为米。对它进行缓冲现在很容易。
Translated content:
因此,现在pGeom
是以米为单位的点。 对其进行缓冲现在很容易。
Geometry out = bufferFeature(pGeom, distance.doubleValue(SI.METER))
然后,使用之前查找的反向变换将其投影回WGS84(纬度/经度):
then we project back to WGS84 (lat/lon) using the reverse transform we looked up earlier:
retGeom = JTS.transform(out, fromTransform)
然后需要进行一些调整,以更改要返回的特征类型以反映我们返回的是多边形而不是点。完整代码在此代码片段中。
运行代码后,将得到以下输出:
POINT (10.840378413128576 3.4152050343701745)
POLYGON ((10.84937634426605 3.4151876838951822, 10.849200076653755 3.413423962919184, 10.84868480171117 3.4117286878605766, 10.847850322146979 3.4101670058279794, 10.846728706726902 3.4087989300555464, 10.845363057862208 3.407677033830687, 10.843805855306746 3.406844430298736, 10.84211693959797 3.406333115754347, 10.840361212705258 3.4061627400701946, 10.838606144204721 3.4063398515107184, 10.836919178768184 3.4068576449605277, 10.835365144548726 3.4076962232621035, 10.834003762019957 3.408823361646906, 10.832887348980522 3.410195745914279, 10.832058809914859 3.411760636805914, 10.831549986992338 3.4134578966399034, 10.831380436105858 3.4152223003379722, 10.831556675029052 3.416986042039048, 10.832071932633442 3.4186813409639054, 10.832906408849936 3.4202430463705085, 10.834028035422469 3.4216111414662183, 10.835393708241908 3.422733050021835, 10.836950943907517 3.4235656570147763, 10.838639896841123 3.424076965623486, 10.840395659406198 3.4242473268789406, 10.842150756595839 3.4240701947133396, 10.843837739370569 3.4235523773972796, 10.845391776937724 3.4227137757216988, 10.846753148314034 3.4215866180136185, 10.847869537398722 3.4202142214154887, 10.848698043354238 3.4186493270628633, 10.849206829051935 3.4169520731645546, 10.84937634426605 3.4151876838951822))
geom
之前的部分。 - Ian Turton