Добавьте новый атрибут столбца в шейп-файл и сохраните его в базе данных с помощью Geotools Java.

Я преобразовываю шейп-файл, добавляя новые атрибуты столбца. Поскольку эта задача выполняется с помощью Java, единственный известный мне вариант — использовать Geotools. У меня 2 основных опасения:

<сильный>1. Я не могу понять, как добавить новую переменную столбца. Является ли ответ feature.setAttribute("col","value")?

Я вижу из этого поста только пример: https://gis.stackexchange.com/questions/215660/modifying-feature-attributes-of-a-shapefile-in-geotools, но я не понимаю решения.

   //Upload the ShapeFile
    File file = JFileDataStoreChooser.showOpenFile("shp", null);
    Map<String, Object> params = new HashMap<>();
    params.put("url", file.toURI().toURL());

    DataStore store = DataStoreFinder.getDataStore(params);
    SimpleFeatureSource featureSource = store.getFeatureSource(store.getTypeNames()[0]);
    String typeName = store.getTypeNames()[0];


     FeatureSource<SimpleFeatureType, SimpleFeature> source =
            store.getFeatureSource(typeName);
        Filter filter = Filter.INCLUDE;

    FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures(filter);
    try (FeatureIterator<SimpleFeature> features = collection.features()) {
        while (features.hasNext()) {
            SimpleFeature feature = features.next();

            //adding new columns

            feature.setAttribute("ShapeID", "SHP1213");
            feature.setAttribute("UserName", "John");

            System.out.print(feature.getID());
            System.out.print(":");
            System.out.println(feature.getDefaultGeometryProperty().getValue());
        }
    }

/*
 * Write the features to the shapefile
 */
Transaction transaction = new DefaultTransaction("create");


// featureSource.addFeatureListener(fl);

if (featureSource instanceof SimpleFeatureStore) {
    SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;

    featureStore.setTransaction(transaction);
    try {
        featureStore.addFeatures(collection);
        transaction.commit();

    } catch (Exception problem) {
        problem.printStackTrace();
        transaction.rollback();

    } finally {
        transaction.close();
    }
    System.exit(0); // success!
} else {
    System.out.println(typeName + " does not support read/write access");
    System.exit(1);
}

Предполагая, что setattribute добавляет, я получаю следующую ошибку для приведенного выше кода.

Exception in thread "main" org.geotools.feature.IllegalAttributeException:Unknown attribute ShapeID:null value:null
    at org.geotools.feature.simple.SimpleFeatureImpl.setAttribute(SimpleFeatureImpl.java:238)
    at org.geotools.Testing.WritetoDatabase.main(WritetoDatabase.java:73)

<сильный>2. После изменения этих изменений я хочу сохранить их в базе данных (PostGIS). Я понял, что приведенный ниже фрагмент выполняет задачу, но, похоже, не работает для меня только с вставкой файла формы

  Properties params = new Properties();
    params.put("user", "postgres");
    params.put("passwd", "postgres");
    params.put("port", "5432");
    params.put("host", "127.0.0.1");
    params.put("database", "test");
    params.put("dbtype", "postgis");

  dataStore = DataStoreFinder.getDataStore(params);

В приведенном выше случае ошибка представляет собой исключение NullPointerException.


person GeoFresher    schedule 28.09.2018    source источник


Ответы (1)


В GeoTools (Simple)FeatureType неизменяем (неизменяем), поэтому вы не можете просто добавить новый атрибут в шейп-файл. Итак, сначала вы должны создать новый FeatureType с включенным вашим новым атрибутом.

FileDataStore ds = FileDataStoreFinder.getDataStore(new File("/home/ian/Data/states/states.shp"));
SimpleFeatureType schema = ds.getSchema();
// create new schema
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(schema.getName());
builder.setSuperType((SimpleFeatureType) schema.getSuper());
builder.addAll(schema.getAttributeDescriptors());
// add new attribute(s)
builder.add("shapeID", String.class);
// build new schema
SimpleFeatureType nSchema = builder.buildFeatureType();

Затем вам нужно преобразовать все существующие функции в новую схему и добавить новый атрибут.

// loop through features adding new attribute
List<SimpleFeature> features = new ArrayList<>();
try (SimpleFeatureIterator itr = ds.getFeatureSource().getFeatures().features()) {
  while (itr.hasNext()) {
    SimpleFeature f = itr.next();
    SimpleFeature f2 = DataUtilities.reType(nSchema, f);
    f2.setAttribute("shapeID", "newAttrValue");
    //System.out.println(f2);
    features.add(f2);
  }
}

Наконец, откройте хранилище данных Postgis и запишите в него новые функции.

Properties params = new Properties();
params.put("user", "postgres");
params.put("passwd", "postgres");
params.put("port", "5432");
params.put("host", "127.0.0.1");
params.put("database", "test");
params.put("dbtype", "postgis");

DataStore dataStore = DataStoreFinder.getDataStore(params);
SimpleFeatureSource source = dataStore.getFeatureSource("tablename");
if (source instanceof SimpleFeatureStore) {
  SimpleFeatureStore store = (SimpleFeatureStore) source;
  store.addFeatures(DataUtilities.collection(features));
} else {
  System.err.println("Unable to write to database");
}
person Ian Turton    schedule 29.09.2018
comment
Это отвечает на все проблемы, с которыми я сталкивался... Недурно Ян :) - person GeoFresher; 30.09.2018
comment
имя таблицы: создает новую таблицу, верно? согласно этой документации кажется, что docs.geotools.org/latest /javadocs/org/geotools/data/, однако я получаю java.lang.NullPointerException в этой строке. - person GeoFresher; 01.10.2018
comment
Нет, по умолчанию таблица не будет создана, если она не существует, вам нужно вызвать store.dataStore.createSchema(nSchema); для создания таблицы. - person Ian Turton; 01.10.2018
comment
Я попытался выполнить с существующим именем таблицы, и это не удалось с исключением нулевого указателя. Я также попытался создать новую таблицу на основе вашего ввода, используя dataStore.createSchema(nSchema), я получил то же самое исключение нулевого указателя в той же точке. Я что-то упустил в конкретной зависимости w.r.t для PostGIS? Он отлично работает до добавления атрибута, после чего код дает сбой после чтения сведений о параметре postgis. Я немного потерялся с половиной знаний в этой реализации. - person GeoFresher; 01.10.2018
comment
вы добавили gt-postgis в зависимости? может быть лучше задать новый q с кодом и трассировкой стека - person Ian Turton; 01.10.2018
comment
Конечно ... Спасибо за ваш вклад, Ян .. :) Я попытаюсь опубликовать новый вопрос в трассировке стека ... кажется, это нестандартно для этого вопроса .. - person GeoFresher; 01.10.2018