使用GeoTools关联CSV属性到Shapefile失败,求解决方案
问题描述
需将导入的CSV文件属性传递至已存入FeatureCollection的Shapefile,通过Shapefile的SCH_SG属性与CSV的SCH_GEM属性匹配特征并更新属性,但多次尝试后属性仍未成功添加。
关联方法
public SimpleFeatureCollection linkCsvShp(SimpleFeatureCollection sfColl) { // 遍历Shapefile数据源的要素并更新属性 try (SimpleFeatureIterator it = sfColl.features()) { DefaultFeatureCollection newSfc = new DefaultFeatureCollection(); while (it.hasNext()) { SimpleFeature sf = it.next(); String shpKeyAttribute = (String) sf.getAttribute("SCH_SG"); try (FeatureIterator<SimpleFeature> csvFeatures = csvCollection.features()) { while (csvFeatures.hasNext()) { SimpleFeature csvFeature = csvFeatures.next(); Object csvAttribute = csvFeature.getAttribute("SCH_GEM"); if (csvAttribute != null && csvAttribute.equals(shpKeyAttribute)) { // 更新Shape要素的属性 sf.setAttribute("GEM_TYP", csvFeature.getAttribute("GEM_TYP")); sf.setAttribute("KREIS", csvFeature.getAttribute("KREIS")); sf.setAttribute("REGION", csvFeature.getAttribute("REGION")); sf.setAttribute("EINW_KL", csvFeature.getAttribute("EINW_KLASSE")); newSfc.add(sf); break; } } } } it.close(); setStatus("Das Punktfeature wurde erfolgreich erweitert!"); } return sfColl; }
Shapefile加载方法
java.net.URL shapeURL = pointFile.toURI().toURL(); store = new ShapefileDataStore(shapeURL); store.setTryCPGFile(true); SimpleFeatureSource fSource = store.getFeatureSource(); SimpleFeatureCollection sfColl = linkCsvShp(fSource.getFeatures());
CSV加载方法
private FeatureCollection<SimpleFeatureType, SimpleFeature> csvCollection; public void loadCsv(String path) { Map<String, Serializable> params = new HashMap<String, Serializable>(); params.put("file", path); DataStore store; try { store = DataStoreFinder.getDataStore(params); String typeName = store.getTypeNames()[0]; FeatureSource<SimpleFeatureType, SimpleFeature> source = store.getFeatureSource(typeName); Filter filter = Filter.INCLUDE; csvCollection = source.getFeatures(filter); } catch (IOException e) { e.printStackTrace(); } }
问题排查与解决方案
1. 返回值错误
当前linkCsvShp方法最后返回原始的sfColl,而非处理后的newSfc,导致所有修改无法生效。修改返回语句:
return newSfc;
2. 要素类型不兼容
Shapefile的SimpleFeatureType必须包含要添加的属性(GEM_TYP、KREIS、REGION、EINW_KL),否则setAttribute调用会失败。需先扩展要素类型:
// 扩展原始SimpleFeatureType SimpleFeatureType originalType = sfColl.getSchema(); SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.init(originalType); // 按CSV属性类型添加新字段 builder.add("GEM_TYP", String.class); builder.add("KREIS", String.class); builder.add("REGION", String.class); builder.add("EINW_KL", String.class); SimpleFeatureType newType = builder.buildFeatureType(); // 转换要素类型后再赋值 SimpleFeature newFeature = DataUtilities.retype(newType, sf); newFeature.setAttribute("GEM_TYP", csvFeature.getAttribute("GEM_TYP")); newFeature.setAttribute("KREIS", csvFeature.getAttribute("KREIS")); newFeature.setAttribute("REGION", csvFeature.getAttribute("REGION")); newFeature.setAttribute("EINW_KL", csvFeature.getAttribute("EINW_KLASSE")); newSfc.add(newFeature);
3. 字符串匹配失效
检查SCH_SG与SCH_GEM是否存在空格、大小写差异或数据类型不匹配(如一个是数字字符串,一个是整数)。添加标准化处理:
String shpKeyAttribute = (String) sf.getAttribute("SCH_SG"); if (shpKeyAttribute != null) { shpKeyAttribute = shpKeyAttribute.trim(); } String csvAttribute = csvFeature.getAttribute("SCH_GEM") != null ? csvFeature.getAttribute("SCH_GEM").toString().trim() : null; if (csvAttribute != null && csvAttribute.equals(shpKeyAttribute)) { // 执行属性更新逻辑 }
4. 资源冗余关闭
try-with-resources会自动关闭迭代器,可移除多余的it.close()语句,避免潜在异常。
5. 未匹配要素保留
若需要保留未匹配的Shapefile要素,在CSV循环结束后添加:
if (!newSfc.contains(sf)) { newSfc.add(sf); }
内容的提问来源于stack exchange,提问作者Marc
相关产品推荐
相关产品推荐

