GeoTools应用:往shape文件中写GIS图层数据(5)
#一、环境准备
装配GeoTools有两种方式,一种是配置maven工程的pom文件(配置方式参考官网),另一种是下载geotools的jar包到本地导入依赖。我采用的是下载jar的方式,下载路径:https://sourceforge.net/projects/geotools/files/
#二、实现功能
本章要描述的功能是如何将GIS对象数据写入shape文件。下面以Point对象为例,线和多边形的处理方式类似。
#三、样例代码
##1、ShapeFieldInfo定义
package com.elon.model;
import java.io.Serializable;
/**
* Shape文件字段信息模型。
*
* @author elon
* @version 2018年6月24日
*/
public class ShapeFieldInfo implements Serializable {
private static final long serialVersionUID = 6947403344262247581L;
/**
* 字段名称
*/
private String fieldName = "";
/**
* 字段类型
*/
private Class<?> fieldType = null;
public ShapeFieldInfo(String fieldName, Class<?> fieldType) {
this.fieldName = fieldName;
this.fieldType = fieldType;
}
@Override
public String toString() {
return "fieldName:" + fieldName + "|fieldType:" + fieldType.getName();
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public Class<?> getFieldType() {
return fieldType;
}
public void setFieldType(Class<?> fieldType) {
this.fieldType = fieldType;
}
}
##2、定义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 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 List<ShapeFieldInfo> attrFieldList = new ArrayList<>();
/**
* 属性值信息<属性名称, 属性值>
*/
private Map<String, Object> attributeMap = new HashMap<>();
protected GISObjectBase(EnumGISObjectType type,
List<ShapeFieldInfo> attrFieldList){
this.type = type;
this.attrFieldList = attrFieldList;
}
public EnumGISObjectType getType() {
return type;
}
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 List<ShapeFieldInfo> getAttrFieldList() {
return attrFieldList;
}
public void setAttrFieldList(List<ShapeFieldInfo> attrFieldList) {
this.attrFieldList = attrFieldList;
}
}
##3、定义GISPoint的模型
package com.elon.model.gismodel;
import java.util.List;
import com.elon.constant.EnumGISObjectType;
import com.elon.model.ShapeFieldInfo;
import com.vividsolutions.jts.geom.Point;
/**
* 点对象模型
* @author elon
* @version 2018年6月26日
*/
public class GISPoint extends GISObjectBase {
private static final long serialVersionUID = 851468237977190995L;
/**
* 点geometry对象
*/
private Point point = null;
public GISPoint(Point point, List<ShapeFieldInfo> attrFieldList) {
super(EnumGISObjectType.POINT, attrFieldList);
this.point = point;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
}
##4、写GISPoint对象到shape文件的代码
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.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
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 {
/**
* 写GIS对象到Shape文件。
* @param dataStore shape文件源
* @param gisObjectList 对象列表
* @param attrFieldList 属性列表
* @throws IOException
*/
public static <T extends GISObjectBase> void writeShapeFile(ShapefileDataStore dataStore, List<T> gisObjectList,
List<ShapeFieldInfo> attrFieldList) throws IOException {
if (gisObjectList.isEmpty()) {
return;
}
EnumGISObjectType type = gisObjectList.get(0).getType();
// 设置图层对象属性
SimpleFeatureType featureType = buildFeatureType(attrFieldList, type);
dataStore.createSchema(featureType);
dataStore.setCharset(Charset.forName("GBK"));
List<SimpleFeature> featureList = buildFeatureList(gisObjectList, type, featureType);
// 写数据
SimpleFeatureSource featureSource = (SimpleFeatureSource) dataStore
.getFeatureSource(dataStore.getTypeNames()[0]);
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
SimpleFeatureCollection collection = new ListFeatureCollection(featureType, featureList);
Transaction transaction = new DefaultTransaction("create");
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
} finally {
transaction.close();
}
}
/**
* 构建feature对象列表。
*
* @param gisObjectList GIS对象列表
* @param type feature类型
* @param featureType
* @return feature列表
*/
private static <T extends GISObjectBase> List<SimpleFeature> buildFeatureList(List<T> gisObjectList,
EnumGISObjectType type, SimpleFeatureType featureType){
List<SimpleFeature> featureList = new ArrayList<>();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
for (T gis : gisObjectList) {
if (type == EnumGISObjectType.POINT) {
featureBuilder.set("the_geom", ((GISPoint)gis).getPoint());
}else if (type == EnumGISObjectType.LINE) {
featureBuilder.set("the_geom", ((GISLine)gis).getLine());
}else if (type == EnumGISObjectType.POLYGON) {
featureBuilder.set("the_geom", ((GISMultiPolygon)gis).getPolygon());
}else {
System.out.println("Invalid gisobject type.");
continue;
}
gis.getAttributeMap().forEach((k, v) -> featureBuilder.set(k, v));
featureList.add(featureBuilder.buildFeature(null));
}
return featureList;
}
/**
* 构建feature类型信息。
*
* @param attrFieldList 属性字段列表
* @param type gis对象类型
* @return feature类型
*/
private static SimpleFeatureType buildFeatureType(List<ShapeFieldInfo> attrFieldList,
EnumGISObjectType type) {
SimpleFeatureTypeBuilder sb = new SimpleFeatureTypeBuilder();
sb.setCRS(DefaultGeographicCRS.WGS84);
sb.setName("shape");
attrFieldList.forEach((f) -> sb.add(f.getFieldName(), f.getFieldType()));
if (type == EnumGISObjectType.POINT) {
sb.add("the_geom", Point.class);
}else if (type == EnumGISObjectType.LINE) {
sb.add("the_geom", MultiLineString.class);
}else if (type == EnumGISObjectType.POLYGON) {
sb.add("the_geom", MultiPolygon.class);
}else {
System.out.println("Invalid gisobject type.");
return null;
}
return sb.buildFeatureType();
}
/**
* 构建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;
}
}
##5、客户端调用代码
package com.elon;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.geotools.data.shapefile.ShapefileDataStore;
import com.elon.model.ShapeFieldInfo;
import com.elon.model.gismodel.GISPoint;
import com.elon.shape.ShapeUtils;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
public class StartupGeoTools {
public static void main(String[] args) throws IOException {
String workSpacePath = System.getProperty("user.dir");
List<ShapeFieldInfo> attrFieldList = new ArrayList<>();
attrFieldList.add(new ShapeFieldInfo("id", Integer.class));
attrFieldList.add(new ShapeFieldInfo("name", String.class));
GeometryFactory factory = new GeometryFactory();
List<GISPoint> pointList = new ArrayList<>();
GISPoint point1 = new GISPoint(factory.createPoint(new Coordinate(20.11, 35.22)), attrFieldList);
point1.getAttributeMap().put("id", 6);
point1.getAttributeMap().put("name", "111");
pointList.add(point1);
GISPoint point2 = new GISPoint(factory.createPoint(new Coordinate(50.121, 45.2222)), attrFieldList);
point2.getAttributeMap().put("id", 8);
point2.getAttributeMap().put("name", "222");
pointList.add(point2);
String shpFilePath2 = workSpacePath + File.separator + "shape/student/student.shp";
ShapefileDataStore dataStore = ShapeUtils.buildDataStore(shpFilePath2);
ShapeUtils.writeShapeFile(dataStore, pointList, attrFieldList);
dataStore.dispose();
System.out.println("Start GeoTools success!");
}
}
student.shp是用QGIS建的一个点图层shape文件,有id和name这两个属性。
#四、补充说明
上面写shape文件的方式是全量写的方式,也就是说新增的数据会将旧数据覆盖,不会保留。
转载自:https://blog.csdn.net/ylforever/article/details/80935231