SpringBoot + geotools 操作 shp文件

1、GeoTools相关的依赖

<dependencies>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-mysql</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>
        <!-- 解析几何geometry对象用的-->
        <dependency>
            <groupId>org.locationtech.jts</groupId>
            <artifactId>jts-core</artifactId>
            <version>1.19.0</version>
        </dependency>
    </dependencies>

在pom文件中添加以下文字,防止geotools依赖导入失败

<repositories>
        <repository>
            <id>osgeo</id>
            <name>OSGeo Release Repository</name>
            <url>https://repo.osgeo.org/repository/release/</url>
            <snapshots><enabled>false</enabled></snapshots>
            <releases><enabled>true</enabled></releases>
        </repository>
        <repository>
            <id>osgeo-snapshot</id>
            <name>OSGeo Snapshot Repository</name>
            <url>https://repo.osgeo.org/repository/snapshot/</url>
            <snapshots><enabled>true</enabled></snapshots>
            <releases><enabled>false</enabled></releases>
        </repository>
    </repositories>

2、本文所用到的公共类及实体类

R

@Data
@NoArgsConstructor
public class R<T> {
    private int code;
    private String msg;
    private T data;


    public static R ok(){
        R r = new R();
        r.setCode(200);
        r.setMsg("成功");
        return r;
    }
    public static R error(){
        R r = new R();
        r.setCode(444);
        r.setMsg("失败");
        return r;
    }


    public R data(T data){
        this.setData(data);
        return this;
    }
}

China

@Data
public class China {
    private int fid;
    private String theGeom;
    private String sheng;
}

3、本文所用到的数据库表

china
在这里插入图片描述

4、WKT格式怎么转化为GeoJson格式

