You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用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.

火山引擎 最新活动