【问题标题】:Trouble building Shapefile in Geotools在 Geotools 中构建 Shapefile 时遇到问题
【发布时间】:2016-05-23 18:27:37
【问题描述】:

我有一个项目,我想在给定的 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(确实已创建并且大小合适),没有任何显示。

【问题讨论】:

    标签: java shapefile geotools


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我相信您缺少完成/关闭文件的步骤。尝试在 t.commit 行之后添加它。

      fs.close();
      

      作为一种权宜之计,您可以尝试在 Shapefile DataStores docs 中提到的 Shapefile dumper 实用程序。使用它可以将您的第二个代码块简化为两行或三行。

      【讨论】:

      • 这并不能解决特征边界为空的事实。功能本身未正确创建。关闭交易并没有解决这个问题。我会更详细地研究 Shapefile DataStore,谢谢!
      • 我已经尝试过更简单的代码,它只是制作一个带有孔的 MultiPolygon,但遇到了同样的问题......我显然在如何创建该特征方面遗漏了一些东西......
      猜你喜欢
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 2014-06-12
      相关资源
      最近更新 更多