工具类

     /**
     *  WKT 格式转化为 GeoJson
     * @Param: 传入WKT形式的字符串
     */

    public static String WktToGeojson(String wktPoint){
        WKTReader reader = new WKTReader();
        Geometry geometry = null;
        try {
            geometry = reader.read(wktPoint);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        StringWriter writer = new StringWriter();
        GeometryJSON g = new GeometryJSON();
        try {
            g.write(geometry, writer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String result = writer.toString();
        return result;
    }

测试:

// wkt转geoJson
    @GetMapping("/WktToGeojson")
    public R WktToGeojson(){
        try {
            String wktPoint = "POINT(11.11111 12.22222)";
            String result = GeoToolsUtils.WktToGeojson(wktPoint);
            return R.ok().data(result);
        } catch (Exception e) {
            System.out.println("转换异常!" + e.toString());
        }
        return R.error();
    }

结果:

在这里插入图片描述

5、GeoJson格式怎么转化为WKT格式

工具类

/**
     *  GeoJson 格式转化为 WKT
     * @Param: 传入GeoJson形式的字符串
     */
    public static String GeojsonToWkt(String geoJson) {
        GeometryJSON gjson = new GeometryJSON();
        Reader reader = new StringReader(geoJson);
        Geometry geometry = null;
        try {
            geometry = gjson.read(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String wkt = geometry.toText();
        return wkt;
    }

测试:

// geoJson转wkt
    @GetMapping("/GeojsonToWkt")
    public R GeojsonToWkt(){
        String geoJson="{\n" +
                "  \"type\": \"MultiPolygon\",\n" +
                "  \"coordinates\":\n" +
                "    [ \n" +
                "        [\n" +
                "            [\n" +
                "                [109.2041015625,30.088107753367257],\n" +
                "                [115.02685546875,30.088107753367257],\n" +
                "                [115.02685546875,32.7872745269555],\n" +
                "                [109.2041015625,32.7872745269555],\n" +
                "                [109.2041015625,30.088107753367257]\n" +
                "          \n" +
                "          \n" +
                "            ]\n" +
                "        ],\n" +
                "        [\n" +
                "            [\n" +
                "                [112.9833984375,26.82407078047018],\n" +
                "                [116.69677734375,26.82407078047018],\n" +
                "                [116.69677734375,29.036960648558267],\n" +
                "                [112.9833984375,29.036960648558267],\n" +
                "                [112.9833984375,26.82407078047018]\n" +
                "            ]\n" +
                "        ]\n" +
                "    ]\n" +
                "}";
        String wkt = GeoToolsUtils.GeojsonToWkt(geoJson);
        return R.ok().data(wkt);
    }

结果:
在这里插入图片描述

6、怎么把一张表的数据写入shp文件中

工具类

    /**
     * 写shp文件
     * @Param: 文件存放的路径和名字  格式:D:\\test\\locations.shp
     * @Param: 需要构建的shp文件的属性表字段名,其中第一个参数为空间数据名,比如 list["the_geom","fid","name","number"]
     * @Param: 需要存入属性表中的值,其中空间属性值为WKT格式,属性顺序与名称必须与第二个参数传入的顺序一致
     * @Param: 传入的空间属性类型,比如:Point、LineString、Polygon等
     */
    public static void WriteSHP(String path,List<String> list,List<?> dataList,Class<?> geometry) throws IOException, IllegalAccessException, ParseException {
        //1.创建shape文件对象
        File file =new File(path);

        Map<String, Serializable> params = new HashMap<>();

        //用于捕获参数需求的数据类
        //URLP:url to the .shp file.
        params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());

        //2.创建一个新的数据存储——对于一个还不存在的文件。
        ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);

        //3.定义图形信息和属性信息
        //SimpleFeatureTypeBuilder 构造简单特性类型的构造器
        SimpleFeatureTypeBuilder tBuilder = new SimpleFeatureTypeBuilder();

        //设置
        //WGS84:一个二维地理坐标参考系统,使用WGS84数据
        tBuilder.setCRS(DefaultGeographicCRS.WGS84);
        tBuilder.setName("shapefile");
        

        //构造属性表字段名
        tBuilder.add(list.get(0), geometry);
        for(int i=1;i<list.size();i++){
            tBuilder.add(list.get(i),String.class);
        }


        //设置此数据存储的特征类型
        ds.createSchema(tBuilder.buildFeatureType());

        //设置编码
        ds.setCharset(Charset.forName("GBK"));

        //设置writer
        //为给定的类型名称创建一个特性写入器

        //1.typeName:特征类型
        //2.transaction :事物,写入失败,回滚
        //3.ShapefileDataStore::getTypeNames:
		/*public String[] getTypeNames()
		 获取这个数据存储保存的类型名称数组。
		ShapefileDataStore总是返回一个名称
		*/
        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(
                ds.getTypeNames()[0], Transaction.AUTO_COMMIT);



        //从数据库中读取数据
        SimpleFeature feature = null;

        GeometryFactory geometryFactory = new GeometryFactory();




        for(Object o:dataList){
            feature= writer.next();


            // 通过反射机制获取对象的属性值
            Class<?> aClass = o.getClass();
            Field[] fields = aClass.getDeclaredFields();

            for(Field f:fields){
                f.setAccessible(true);

                // 获得属性值
                String s=f.get(o).toString();


                if(s.indexOf("POINT")==0||s.indexOf("MULTIPOINT")==0||s.indexOf("LINESTRING")==0
                    ||s.indexOf("MULTILINESTRING")==0||s.indexOf("POLYGON")==0||s.indexOf("MULTIPOLYGON")==0){

                    WKTReader reader = new WKTReader(geometryFactory);
                    feature.setAttribute(list.get(0),reader.read(s));

                }else{
                    // 设置属性名和属性值
                    feature.setAttribute(f.getName(), s);
                }
            }
        }

        //写入
        writer.write();

        //关闭
        writer.close();

        //释放资源
        ds.dispose();
    }

测试:
Controller

    // 写shp文件
    @PostMapping("/WriteSHP")
    public R WriteSHP() throws IOException, ParseException, IllegalAccessException {


        String path="D:\\test\\china\\china.shp";

        ArrayList<String> arr = new ArrayList<>();
        arr.add("the_geom");
        arr.add("fid");
        arr.add("sheng");

        GeoToolsUtils.WriteSHP(path,arr, chinaService.getAll(), MultiPolygon.class);

        return R.ok();
    }

service:

List<China> getAll();

serviceImpl:

    @Autowired
    private ChinaMapper chinaMapper;

    @Override
    public List<China> getAll() {
        return chinaMapper.getAll();
    }

mapper:

    int insert(China china);

mapper.xml:

    <resultMap id="BaseChina" type="China">
        <id column="fid" jdbcType="INTEGER" property="fid"/>
        <result column="the_geom" jdbcType="OTHER" property="theGeom" />
        <result column="sheng" jdbcType="OTHER" property="sheng" />
    </resultMap>
    
    <select id="getAll" resultMap="BaseChina">
        select fid,ST_ASWKT(the_geom) AS the_geom,sheng from china
    </select>

结果:

在这里插入图片描述

查看 D:\test\china 路径:
在这里插入图片描述

使用ArcMap查看china.shp:
在这里插入图片描述
查看china.shp的属性表:
在这里插入图片描述

7、怎么读取shp文件并把数据存入数据库表中

工具类

/**
     *     读shp文件并把数据存入数据库
     * @Param: 需要读取的shp文件的路径及名字
     * @return
     */
    public static FeatureCollection<SimpleFeatureType, SimpleFeature> ReadSHP(String path) throws Exception{

        //构建shapefile数据存储的实例
        ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

        //基于路径构建文件对象
        File file = new File(path);

        //构建一个已存在的shapfile数据源
        //ShapefileDataStore:数据存储实现,允许从Shapefiles读取和写入
        ShapefileDataStore ds = (ShapefileDataStore) dataStoreFactory.createDataStore(file.toURI().toURL());

        //设置编码,防止中文读取乱码
        ds.setCharset(Charset.forName("GBK"));

        //getFeatureSource():ContentFeatureSource
        //这个特性是由 FeatureCollection提供的操作完成的。单独的特征记忆实现由子类提供:
        //SimpleFeatureSource特征资源明确地使用FeatureCollection【集合】,可迭代
        SimpleFeatureSource featureSource = ds.getFeatureSource();

        //getFeatures():以FeatureCollection的形式检索所有特性。
        //一个用于处理FeatureCollection的实用工具类。提供一个获取FeatureCollection实例的机制
        FeatureCollection<SimpleFeatureType, SimpleFeature> result=featureSource.getFeatures();

        System.out.println("几何对象总共有:"+result.size());

        return result;
    }

测试: 这里的shp文件基于上面第6点所构造的shp文件,while循环中设置China属性值的顺序是按照shp文件属性表中的顺序来的

controller

// 读取shp文件并把数据存入mysql
    @PostMapping("/ReadSHP")
    public R ReadSHP() throws Exception {
        //基于shapfile文件,进行读取
        String path = "D:\\test\\china\\china.shp";

        FeatureCollection<SimpleFeatureType, SimpleFeature> result = GeoToolsUtils.ReadSHP(path);

        System.out.println("几何对象总共有:"+result.size());
        //features():返回一个FeatureIterator迭代器
        SimpleFeatureIterator it =(SimpleFeatureIterator) result.features();

        while(it.hasNext()){
            SimpleFeature feature = it.next();
            //迭代属性【属性我们可以理解为一个几何对象的属性节点,也就是对一个几何图形的描述字段】
            Iterator<Property> ip = feature.getProperties().iterator();
            System.out.println("========================");

            China china = new China();

            Property property = ip.next();
            china.setTheGeom(String.valueOf(property.getValue()));

            property=ip.next();
            china.setFid(Integer.parseInt((String) property.getValue()));

            property=ip.next();
            china.setSheng(String.valueOf(property.getValue()));


            chinaService.insertWKT(china);
        }
        it.close();


        return R.ok();
    }

service:

    int insertWKT(China china);

serviceImpl:

    @Override
    public int insertWKT(China china) {
        return chinaMapper.insertWKT(china);
    }

mapper:

    int insertWKT(China china);

mapper.xml: 我这里数据库中空间字段the_geom的类型设置为longtext,是以WKT格式直接存入数据库

    <insert id="insertWKT" parameterType="China">
        insert into newchina  (the_geom,sheng) values (#{theGeom},#{sheng})
    </insert>

结果:
在这里插入图片描述
数据库中也有值:
在这里插入图片描述

8、一些常用的空间函数(mysql版)

ST_AsText()ST_AsWKT()                        从Geometry格式转换为WKT
ST_AsGeoJSON()                                  从Geometry格式转换为GeoJson
ST_GeomFromText()ST_GeometryFromText()       从WKT格式返回Geometry
等等

参考文档:https://blog.csdn.net/ununie/article/details/101014849

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Geotools库来读写shp文件。下面是一个简单的示例代码,可以读取shp文件并打印出其属性表信息: ```java import java.io.File; import java.io.IOException; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; public class ShpFileReader { public static void main(String[] args) throws IOException { // 读取shp文件 File file = new File("path/to/shapefile.shp"); DataStore dataStore = DataStoreFinder.getDataStore(file); String typeName = dataStore.getTypeNames()[0]; SimpleFeatureType schema = dataStore.getSchema(typeName); // 获取属性表信息 System.out.println("Feature Type: " + typeName); System.out.println("Number of attributes: " + schema.getAttributeCount()); System.out.println("Attributes: "); for (int i = 0; i < schema.getAttributeCount(); i++) { System.out.println(schema.getAttributeDescriptors().get(i).getName()); } // 获取要素信息 SimpleFeatureCollection collection = dataStore.getFeatureSource(typeName).getFeatures(); try (SimpleFeatureIterator features = collection.features()) { while (features.hasNext()) { SimpleFeature feature = features.next(); System.out.println(feature.getID() + ": " + feature.getDefaultGeometryProperty().getValue()); } } dataStore.dispose(); } } ``` 需要注意的是,需要在pom.xml中添加geotools依赖: ```xml <dependency> <groupId>org.geotools</groupId> <artifactId>gt-shapefile</artifactId> <version>24.0</version> </dependency> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值