使用GDAL将geojson传入的面转成点阵数据 ,并且处理多个面取最大的经纬度四个点闭合,同时将参数化 将 GeoJSON 中的 Polygon / MultiPolygon 转为点阵;

将 GeoJSON 中的 Polygon / MultiPolygon 转为点阵;

支持参数控制:

点之间的距离(单位:度);

每个面允许的最大点数;

每个面允许的最大面积;

输出结构清晰,包含每个面的信息及生成的点。

java

import org.gdal.ogr.;
import java.util.
;

public class GeoJsonGridGenerator {

static {
    ogr.RegisterAll();
}

/**
 * 生成点阵数据
 *
 * @param filePath           GeoJSON 文件路径
 * @param pointSpacingDeg    点之间的间隔(单位:度,约 0.009 ~ 1km)
 * @param maxPointsPerGeom   每个面最大点数限制
 * @param maxAreaPerGeom     每个面最大面积限制(单位:平方度,约等于平方千米)
 * @return Map<String, Object> 结果数据结构
 */
public static Map<String, Object> generatePointGridsFromGeoJson(
        String filePath,
        double pointSpacingDeg,
        int maxPointsPerGeom,
        double maxAreaPerGeom
) {
    Map<String, Object> response = new HashMap<>();
    List<Map<String, Object>> featurePointsList = new ArrayList<>();

    DataSource ds = ogr.Open(filePath, 0);
    if (ds == null) {
        response.put("error", "文件不存在或无法打开");
        return response;
    }

    Layer srcLayer = ds.GetLayer(0);
    Feature srcFeature;
    int featureIndex = 0;

    while ((srcFeature = srcLayer.GetNextFeature()) != null) {
        Geometry geom = srcFeature.GetGeometryRef();
        if (geom == null) continue;

        int geomType = ogr.GT_Flatten(geom.GetGeometryType());
        if (geomType != ogr.wkbPolygon && geomType != ogr.wkbMultiPolygon) {
            continue;
        }

        double area = geom.GetArea();
        if (area > maxAreaPerGeom) {
            System.out.println("跳过面积过大的面: " + area);
            continue;
        }

        List<double[]> gridPoints = generatePointsInGeometry(geom, pointSpacingDeg, maxPointsPerGeom);
        if (gridPoints == null) continue;

        Map<String, Object> featureResult = new HashMap<>();
        featureResult.put("featureIndex", featureIndex++);
        featureResult.put("pointCount", gridPoints.size());
        featureResult.put("area", area);
        featureResult.put("points", gridPoints);

        featurePointsList.add(featureResult);
    }

    response.put("features", featurePointsList);
    return response;
}

/**
 * 在几何体内部生成点阵
 */
private static List<double[]> generatePointsInGeometry(Geometry geom, double spacing, int maxPoints) {
    List<double[]> points = new ArrayList<>();

    double[] envelope = new double[4]; // minX, maxX, minY, maxY
    geom.GetEnvelope(envelope);
    double minX = envelope[0];
    double maxX = envelope[1];
    double minY = envelope[2];
    double maxY = envelope[3];

    for (double x = minX; x <= maxX; x += spacing) {
        for (double y = minY; y <= maxY; y += spacing) {
            Geometry pt = ogr.CreateGeometryFromWkt(String.format("POINT(%f %f)", x, y));
            if (geom.Contains(pt)) {
                points.add(new double[]{x, y});
                if (points.size() >= maxPoints) {
                    pt.delete();
                    return points;
                }
            }
            pt.delete();
        }
    }

    return points;
}

// 可选:用于打开 Layer
public static Layer openLayer(String filePath) {
    DataSource ds = ogr.Open(filePath, 0);
    if (ds == null) return null;
    return ds.GetLayer(0);
}

}
使用方式:
java

Map<String, Object> result = GeoJsonGridGenerator.generatePointGridsFromGeoJson(
    "path/to/your.geojson",
    0.009,     // 点间距 (约1km)
    10000,     // 每个面最多10000个点
    10.0       // 每个面最多约10平方千米(以度为单位)
);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值