Проблемы со сборкой шейп-файла в Geotools

У меня есть проект, в котором я хочу загрузить данный шейп-файл и выбрать полигоны выше определенного размера, прежде чем записывать результаты в новый шейп-файл. Возможно, не самый эффективный, но у меня есть код, который успешно выполняет все это, вплоть до того момента, когда он должен написать шейп-файл. Я не получаю ошибок, но полученный шейп-файл не содержит полезных данных. Я следовал как можно большему количеству руководств, но все равно ничего не понимаю.

Первый фрагмент кода — это то место, где я читаю шейп-файл, выбираю нужные полигоны и помещаю их в набор функций. Насколько я могу судить, эта часть работает нормально.

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
            }

На данный момент у меня есть коллекция, которая выглядит правильно — у нее правильные границы и все такое. Следующий бит кода — это место, где я помещаю его в новый шейп-файл.

            //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, и он возвращается нулевым. Очевидно, что при загрузке вновь созданного шейп-файла (который ДЕЙСТВИТЕЛЬНО создается и имеет правильный размер), ничего не появляется.


person Bruce Ikelheimer    schedule 23.05.2016    source источник


Ответы (2)


Решение на самом деле не имело ничего общего с кодом, который я опубликовал, — оно имело прямое отношение к моему определению FeatureType. Я не включил «the_geom» в свой полигональный тип объектов, поэтому в файл ничего не записывалось.

person Bruce Ikelheimer    schedule 25.05.2016

Я считаю, что вы пропустили шаг, чтобы завершить/закрыть файл. Попробуйте добавить это после строки t.commit.

fs.close();

В качестве подходящей альтернативы вы можете попробовать утилиту создания дампа шейп-файлов, упомянутую в хранилищах данных шейп-файлов документы. Это может упростить ваш второй блок кода до двух или трех строк.

person GeoMesaJim    schedule 24.05.2016
comment
Это не исправляет тот факт, что границы функции равны нулю. Сама функция не создана должным образом. Закрытие транзакции не решило эту проблему. И я рассмотрю хранилище данных Shapefile более подробно, спасибо! - person Bruce Ikelheimer; 25.05.2016
comment
Я пробовал даже более простой код, который просто создает MultiPolygon с отверстием, и получаю ту же проблему... Я явно что-то упустил в том, как создать функцию... - person Bruce Ikelheimer; 25.05.2016