前言
本教程包括以下内容:
- 创建
FeatureType
,FeatureCollection
和Features
- 使用
GeometryFactory
建立点 - 写出一个Shapefile
- 强制投影
csv文件
-
创建一个文本文件
location.csv
,然后将以下位置复制并粘贴到其中:LAT, LON, CITY, NUMBER 46.066667, 11.116667, Trento, 140 44.9441, -93.0852, St Paul, 125 13.752222, 100.493889, Bangkok, 150 45.420833, -75.69, Ottawa, 200 44.9801, -93.251867, Minneapolis, 350 46.519833, 6.6335, Lausanne, 560 48.428611, -123.365556, Victoria, 721 -33.925278, 18.423889, Cape Town, 550 -33.859972, 151.211111, Sydney, 436 41.383333, 2.183333, Barcelona, 914 39.739167, -104.984722, Denver, 869 52.95, -1.133333, Nottingham, 800 45.52, -122.681944, Portland, 840 37.5667,129.681944,Seoul,473 50.733992,7.099814,Bonn,700,2016
-
或下载
locations.csv
。 -
随意将其他位置添加到文件中,例如您的家乡。
Dependencies文件
教程采用的版本为最新版本23-SNAPSHOT,测试的时候发现出现点问题,我使用的是版本22.2,可根据自己需要采用不同的版本
<dependencies>
<--shapefile相关依赖-->
<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>
</dependencies>
<--以下三个仓库不用FQ可用,maven仓库如果无法使用可使用国内镜像-->
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>boundless</id>
<name>Boundless Maven Repository</name>
<url>http://repo.boundlessgeo.com/main</url>
</repository>
</repositories>
步骤
1、选择csv文件
import org.geotools.swing.data.JFileDataStoreChooser;
File file = JFileDataStoreChooser.showOpenFile("csv", null);
if(file == null) {
return;
}
2、创建要素类型FeatureType
import org.opengis.feature.simple.SimpleFeatureType;
import org.geotools.data.DataUtilities;
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
);
3、解析csv文件,保存到SimpleFeature的数组中
解析的思路为:通过java读取器BufferedReader逐行读取csv文件(csv每行对应一个要素),通过几何要素工厂GeometryFactory创建几何要素点,通过shp要素构建工具SimpleFeatureBuilder构建shp要素,添加几何要素点信息和属性信息,最后添加到数组中。
import org.opengis.feature.simple.SimpleFeature;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.GeometryFactory
import org.geotools.feature.simple.SimpleFeatureBuilder;
// SimpleFeature数组
List<SimpleFeature> features = new ArrayList<SimpleFeature>();
// 几何要素工厂
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
// 要素构建器
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
try(
BufferedReader reader = new BufferedReader(new FileReader(file))
){
String line = reader.readLine();
// 解析csv文件到SimpleFeature列表中
for(line = reader.readLine(); line != null; line = reader.readLine()){
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、调出对话框,保存shp文件,此时shp文件为空文件,保存待用。
import org.geotools.swing.data.JFileDataStoreChooser;
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("Save shapefile");
chooser.setSelectedFile(new File(newPath));
int returnVal = chooser.showSaveDialog(null);
if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
// the user cancelled the dialog
System.exit(0);
}
// 此文件为空文件,需要填充要素
File newFile = chooser.getSelectedFile();
if (newFile.equals(csvFile)) {
System.out.println("Error: cannot replace " + csvFile);
System.exit(0);
}
return newFile;
}
5、获取shp数据源SimpleFeatureSource
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 newDataStore =
(ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
// 定义数据仓库 数据要素类型
newDataStore.createSchema(TYPE);
// FeatureStore事务控制,这里是创建create
Transaction transaction = new DefaultTransaction("create");
String typeName = newDataStore.getTypeNames()[0]; // points
// 要素源
SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
6、保存shp数据源到空的shp文件
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
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);
}
其他
1、构建SimpleFeatureType更为灵活的方式,可包含属性信息。
private static SimpleFeatureType createFeatureType() {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Location");
builder.setCRS(DefaultGeographicCRS.WGS84); // <- Coordinate reference system
// add attributes in order
builder.add("the_geom", Point.class);
builder.length(15).add("Name", String.class); // <- 15 chars width for name field
builder.add("number", Integer.class);
// build the type
final SimpleFeatureType LOCATION = builder.buildFeatureType();
return LOCATION;
}