如何使用Geotools创建指定参数的楔形几何图形?
用GeoTools生成楔形多边形的解决方案
嘿,刚接触GeoTools确实会有点懵,不过你说的没错——GeoTools完全能搞定这个楔形(WEDGE)的生成,核心就是把楔形转换成多边形的坐标点集合,咱们一步步来:
1. 先理清楚需求参数
从你给的JSON数据里,我们能拿到关键信息:
- 中心点:
(43.87, -103.45)(纬度,经度) - 方位角(AZIMUTH):0.0°(一般指正北方向)
- 张角(ANGLE):120.0°(楔形的开口角度)
- 半径(RADIUS):1000.0米
2. 关键思路:把楔形转成多边形坐标
楔形本质是一个扇形的多边形,需要三个核心点:中心点、扇形的两个端点,再把这三个点按顺序闭合就能生成多边形。不过有个重要前提:经纬度坐标系(WGS84,EPSG:4326)不适合直接计算米级距离,所以我们需要先把坐标转换成投影坐标系(比如UTM,根据中心点找对应的分区),计算完点之后再转回去。
3. 具体代码实现
下面是完整的代码示例,我会加注释说明每一步:
import org.geotools.geometry.jts.JTS; import org.geotools.referencing.CRS; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Polygon; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import org.geotools.geometry.DirectPosition2D; import org.geotools.referencing.GeodeticCalculator; public class WedgeGenerator { public static void main(String[] args) throws FactoryException, TransformException { // 1. 解析输入参数 double centerLat = 43.87; double centerLon = -103.45; double azimuth = 0.0; // 正北方向 double wedgeAngle = 120.0; // 开口角度 double radius = 1000.0; // 半径,单位米 // 2. 定义坐标系:WGS84(经纬度)和对应的UTM投影 CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326"); // 根据中心点计算UTM分区,GeoTools的CRS.lookupIdentifier可以自动匹配 String utmCode = CRS.lookupIdentifier(wgs84, new DirectPosition2D(wgs84, centerLon, centerLat), true); CoordinateReferenceSystem utmCrs = CRS.decode(utmCode); // 3. 转换中心点到UTM坐标系 MathTransform wgsToUtm = CRS.findMathTransform(wgs84, utmCrs); DirectPosition2D centerWgs = new DirectPosition2D(wgs84, centerLon, centerLat); DirectPosition2D centerUtm = new DirectPosition2D(utmCrs); wgsToUtm.transform(centerWgs, centerUtm); // 4. 计算楔形的两个端点(在UTM坐标系下) GeodeticCalculator calculator = new GeodeticCalculator(utmCrs); calculator.setStartingPosition(centerUtm); // 第一个端点:方位角 - 半张角 calculator.setDirection(azimuth - wedgeAngle / 2, radius); DirectPosition2D endPoint1 = calculator.getDestinationPosition(); // 第二个端点:方位角 + 半张角 calculator.setDirection(azimuth + wedgeAngle / 2, radius); DirectPosition2D endPoint2 = calculator.getDestinationPosition(); // 5. 把UTM坐标转回到WGS84 MathTransform utmToWgs = CRS.findMathTransform(utmCrs, wgs84); DirectPosition2D end1Wgs = new DirectPosition2D(wgs84); DirectPosition2D end2Wgs = new DirectPosition2D(wgs84); utmToWgs.transform(endPoint1, end1Wgs); utmToWgs.transform(endPoint2, end2Wgs); // 6. 创建多边形坐标数组(注意顺序:中心点→端点1→端点2→中心点,闭合多边形) Coordinate[] coords = new Coordinate[]{ new Coordinate(centerLon, centerLat), new Coordinate(end1Wgs.getOrdinate(0), end1Wgs.getOrdinate(1)), new Coordinate(end2Wgs.getOrdinate(0), end2Wgs.getOrdinate(1)), new Coordinate(centerLon, centerLat) // 闭合点 }; // 7. 生成JTS多边形 GeometryFactory geometryFactory = new GeometryFactory(); Polygon wedgePolygon = geometryFactory.createPolygon(coords); // 输出结果,你可以验证一下坐标是否正确 System.out.println("生成的楔形多边形WKT:" + wedgePolygon.toText()); } }
4. 关键细节说明
- 坐标系转换:一定要用投影坐标系计算米级距离,否则直接用经纬度算出来的距离会有很大误差(因为经纬度是球面坐标)。
- 方位角的定义:GeoTools的
GeodeticCalculator里的方位角是从正北方向顺时针计算的,和你的输入参数定义一致,如果你的方位角是其他定义(比如正东为0),需要调整角度转换。 - 多边形闭合:JTS的多边形要求坐标数组的第一个点和最后一个点必须重合,否则会报错。
5. 解析shapeString
如果你需要从shapeString里解析参数,可以用简单的字符串分割或者正则表达式,比如:
String shapeString = "WEDGE (-103.45,43.87) AZIMUTH:0.0 ANGLE:120.0 RADIUS:1000.0"; // 用正则匹配参数 Pattern pattern = Pattern.compile("WEDGE \\((-?\\d+\\.\\d+),(-?\\d+\\.\\d+)\\) AZIMUTH:(\\d+\\.\\d+) ANGLE:(\\d+\\.\\d+) RADIUS:(\\d+\\.\\d+)"); Matcher matcher = pattern.matcher(shapeString); if (matcher.find()) { double lon = Double.parseDouble(matcher.group(1)); double lat = Double.parseDouble(matcher.group(2)); double azimuth = Double.parseDouble(matcher.group(3)); double angle = Double.parseDouble(matcher.group(4)); double radius = Double.parseDouble(matcher.group(5)); // 接下来就可以用上面的代码生成多边形了 }
这样应该就能完美生成你需要的楔形多边形啦,要是有哪里卡壳了,随时调整细节就行~
内容的提问来源于stack exchange,提问作者Chris D.




