简要说明
在java,利用gdal,将裁剪范围的shpfile 对 目标shpfile 进行裁剪;前置条件是两个shpfile处于一个坐标系下,不然裁剪结果可能为空。
maven依赖
<!--需要安装完gdal后,本地install gdal包才能使用 -->
<!--gdal安装可参考 https://blog.csdn.net/qq_41613913/article/details/135743562 -->
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>3.7.3</version>
</dependency>
样例代码
public static void main(String[] args) {
//临时的裁剪结果目录
String clippingParentDirFileStr = "D:/tmp/clipping" + File.separator ;
//将裁剪范围shp文件
String clipfilePath = "D:/data/clipping.shp";
//读取shp文件
DataSource clipShpDs = ogr.Open(clipfilePath, 0);
//单图层过滤
Layer shpFilterLayer = clipShpDs.GetLayer(0);
org.gdal.ogr.Driver shpDriver = ogr.GetDriverByName("ESRI Shapefile");
if (shpDriver == null) {
System.out.println("shpfile 驱动不可用");
return;
}
String originalFilePath = "D:/data/xxx.shp";
DataSource originalDataSource = shpDriver.Open(originalFileStr, 0);
String originalName = cn.hutool.core.io.FileUtil.getName(originalFileStr);
String layerName = originalName.replace(".shp", "");
Layer originalLayer = originalDataSource.GetLayer(layerName);
//判断裁剪文件的坐标系和源数据坐标系是否一致
SpatialReference shpFilterSpatialReference = shpFilterLayer.GetSpatialRef();
String shpFilterSrid = shpFilterSpatialReference.GetAttrValue("AUTHORITY", 1);
String originalSrid = originalLayer.GetSpatialRef().GetAttrValue("AUTHORITY", 1);
if(!shpFilterSrid.equals(originalSrid)) {
System.out.println("两个shp的坐标系不一样")
return;
}
String outputfilePath = clippingParentDirFileStr + "output.shp";
File existFile = new File(outputfilePath);
if (!existFile.getParentFile().exists()) {
existFile.getParentFile().mkdirs();
}
DataSource dataSourceOut = shpDriver.CreateDataSource(outputfilePath);
//设置坐标系
SpatialReference sr = new SpatialReference();
sr.ImportFromEPSG(Integer.valueOf(originalSrid));
Layer layerOut = dataSourceOut.CreateLayer(outLayerName, sr);
//设置字段
FeatureDefn originalfeatureDefn = originalLayer.GetLayerDefn();
int fieldCount = originalfeatureDefn.GetFieldCount();
for (int i = 0; i < fieldCount; i++) {
FieldDefn defn = originalfeatureDefn.GetFieldDefn(i);
layerOut.CreateField(defn);
}
//遍历图层每个几何
long featureCount = originalLayer.GetFeatureCount();
long filterFeatureCount = shpFilterLayer.GetFeatureCount();
Feature feature1 = null;
Feature feature2 = null;
for (int i = 0; i < filterFeatureCount ;i++) {
feature1 = shpFilterLayer.GetFeature(i);
Geometry geometry1 = feature1.GetGeometryRef();
for (int j = 0 ; j < featureCount ;j++) {
feature2 = originalLayer.GetFeature(j);
Geometry geometry2 = feature2.GetGeometryRef();
if (geometry1.Intersect(geometry2)) {
Geometry intersection = geometry1.Intersection(geometry2);
feature2.SetGeometry(intersection);
layerOut.CreateFeature(feature2);
}
}
}
originalLayer.delete();
shpFilterLayer.delete();
layerOut.delete();
shpDriver.delete();
dataSourceOut.delete();
}