--- 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