将新列属性添加到shapefile并使用Geotools Java将其保存到数据库
Add new column attribute to the shapefile and save it to database using Geotools Java
问题描述
我正在通过添加新的列属性来转换shapefile。由于此任务是使用Java执行的,因此我现在知道的唯一选项是使用Geotools。我有两个主要问题:
参考:https://blog.csdn.net/weixin_35766308/article/details/118839642
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。
推荐答案
在GeoTools中,(简单)FeatureType是不可变的(不可更改),因此您不能只是向shapefile添加新属性。首先,您必须使用新属性创建一个新的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"); }