将 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平方千米(以度为单位)
);