Geotools例子2,解析csv文件保存为shp


locations.csv

  • 随意将其他位置添加到文件中,例如您的家乡。

  • Dependencies文件

    ? 教程采用的版本为最新版本23-SNAPSHOT,测试的时候发现出现点问题,我使用的是版本22.2,可根据自己需要采用不同的版本

    <dependencies>
      <--shapefile相关依赖-->
      <dependency>
       <groupId>org.geotoolsgroupId>
       <artifactId>gt-shapefileartifactId>
       <version>${geotools.version}version>
      dependency>
      <--投影依赖-->
      <dependency>
       <groupId>org.geotoolsgroupId>
       <artifactId>gt-epsg-hsqlartifactId>
       <version>${geotools.version}version>
      dependency>
     dependencies>
      <--以下三个仓库不用FQ可用,maven仓库如果无法使用可使用国内镜像-->
      <repositories>
          <repository>
              <id>maven2-repository.dev.java.netid>
              <name>Java.net repositoryname>
              <url>http://download.java.net/maven/2url>
          repository>
          <repository>
              <id>osgeoid>
              <name>Open Source Geospatial Foundation Repositoryname>
              <url>http://download.osgeo.org/webdav/geotools/url>
          repository>
          <repository>
            <snapshots>
              <enabled>trueenabled>
            snapshots>
            <id>boundlessid>
            <name>Boundless Maven Repositoryname>
            <url>http://repo.boundlessgeo.com/mainurl>
          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;
    }