---
title: GeoTools-创建要素Feature
date: 2023-11-19
author: ac
categries:
- GIS
tags:
- GeoTools
---
### GeoTools-创建要素
> csv2shp,通过csv转点shp文件,学习:
>
> 1. 如何创建`FeatureType`、`FeatureCollection`和`Features`;
> 2. 通过`GeometryFactory`构建`Points`点集;
> 3. 输出shp文件;
> 4. 设置投影。
#### 1.数据准备
下载一份[csv文件](https://docs.geotools.org/latest/userguide/_downloads/d4bcf8751cc3f33a9fb673902a960e53/locations.csv) ,内容格式如下:
```text
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
```
#### 2.添加依赖
```xml
org.geotools
gt-shapefile
${geotools.version}
org.geotools
gt-epsg-hsql
${geotools.version}
osgeo
OSGeo Release Repository
https://repo.osgeo.org/repository/release/
false
true
osgeo-snapshot
OSGeo Snapshot Repository
https://repo.osgeo.org/repository/snapshot/
true
false
```
#### 3. 示例
```java
package learning;
import org.geotools.api.feature.simple.SimpleFeature;
import org.geotools.api.feature.simple.SimpleFeatureType;
import org.geotools.data.DataUtilities;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.swing.data.JFileDataStoreChooser;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import javax.swing.*;
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;
/**
* @author ac
* @date 2023/11/20 15:44
*/
public class Csv2Shape {
public static void main(String[] args) throws Exception {
// Set cross-platform look & feel for compatability
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
File file = JFileDataStoreChooser.showOpenFile("csv", null);
if (file == null) {
return;
}
/*
* We use the DataUtilities class to create a FeatureType that will describe the data in our
* shapefile.
*
* See also the createFeatureType method below for another, more flexible approach.
*
* 通过 DataUtilities 创建 FeatureType ,类似定义shp文件的名称、几何类型、属性字段、空间参考等信息。
*/
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
);
System.out.println("TYPE:" + TYPE);
/*
* A list to collect features as we create them.
*/
List features = new ArrayList<>();
/*
* GeometryFactory will be used to create the geometry attribute of each feature,
* using a Point object for the location.
* 创建几何工厂实例,要素构建者实例
* 通过缓冲流一行行读取,解析数据,构建Point实例
*/
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
/* First line of the data file is the header */
String line = reader.readLine();
System.out.println("Header: " + line);
for (line = reader.readLine(); line != null; line = reader.readLine()) {
if (line.trim().length() > 0) { // skip blank lines
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());
/* Longitude (= x coord) first ! */
// 创建几何实例geometry - point
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
// 创建要素实例feature
// feature
// ↙ ↘
// geometry properties
featureBuilder.add(point);
featureBuilder.add(name);
featureBuilder.add(number);
SimpleFeature feature = featureBuilder.buildFeature(null);
features.add(feature);
}
}
}
/*
* Get an output file name and create the new shapefile
*
* 设置输出路径
*/
File newFile = getNewShapeFile(file);
// 创建数据存储工厂实例
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map params = new HashMap<>();
params.put("url", newFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
// 创建新的数据存储,会输出shp文件
ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
/*
* TYPE is used as a template to describe the file contents
* 添加类型描述
*/
newDataStore.createSchema(TYPE);
}
/**
* Prompt the user for the name and path to use for the output shapefile
* 弹窗让用户选择新生成的shp文件的保存位置
*
* @param csvFile the input csv file used to create a default shapefile name
* @return name and path for the shapefile as a new File object
*/
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;
}
}
```
#### 参考文章
[1] Feature Tutorial https://docs.geotools.org/latest/userguide/tutorial/feature/csv2shp.html