使用 geotools 生成 shapefile

前言

使用 GeoTools 将存储在 csv 文件中的数据读出并写入 shapefile 文件,并保存到本地。

GeoTools:是一个开放原代码的 Java 库,提供用于地理空间数据的工具
shapefile 文件:用于描述几何体对象,点、折线与多边形。例如,Shapefile文件可以存储井、河流、湖泊等空间对象的几何位置。除了几何位置,shp文件也可以存储这些空间对象的属性,例如一条河流的名字,一个城市的温度等等。


开发环境

  • 操作系统:windows
  • 集成开发环境:idea
  • 使用编程语言:java
  • 构建工具:gradle

开发步骤

  1. 使用 idea 新建一个空白的 gradle 项目。

    • 点击 Create New Project
      new-1
    • 点击 Next ,设置项目名,设置项目所在路径 new-2
    • 点击 Finish , 等待构建完成,构建时间取决于网速。
      new-3
    • 选中项目 新建代码存放目录。
      new-4
    • 将四个目录全选,然后敲回车,就可以了。
      new-5
    • 当前的项目结构
      new-6
  2. 在 build.gradle 中引入 GeoTools 依赖

    • 在 dependencies 语句块中加入
      implementation 'org.geotools:gt-shapefile:23-RC'
      implementation 'org.geotools:gt-epsg-hsql:23-RC'
      implementation 'org.geotools:gt-swing:23-RC'
      
    • 在 repositories 语句块中加入
      maven {
        url "https://repo.osgeo.org/repository/release/"
      }
      
    • 点击更新依赖
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYXNsbwY-1597714161247)(images/geo-sync.png)]
    • 完整的 build.gradle 内容
          plugins {
              id 'java'
          }
      
          group 'org.example'
          version '1.0-SNAPSHOT'
      
          repositories {
              maven {
                  url "https://repo.osgeo.org/repository/release/"
              }
              mavenCentral()
          }
      
          dependencies {
              implementation 'org.geotools:gt-shapefile:23-RC'
              implementation 'org.geotools:gt-epsg-hsql:23-RC'
              implementation 'org.geotools:gt-swing:23-RC'
              testCompile group: 'junit', name: 'junit', version: '4.12'
          }
      
  3. 创建工具类

     package org.example.tutorial;
    
     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;
     import javax.swing.UIManager;
     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.feature.simple.SimpleFeatureTypeBuilder;
     import org.geotools.geometry.jts.JTSFactoryFinder;
     import org.geotools.referencing.crs.DefaultGeographicCRS;
     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 org.opengis.feature.simple.SimpleFeature;
     import org.opengis.feature.simple.SimpleFeatureType;
    
     /**
     * This example reads data for point locations and associated attributes from a comma separated text
     * (CSV) file and exports them as a new shapefile. It illustrates how to build a feature type.
     *
     * <p>Note: to keep things simple in the code below the input file should not have additional spaces
     * or tabs between fields.
     */
     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.
             */
             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<SimpleFeature> features = new ArrayList<>();
    
             /*
             * GeometryFactory will be used to create the geometry attribute of each feature,
             * using a Point object for the location.
             */
             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 ! */
                         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);
                     }
                 }
             }
    
             /*
             * Get an output file name and create the new 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 newDataStore =
                     (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    
             /*
             * TYPE is used as a template to describe the file contents
             */
             newDataStore.createSchema(TYPE);
    
             /*
             * Write the features to the shapefile
             */
             Transaction transaction = new DefaultTransaction("create");
    
             String typeName = newDataStore.getTypeNames()[0];
             SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
             SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();
             /*
             * The Shapefile format has a couple limitations:
             * - "the_geom" is always first, and used for the geometry attribute name
             * - "the_geom" must be of type Point, MultiPoint, MuiltiLineString, MultiPolygon
             * - Attribute names are limited in length
             * - Not all data types are supported (example Timestamp represented as Date)
             *
             * Each data store has different limitations so check the resulting SimpleFeatureType.
             */
             System.out.println("SHAPE:" + SHAPE_TYPE);
    
             if (featureSource instanceof SimpleFeatureStore) {
                 SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
                 /*
                 * SimpleFeatureStore has a method to add features from a
                 * SimpleFeatureCollection object, so we use the ListFeatureCollection
                 * class to wrap our list of features.
                 */
                 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);
             }
         }
    
         /**
         * Prompt the user for the name and path to use for the output shapefile
         *
         * @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;
         }
    
         
     }
    

项目运行结果

将数据读取出来,然后生成 shapefile 文件
在这里插入图片描述


源码下载

利用GeoTools生成shapefile文件


参考文献

GeoTools 官网

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高建伟-joe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值