使用geotools对shape进行多边形范围裁剪

      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();
    }

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值