在上一篇文章《GeoTools:Feature&Shapefile之CRUD操作》中,介绍了基于GeoTools的Shapefile文件CRUD基本操作,那么,能否使用GeoTools创建Shapefile文件呢?答案是可以的。以下,我们将深入讨论如何实现。
目录
SimpleFeatureType接口
ShapefileDataStoreFactory类
ShapefileDataStore类
创建Shapefile文件实示例
SimpleFeatureType接口
GeoTools框架内置了SimpleFeatureType接口,用于描述一个Shapefile文件的结构(即:通俗意义上的属性字段信息,既包括属性字段,也包括几何字段)。这个话题在之前已经讨论过。但是问题在于SImpleFeature是一个接口,如何创建其对象呢?
目前我总结下来的有两种方式,
①读取数据源时,通过DataStore数据源实例的getSchema(schemaName)方法获取;
②创建Shapefile文件时,使用GeoTools内置的DataUtilities工具类的createType方法获取。示例代码如下:
final SimpleFeatureType TYPE =
//定义图层的基本结构
DataUtilities.createType(
"Location",
"the_geom:Point:srid=4326,"
+ // <- the geometry attribute: Point type
"name:String,"
+ // <- a String attribute
"number:Integer" // a number attribute
);
ShapefileDataStoreFactory类
ShapefileDataStoreFactory类,可用于构建一个Shapefile数据源/存储对象,
通过该类的createNewDataStore()方法,接收一个Map类型的参数,可以创建一个代表Shapefile数据源对象的对象。
以下示例代码使用ShapefileDataStoreFactory类,从一个shp文件,创建一个ShapefileDataStore数据源对象,
String outputfilePath = "C:\\Users\\13241\\Documents\\data\\out.shp";
File file = new File(outputfilePath);
/*
* Get an output file name and create the new shapefile
* ShapefileDataStoreFactory-Builds instances of the shapefile data store
*/
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map<String, Serializable> params = new HashMap<>();
params.put("url", file.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
ShapefileDataStore newDataStore =
(ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
ShapefileDataStore类
GeoTools内置了ShapefileDataStore类,用于代表一个Shapefile数据源。该类提供了createNewDataStore()方法,可以基于SImpleFeatureType指定的Shapefile结构,创建一个Shapefile文件。
创建Shapefile文件实示例
以下为创建Shapefile文件,并通过SimpleFeatureCollection将Feature写入到Shapefile文件的完整示例代码。
@Test
public void createShp() throws Exception {
Random random = new Random();//随机数对象生成工具
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();//Geometry工厂对象
//创建shp基本结构
SimpleFeatureType featureType = DataUtilities.createType("Polygon",
"the_geom:Polygon:srid=4326," +
"name:String," +
"type:String");
List<AttributeType> types = featureType.getTypes();
types.forEach(System.out::println);
//创建shp文件
String shpFilePath = "C:\\Users\\13241\\Documents\\data\\polygon.shp";
File file = new File(shpFilePath);
if (!file.exists()) file.createNewFile();
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map<String, Serializable> params = new HashMap<>();
params.put("url", file.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
boolean flag = dataStoreFactory.canProcess(params);
if (flag){
ShapefileDataStore newDataStore =
(ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
newDataStore.createSchema(featureType);//创建shp
//获取新创建好的FeatureSource数据源操作
String typeName = newDataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
// SimpleFeatureType featureType = featureSource.getSchema();//获取shp的表结构
String nameSource = "sdajlskdadasl;d,a;ldal;sdaldam,sdadsad";
String[] typeArray = new String[]{"group_one","group_two","group_three","group_four"};
//构造FeatureCollection数据源
List<SimpleFeature> features = new ArrayList<>();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);//Feature要素构造器
for (int i = 0; i < 15; i++) {
double longitude = 120.0 + Math.random()*10,
latitude = 30.0 + Math.random()*10;
Coordinate[] coordinates = new Coordinate[]{
new Coordinate(longitude - 1,latitude-1),
new Coordinate(longitude - 1,latitude+1),
new Coordinate(longitude + 1,latitude+1),
new Coordinate(longitude + 1,latitude-1),
new Coordinate(longitude - 1,latitude-1)
// new Coordinate(119.0,32.0),
// new Coordinate(119.0,32.5),
// new Coordinate(120.0,32.5),
// new Coordinate(120.0,32.0),
// new Coordinate(119.0,32.0)
};
Polygon polygon = geometryFactory.createPolygon(coordinates);
featureBuilder.add(polygon);
featureBuilder.add(nameSource.substring(0,3+random.nextInt(nameSource.length()-5)));
featureBuilder.add(typeArray[random.nextInt(typeArray.length)]);
SimpleFeature simpleFeature = featureBuilder.buildFeature(null);
features.add(simpleFeature);
}
//根据List<SimpleFeature>构造SimpleFeatureCollection,并将其添加到Shapefile文件中
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
SimpleFeatureCollection collection = new ListFeatureCollection(featureType, features);
Transaction transaction = new DefaultTransaction("create");
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
} finally {
transaction.close();
}
System.exit(0); // success!
}
}else{
throw new Exception("操作不被支持!");
}
}
将创建好的shapefile文件放入QGIS中进行加载,显示效果如下,