csv文件转换为shapefile并导出

一、前提

1、生成shapefile前需要知道CSV文件是属于点(Point)、线(Line)、面(Polygon)、还是多面(MultiPolygon);因为shp文件是有这些属性的,这篇文章中用的示例CSV是点数据;
2、也需要知道CSV文件每个字段(通常CSV文件第一行是字段属性)是什么数据类型;因为CSV文件默认都是字符串,但是shapefile中每个字段都有具体的数据类型,所以要提前对应上(案例csv文件);
3、代码需要引入geotools的相关依赖

二、代码

package com.example.forestry.util.geotools;

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.geometry.jts.JTSFactoryFinder;
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;

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;


/**
 * 将csv文件转换为shapefile并导出
 */
public class CSVToShp {

    public static void main(String[] args) throws Exception {
        String CSVFile = "D:\\data\\csv\\locations.csv";
        String shpPath = "D:\\data\\csv\\shp";
        String shpName = "tempp";
        csvToShp(CSVFile , shpPath , shpName);
    }


    /**
     * 将 CSV 数据写入 shp文件中,并导出指定位置
     *
     * @param path          CSV文件的路径
     * @param shpPath       生成的shp存放的路径
     * @param shpName       生成的shp的名称(不包含.shp后缀)
     * @return
     */
    public static void csvToShp(String path , String shpPath , String shpName) throws Exception {

        /**
         * 第一部分,获取CSV特征数据列表(特征数据表示CSV每一行的数据)
         */

        //用于存储的CSV每一行特征列表
        List<SimpleFeature> list = new ArrayList<>();
        //CSV文件对象
        File file = new File(path);

        //获取csv文件读取流
        BufferedReader reader = new BufferedReader(new FileReader(file));

        //获取csv文件的第一行,即csv文件的头部;此CSV头信息为(LAT属性、LON属性、CITY属性、NUMBER属性;LAT和LON为经纬度属性)
        String CSVHead = reader.readLine();
        System.out.println(CSVHead);
        /**
         * 创建和当前 CSV 匹配的类型
         *
         * typeName: 指定类型名称
         * typeSpec:{
         *              1、第一个参数是指定类型为Point,坐标系为4326(1984的平面坐标)
         *              2、第二个参数是CSV的属性CITY,类型为String
         *              3、第三个参数是CSV的属性NUMBER,类型为Integer
         *           }
         */
        final SimpleFeatureType TYPE = DataUtilities.createType("Location",
                "the_geom:Point:srid=4326," + "city:String," + "number:Integer");
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

        //创建GeometryFactory对象,此对象用于生成点(Point)、线(Line)、面(Polygon)、多面(MultiPolygon)等对象
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

        //遍历依次读取CSV文件的下一行
        for(String featureStr = reader.readLine() ; featureStr != null ; featureStr = reader.readLine()){
            String s = featureStr.replaceAll(" ", "");
            String[] split = s.split(",");

            //获取当前点的经纬度
            double latitude = Double.parseDouble(split[0]);
            double longitude = Double.parseDouble(split[1]);
            Point point = geometryFactory.createPoint(new Coordinate(latitude, longitude));

            //获取当前点的CITY属性
            String city = split[2];

            //获取当前点的NUMBER属性
            int number = Integer.parseInt(split[3]);

            //将当前点的经纬度、CITY、NUMBER属性存入 featureBuilder 中
            featureBuilder.add(point);
            featureBuilder.add(city);
            featureBuilder.add(number);

            // featureBuilder 生成一个点特征
            SimpleFeature simpleFeature = featureBuilder.buildFeature(null);

            list.add(simpleFeature);
        }


        /**
         * 第二部分 , 生成shp文件
         */
        //生成shp文件
        File newFile = new File(shpPath + File.separator + shpName + ".shp");

        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);
        //根据CSV类型创建 shp 的结构
        newDataStore.createSchema(TYPE);


        /**
         * 第三部分,将CSV特征数据写入shp
         */
        Transaction transaction = new DefaultTransaction("create");

        String typeName = newDataStore.getTypeNames()[0];
        SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
        SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();

        System.out.println("SHAPE:" + SHAPE_TYPE);

        if (featureSource instanceof SimpleFeatureStore) {
            SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;

            //将 CSV 特征数据存入 feature集合 中
            SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, list);
            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);
        }

    }


}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值