一、前提
1、生成shapefile前需要知道CSV文件是属于点(Point)、线(Line)、面(Polygon)、还是多面(MultiPolygon);因为shp文件是有这些属性的,这篇文章中用的示例CSV是点数据;
2、也需要知道CSV文件每个字段(通常CSV文件第一行是字段属性)是什么数据类型;因为CSV文件默认都是字符串,但是shapefile中每个字段都有具体的数据类型,所以要提前对应上(案例csv文件);
3、代码需要引入geotools的相关依赖;
二、代码
package com.example.forestry.util.geotools;
import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 将csv文件转换为shapefile并导出
*/
public class CSVToShp {
public static void main(String[] args) throws Exception {
String CSVFile = "D:\\data\\csv\\locations.csv";
String shpPath = "D:\\data\\csv\\shp";
String shpName = "tempp";
csvToShp(CSVFile , shpPath , shpName);
}
/**
* 将 CSV 数据写入 shp文件中,并导出指定位置
*
* @param path CSV文件的路径
* @param shpPath 生成的shp存放的路径
* @param shpName 生成的shp的名称(不包含.shp后缀)
* @return
*/
public static void csvToShp(String path , String shpPath , String shpName) throws Exception {
/**
* 第一部分,获取CSV特征数据列表(特征数据表示CSV每一行的数据)
*/
//用于存储的CSV每一行特征列表
List<SimpleFeature> list = new ArrayList<>();
//CSV文件对象
File file = new File(path);
//获取csv文件读取流
BufferedReader reader = new BufferedReader(new FileReader(file));
//获取csv文件的第一行,即csv文件的头部;此CSV头信息为(LAT属性、LON属性、CITY属性、NUMBER属性;LAT和LON为经纬度属性)
String CSVHead = reader.readLine();
System.out.println(CSVHead);
/**
* 创建和当前 CSV 匹配的类型
*
* typeName: 指定类型名称
* typeSpec:{
* 1、第一个参数是指定类型为Point,坐标系为4326(1984的平面坐标)
* 2、第二个参数是CSV的属性CITY,类型为String
* 3、第三个参数是CSV的属性NUMBER,类型为Integer
* }
*/
final SimpleFeatureType TYPE = DataUtilities.createType("Location",
"the_geom:Point:srid=4326," + "city:String," + "number:Integer");
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
//创建GeometryFactory对象,此对象用于生成点(Point)、线(Line)、面(Polygon)、多面(MultiPolygon)等对象
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
//遍历依次读取CSV文件的下一行
for(String featureStr = reader.readLine() ; featureStr != null ; featureStr = reader.readLine()){
String s = featureStr.replaceAll(" ", "");
String[] split = s.split(",");
//获取当前点的经纬度
double latitude = Double.parseDouble(split[0]);
double longitude = Double.parseDouble(split[1]);
Point point = geometryFactory.createPoint(new Coordinate(latitude, longitude));
//获取当前点的CITY属性
String city = split[2];
//获取当前点的NUMBER属性
int number = Integer.parseInt(split[3]);
//将当前点的经纬度、CITY、NUMBER属性存入 featureBuilder 中
featureBuilder.add(point);
featureBuilder.add(city);
featureBuilder.add(number);
// featureBuilder 生成一个点特征
SimpleFeature simpleFeature = featureBuilder.buildFeature(null);
list.add(simpleFeature);
}
/**
* 第二部分 , 生成shp文件
*/
//生成shp文件
File newFile = new File(shpPath + File.separator + shpName + ".shp");
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map<String, Serializable> params = new HashMap<>();
params.put("url", newFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
//根据CSV类型创建 shp 的结构
newDataStore.createSchema(TYPE);
/**
* 第三部分,将CSV特征数据写入shp
*/
Transaction transaction = new DefaultTransaction("create");
String typeName = newDataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();
System.out.println("SHAPE:" + SHAPE_TYPE);
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
//将 CSV 特征数据存入 feature集合 中
SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, list);
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);
}
}
}