^ 关注我,带你一起学GIS ^
前言
❝在GIS开发中,经常需要进行数据的转换处理。在之前的文章中讲了如何使用GeoTools读取Shapefile数据,并且展示了将Shapefile数据导入PostGIS空间数据库的多种方式。但是还缺少Shapefile数据转换来源的操作。
本篇教程在之前文章的基础上讲解如何将CSV
文件转换为我们熟悉的Shapefile
数据。
开发环境
本文使用开发环境如下,仅供参考。
时间:2025年
GeoTools:34-SNAPSHOT
IDE:IDEA2025.1.2
JDK:17
1. 准备CSV文件
CSV(Comma-Separated Values)文件是一种纯文本格式,用于存储表格数据(如电子表格或数据库)。它以结构简单、兼容性广泛而著称,是数据交换中最常用的格式之一。
CSV文本结构:
Name,Age,Occupation
Alice,28,Engineer
Bob,32,Designer
Charlie,45,Manager
CSV表格结构:
2. 安装依赖
在之前开发的基础上增加gt-epsg-hsql
依赖包。
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
3. 读取CSV文件
使用showOpenFile
方法打开文件选择框,然后使用createType
构造要素结构,第一个参数"location"
为要素类型,第二个参数为要素属性。the_geom
字段表明数据几何类型为Point
;srid
表明数据坐标系为4326
以及后面的字段名称和对应字段类型。
// 设置外观
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// 选择文件
File file = JFileDataStoreChooser.showOpenFile("csv",null);
if(file == null ){
return;
}
// 创建要素类型
final SimpleFeatureType TYPE = DataUtilities.createType(
"location",
"the_geom:Point:srid=4326,"+
"name:String,"+
"number:Integer"
);
现在可以读取CSV
数据并构造Features
,使用GeometryFactory
来创建几何属性。
// 创建要素
List<SimpleFeature> features = new ArrayList<>();
// GeometryFactory 用来为要素创建几何属性
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
try(BufferedReader reader = new BufferedReader(new FileReader(file))){
// 读取第一行头部数据
String line = reader.readLine();
for(line = reader.readLine(); line != null; line = reader.readLine()){
if(line.trim().length()>0){
String[] tokens = line.split("\,");
double latitude = Double.parseDouble(tokens[0]);
double longitude = Double.parseDouble(tokens[1]);
String name = tokens[2].trim();
int number = Integer.parseInt(tokens[3].trim());
// 构造点
Point point = geometryFactory.createPoint(new Coordinate(longitude,latitude));
featureBuilder.add(point);
featureBuilder.add(name);
featureBuilder.add(number);
SimpleFeature feature = featureBuilder.buildFeature(null);
features.add(feature);
}
}
}
4. 创建Shapefile
ShapefileDataStoreFactory
创建Shp
工厂,在createDataStore
参数中将属性"create spatial index"
设置为true
标明为Shp
数据创建空间索引。
// 从要素集创建Shapefile
File newFile = getNewShapeFile(file);
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map<String, Serializable> params = new HashMap<>();
params.put("url",newFile.toURI().toURL());
params.put("create spatial index",Boolean.TRUE);
ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createDataStore(params);
// TYPE 用作描述文件内容的模板
dataStore.createSchema(TYPE);
通过确认FeatureSource
对象实现了FeatureStore
方法来检查是否具有读写权限,使用ListFeatureCollection
包装FeatureCollection
对象。最后使用transaction.comit()
一次性安全地写出所有数据。
// 输出要素数据到Shapefile
Transaction transaction = new DefaultTransaction("create");
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
SimpleFeatureType featureType = featureSource.getSchema();
if(featureSource instanceof SimpleFeatureStore){
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
SimpleFeatureCollection featureCollection = new ListFeatureCollection(featureType,features);
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(featureCollection);
transaction.commit();
}catch (Exception e){
e.printStackTrace();
transaction.rollback();
}finally {
transaction.close();
}
System.exit(0);
}else {
System.out.println(typeName + "缺少读|写权限!!");
System.exit(1);
}
5. Shapefile输出位置
使用getNewShapeFile
方法选择Shp
输出位置。
// 提示输出Shapefile
private static File getNewShapeFile(File csvFile){
String path = csvFile.getAbsolutePath();
String newPath = path.substring(0,path.length()-4)+".shp";
JFileDataStoreChooser chooser = new JFileDataStoreChooser(".shp");
chooser.setDialogTitle("保存 ShapeFile");
chooser.setSelectedFile(new File(newPath));
int returnVal = chooser.showSaveDialog(null);
if(returnVal != JFileDataStoreChooser.APPROVE_OPTION){
System.exit(0);
}
File newFile = chooser.getSelectedFile();
if(newFile.equals(csvFile)){
System.out.println("Error:不能替换" + csvFile);
System.exit(0);
}
return newFile;
}
❝
OpenLayers示例数据下载,请在公众号后台回复:ol数据
全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试
❝
GIS之路公众号已经接入了智能助手,欢迎大家前来提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏+关注 哦!
本号不定时更新有关 GIS开发 相关内容,欢迎关注