在Geotools中构建Shapefile出现问题

3
我有一个项目,我想加载给定的shapefile文件,挑选出大于某个特定大小的多边形,然后将结果写入一个新的shapefile文件。虽然可能不是最有效的方法,但我已经编写了成功完成所有这些功能的代码,直到应该编写shapefile文件的那一步。我没有收到任何错误,但是生成的shapefile文件中没有可用的数据。我已经按照尽可能多的教程进行了操作,但是仍然无法解决问题。
第一部分代码是读取shapefile文件,挑选我想要的多边形,并将它们放入要素集合中。据我所知,这部分代码似乎可以正常工作。
public class ShapefileTest {

    public static void main(String[] args) throws MalformedURLException, IOException, FactoryException, MismatchedDimensionException, TransformException, SchemaException {

        File oldShp = new File("Old.shp"); 
        File newShp = new File("New.shp"); 

        //Get data from the original ShapeFile
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("url", oldShp.toURI().toURL());
        //Connect to the dataStore
        DataStore dataStore = DataStoreFinder.getDataStore(map);
        //Get the typeName from the dataStore
        String typeName = dataStore.getTypeNames()[0];

        //Get the FeatureSource from the dataStore
        FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);

        SimpleFeatureCollection collection = (SimpleFeatureCollection) source.getFeatures(); //Get all of the features - no filter        

        //Start creating the new Shapefile
        final SimpleFeatureType TYPE = createFeatureType(); //Calls a method that builds the feature type - tested and works.
        DefaultFeatureCollection newCollection = new DefaultFeatureCollection();  //To hold my new collection

        try (FeatureIterator<SimpleFeature> features = collection.features()) {
            while (features.hasNext()) {
                SimpleFeature feature = features.next();  //Get next feature
                SimpleFeatureBuilder fb = new SimpleFeatureBuilder(TYPE);  //Create a new SimpleFeature based on the original
                Integer level = (Integer) feature.getAttribute(1); //Get the level for this feature
                MultiPolygon multiPoly = (MultiPolygon) feature.getDefaultGeometry(); //Get the  geometry collection

                //First count how many new polygons we will have
                int numNewPoly = 0;
                for (int i = 0; i < multiPoly.getNumGeometries(); i++) {
                    double area = getArea(multiPoly.getGeometryN(i));
                    if (area > 20200) {
                        numNewPoly++;
                    }
                }

                //Now build an array of the larger polygons
                Polygon[] polys = new Polygon[numNewPoly];  //Array of new geometies

                int iPoly = 0;
                for (int i = 0; i < multiPoly.getNumGeometries(); i++) {
                    double area = getArea(multiPoly.getGeometryN(i));
                    if (area > 20200) {  //Write the new data
                        polys[iPoly] = (Polygon) multiPoly.getGeometryN(i);
                        iPoly++;
                    }
                }

                GeometryFactory gf = new GeometryFactory();     //Create a geometry factory           
                MultiPolygon mp = new MultiPolygon(polys, gf);  //Create the MultiPolygonyy
                fb.add(mp); //Add the geometry collection to the feature builder
                fb.add(level);
                fb.add("dBA");

                SimpleFeature newFeature = SimpleFeatureBuilder.build( TYPE, new Object[]{mp, level,"dBA"}, null );
                newCollection.add(newFeature); //Add it to the collection
            }

目前,我有一个看起来正确的集合-它具有正确的边界和一切。下一步的代码就是将其放入新的Shapefile中。

            //Time to put together the new Shapefile                
            Map<String, Serializable> newMap = new HashMap<String, Serializable>();
            newMap.put("url", newShp.toURI().toURL());
            newMap.put("create spatial index", Boolean.TRUE);

            DataStore newDataStore = DataStoreFinder.getDataStore(newMap);
            newDataStore.createSchema(TYPE);
            String newTypeName = newDataStore.getTypeNames()[0];

            SimpleFeatureStore fs = (SimpleFeatureStore) newDataStore.getFeatureSource(newTypeName);            

            Transaction t = new DefaultTransaction("add");    

            fs.setTransaction(t);
            fs.addFeatures(newCollection);

            t.commit();
            ReferencedEnvelope env = fs.getBounds();

        }

    }

我添加了最后一段代码来检查FeatureStore fs的边界,结果返回null。很明显,加载了新创建的shapefile(确实已经创建并且大小约为正确),但是没有显示任何内容。

2个回答

3
实际上,解决方案与我发布的代码无关,而与我的FeatureType定义有关。我没有将"the_geom"包含在我的多边形要素类型中,因此没有任何内容被写入文件。

2
我相信你可能遗漏了完成/关闭文件的步骤。在t.commit代码行之后尝试添加这一步。
fs.close();

作为一种方便的替代方案,您可以尝试使用 Shapefile 数据存储文档中提到的 Shapefile 转储工具。使用该工具可能会将您的第二个代码块简化为两到三行。docs

这并没有解决特征边界为空的问题。特征本身没有被正确创建。关闭事务也没有解决这个问题。我会更详细地研究Shapefile DataStore,谢谢! - Bruce Ikelheimer
我已经尝试了更简单的代码,只是创建了一个带洞的MultiPolygon,但仍然遇到了同样的问题...显然我在创建要素时漏掉了某些东西... - Bruce Ikelheimer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接