geotools对矢量裁剪功能支持是在org.geotools.gt-shapefile 25.0版本以上的功能。使用此功能首先在Java项目(本案例环境为 springboot)的pom文件中引入相关依赖。
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>
<!--geotools.version 为25.0以上 -->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
接下来 就是在项目中使用,下面是使用该功能点的测试demo。代码示例中都有注释体现基本的逻辑。
public static void main(String[] args) {
File file = new File("/Users/tingting/Desktop/DN10501444/road_result_ls.shp");
SimpleFeatureCollection featureCollection = null;
try {
// 读取源文件shape
ShapefileDataStore dataStore = new ShapefileDataStore(file.toURI().toURL());
dataStore.setCharset(StandardCharsets.UTF_8);
System.out.println(dataStore.getCharset() + "获取编码11111111111111111");
SimpleFeatureSource featureSource = dataStore.getFeatureSource();
featureCollection = featureSource.getFeatures();
// 自定义的裁剪范围
GeometryFactory geometryFactory = new GeometryFactory();
Coordinate[] coordinates = {
new Coordinate(119.8535158272736, 36.0208825916344),
new Coordinate(119.909758272736, 36.091077415795),
new Coordinate(119.97536774812598, 36.1120377415795),
new Coordinate(120.03026774812598, 36.0559377415795),
new Coordinate(120.01796774812598, 36.023648259164),
new Coordinate(119.8535158272736, 36.0208825916344),
};
Polygon polygon = geometryFactory.createPolygon(coordinates);
polygon.setSRID(4326);
// 调用 geotools 的裁剪要素方法
ClippedFeatureCollection collection = new ClippedFeatureCollection(featureCollection, polygon, true);
ClippedFeatureIterator iterator = (ClippedFeatureIterator) collection.features();
//根据图层名称来获取要素的source
SimpleFeatureSource fs = dataStore.getFeatureSource(dataStore.getTypeNames()[0]);
//根据参数创建shape存储空间
// Map<String, Serializable> params = new HashMap<String, Serializable>();
String strPath = "/Users/tingting/Desktop/dsc/cdcfdfs/cdj.shp";
File s1 = new File(strPath);
File fileParent = s1.getParentFile();
if (!fileParent.exists()) {
fileParent.mkdirs();
}
file.createNewFile();
ShapefileDataStore ds = new ShapefileDataStore(s1.toURI().toURL());
// ds.setCharset(StandardCharsets.UTF_8);
ds.setCharset(Charset.forName("GBK"));
System.out.println(ds.getCharset() + "获取编码22222222");
SimpleFeatureType sft = fs.getSchema();
//创建
ds.createSchema(sft);
//设置Writer,并设置为自动提交
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
//循环写入要素
while (iterator.hasNext()) {
//获取要写入的要素
SimpleFeature feature = iterator.next();
//将要写入位置
SimpleFeature featureBuf = writer.next();
//设置写入要素所有属性
featureBuf.setAttributes(feature.getAttributes());
//获取the_geom属性的值
Geometry geo = (Geometry) feature.getAttribute("the_geom");
// //重新覆盖the_geom属性的值,这里的geoBuffer必须为Geometry类型
featureBuf.setAttribute("the_geom", geo);
}
//将所有数据写入
writer.write();
//关闭写入流
writer.close();
iterator.close();
} catch (Exception e) {
e.printStackTrace();
}
}
以上代码执行可输出,自定义范围内的shape文件夹,结果可通过QGIS等第三方软件验证。
以下为源码部分
// 核心裁剪矢量要素的方法
/** When clipping lines and polygons can turn into multilines and multipolygons */
private SimpleFeatureType buildTargetSchema(SimpleFeatureType schema) {
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
for (AttributeDescriptor ad : schema.getAttributeDescriptors()) {
if (ad instanceof GeometryDescriptor) {
GeometryDescriptor gd = (GeometryDescriptor) ad;
Class<?> binding = ad.getType().getBinding();
if (Point.class.isAssignableFrom(binding)
|| GeometryCollection.class.isAssignableFrom(binding)) {
tb.add(ad);
} else {
Class target;
if (LineString.class.isAssignableFrom(binding)) {
target = MultiLineString.class;
} else if (Polygon.class.isAssignableFrom(binding)) {
target = MultiPolygon.class;
} else {
throw new RuntimeException(
"Don't know how to handle geometries of type "
+ binding.getCanonicalName());
}
tb.minOccurs(ad.getMinOccurs());
tb.maxOccurs(ad.getMaxOccurs());
tb.nillable(ad.isNillable());
tb.add(ad.getLocalName(), target, gd.getCoordinateReferenceSystem());
}
} else {
tb.add(ad);
}
}
tb.setName(schema.getName());
return tb.buildFeatureType();
}