GeoTools应用:读取Shape文件对象属性值(3)
程序员文章站
2023-12-26 16:23:46
...
一、环境准备
装配GeoTools有两种方式,一种是配置maven工程的pom文件(配置方式参考官网),另一种是下载geotools的jar包到本地导入依赖。我采用的是下载jar的方式,下载路径:https://sourceforge.net/projects/geotools/files/
二、实现功能
前面两章讲了如何从shape文件中提取属性列头信息和对象的空间坐标数据。这章讲解如何从shape文件中读取每个对象的属性值。
shape文件不是一个文件而是一堆文件,不同的文件描述了GIS对象的不同信息。.shp存储的是坐标数据; .dbf存储对象的属性; *.prj存储的是坐标系信息。这章讲的读取对象属性信息其实就是从dbf文件读取数据。
基础的GIS对象模型参考第二篇:《Java编程基础:GeoTools读取Shape文件中的空间坐标数据(2)》(https://blog.csdn.net/ylforever/article/details/80813711)。
三、样例代码
下面的代码在读取GIS对象时提取出每个对象的属性值,存储在基础GIS对象模型中。
1、GIS对象模型
package com.elon.model.gismodel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opengis.feature.simple.SimpleFeature;
import com.elon.constant.EnumGISObjectType;
import com.elon.model.ShapeFieldInfo;
/**
* GIS对象基类定义。
*
* @author elon
* @version 2018年6月26日
*/
public class GISObjectBase implements Serializable {
private static final long serialVersionUID = -6147262367078689317L;
/**
* 对象类型枚举
*/
private final EnumGISObjectType type;
private SimpleFeature simpleFeature = null;
/**
* 属性列信息
*/
private List<ShapeFieldInfo> attrFieldList = new ArrayList<>();
/**
* 属性值信息<属性名称, 属性值>
*/
private Map<String, Object> attributeMap = new HashMap<>();
protected GISObjectBase(EnumGISObjectType type, SimpleFeature simpleFeature,
List<ShapeFieldInfo> attrFieldList){
this.type = type;
this.simpleFeature = simpleFeature;
this.attrFieldList = attrFieldList;
}
public EnumGISObjectType getType() {
return type;
}
public SimpleFeature getSimpleFeature() {
return simpleFeature;
}
public Map<String, Object> getAttributeMap() {
return attributeMap;
}
public void setAttributeMap(Map<String, Object> attributeMap) {
this.attributeMap = attributeMap;
}
public void addAttribute(String attrName, Object value) {
attributeMap.put(attrName, value);
}
public void setSimpleFeature(SimpleFeature simpleFeature) {
this.simpleFeature = simpleFeature;
}
public List<ShapeFieldInfo> getAttrFieldList() {
return attrFieldList;
}
public void setAttrFieldList(List<ShapeFieldInfo> attrFieldList) {
this.attrFieldList = attrFieldList;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
2、读取GIS对象时填充属性MAP表
package com.elon.shape;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import com.elon.model.ShapeFieldInfo;
import com.elon.model.gismodel.GISObjectBase;
import com.elon.model.gismodel.GISPoint;
import com.elon.model.gismodel.GisLine;
import com.elon.model.gismodel.GisMultiPolygon;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
/**
* Shape文件操作公共类。
* @author elon
* @version 2018年6月24日
*/
public class ShapeUtils {
/**
* 提取shape文件包含的属性字段名称和类型信息。
*
* @param shpFilePath shape文件路径
* @return 属性信息
*/
public static List<ShapeFieldInfo> distillShapeFieldInfo(String shpFilePath) {
List<ShapeFieldInfo> fieldList = new ArrayList<>();
ShapefileDataStore dataStroe = buildDataStore(shpFilePath);
try {
List<AttributeDescriptor> attrList = dataStroe.getFeatureSource().getSchema()
.getAttributeDescriptors();
for (AttributeDescriptor attr : attrList) {
ShapeFieldInfo field = new ShapeFieldInfo();
field.setFieldName(attr.getLocalName());
field.setFieldType(attr.getType().getBinding());
fieldList.add(field);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
dataStroe.dispose();
}
return fieldList;
}
/**
* 读取GIS图层对象。
* @param shpFilePath shp文件路径
* @return 对象列表
*/
@SuppressWarnings("unchecked")
public static <T extends GISObjectBase> List<T> readGisObject(String shpFilePath) {
List<T> gisObjectList = new ArrayList<>();
List<ShapeFieldInfo> attrFieldList = distillShapeFieldInfo(shpFilePath);
ShapefileDataStore dataStore = buildDataStore(shpFilePath);
try {
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> fs = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> fcResult = fs.getFeatures();
System.out.println("fcResult size:" + fcResult.size());
FeatureIterator<SimpleFeature> iter = fcResult.features();
while (iter.hasNext()) {
SimpleFeature sf = iter.next();
Collection<Property> property = sf.getProperties();
Iterator<Property> iterP = property.iterator();
while (iterP.hasNext()) {
Property pro = iterP.next();
if (pro.getValue() instanceof MultiPolygon) {
gisObjectList.add((T) new GisMultiPolygon((MultiPolygon) pro.getValue(), sf, attrFieldList));
} else if (pro.getValue() instanceof Point) {
gisObjectList.add((T) new GISPoint((Point) pro.getValue(), sf, attrFieldList));
} else if (pro.getValue() instanceof MultiLineString) {
gisObjectList.add((T) new GisLine((MultiLineString) pro.getValue(), sf, attrFieldList));
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
dataStore.dispose();
}
fillGisObjectAttr(gisObjectList);
return gisObjectList;
}
/**
* 填充GIS对象的属性信息。
*
* @param gisObjectList gis对象列表
*/
private static <T extends GISObjectBase> void fillGisObjectAttr(List<T> gisObjectList) {
for(T gisObject : gisObjectList) {
for(ShapeFieldInfo field : gisObject.getAttrFieldList()) {
Object value = gisObject.getSimpleFeature().getAttribute(field.getFieldName());
gisObject.addAttribute(field.getFieldName(), value);
}
System.out.println(gisObject.getAttributeMap());
}
}
/**
* 构建ShapeDataStore对象。
* @param shpFilePath shape文件路径。
* @return
*/
public static ShapefileDataStore buildDataStore(String shpFilePath) {
ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
try {
ShapefileDataStore dataStore = (ShapefileDataStore) factory
.createDataStore(new File(shpFilePath).toURI().toURL());
if (dataStore != null) {
dataStore.setCharset(Charset.forName("UTF-8"));
}
return dataStore;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
四、补充说明
通过这种方式读取的属性MAP表中存储了GIS对象的坐标信息,对应的key是the_geom。多变形和线的the_geom值很长,如果需要在在界面展示属性,可以把它去掉。