java 使用 geotools 将 shp 文件(zip压缩包)转换为 geoJson 格式

news2024/10/6 20:41:27

步骤0:你也可以参考这篇文章 :java实现geojson格式数据与shp文件相互转换

步骤1:引入引入geotools工具。

步骤2:编写工具类,获取shp的zip文件。

步骤3:编写工具类,解析shp文件成为jsonObject (geoJson)。

步骤4:拿到你的jsonObject,供你使用。


步骤1:引入geotools工具,笔者全网找半天也没在中文局域网里找到引入的方法,而是在公司同事的pom文件找到了:

<!--    shp文件解析 开始    -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.ejml</groupId>
            <artifactId>ejml-ddense</artifactId>
            <version>0.39</version>
        </dependency>
        <dependency>
            <groupId>org.ejml</groupId>
            <artifactId>ejml-core</artifactId>
            <version>0.39</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-data</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-metadata</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>19.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>javax.measure</groupId>
            <artifactId>jsr-275-1.0-beta</artifactId>
            <version>2</version>
        </dependency>
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.13</version>
        </dependency>
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!--    shp文件解析 结束    -->

你也可以参考来引入geotools:Maven中GeoTools的引入 - Maven 的 repository 与 mirror


步骤2:编写工具类,编写获取shp的zip文件的方法getFeatureCollectionByShpFile()。(该方法是为了将shp的zip压缩包解析后拿到FeatureCollection集合,其中需要自定义的 ZipUtil 解压到随机文件夹)

ShapeFileUtil工具类:

public class ShapeFileUtil {
    /*
     * @param zipFile: 压缩包文件地址
      * @return FeatureCollection
     * @author pangshicheng
     * @description 解析shp压缩包,并返回解析出的 FeatureCollection
     * @date 2023/7/18 16:02
     */
    public static FeatureCollection getFeatureCollectionByShpFile(File zipFile) throws IOException {
        try {
            String tempDir = FileUtil.getTempDirPath();
            File shapeDir = new File(tempDir + File.separator + new Date().getTime());
            shapeDir.mkdir();
            List<String> files = ZipUtil.unZipFiles(zipFile, shapeDir.getPath() + File.separator);
            String shapFileName = "";
            for (String fileName : files) {
                String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
                if ("shp".equals(suffix)) {
                    shapFileName = fileName;
                }
            }
            File shapeFile = new File(shapFileName);
            List<SimpleFeature> list = new ArrayList<>();
            Map<String, Object> shapeFileParams = new HashMap();
            shapeFileParams.put("url", shapeFile.toURI().toURL());
            // 设置编码
            shapeFileParams.put("charset", "GBK");
            DataStore dataStore = DataStoreFinder.getDataStore(shapeFileParams);
            if (dataStore == null) {
                throw new RuntimeException("couldn't load the damn data store: " + shapeFileParams);
            }
            String typeName = dataStore.getTypeNames()[0];
            FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
            Filter filter = Filter.INCLUDE;
            FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures(filter);
            return collection;
        }catch (Exception e){
            throw e;
        }
    }
}

ZipUtil工具类:

/**
 * @author soulmate丶
 * @date 2021-10-26
 */
public class ZipUtil {

    private static final Logger log = LoggerFactory.getLogger(ZipUtil.class);
    /**
     * 保存zip文件到本地并调用解压方法并返回解压出的文件的路径集合
     *
     * @param file 文件
     * @return list //解压出的文件的路径合集
     */
    private static String zipPath = "f:/shpfile/";//zip根路径

    /**
     * zip解压
     *
     * @param srcFile     zip源文件
     * @param destDirPath 解压后的目标文件夹
     * @return list 解压文件的路径合集
     * @throws RuntimeException 解压失败会抛出运行时异常
     */
    public static List<String> unZipFiles(File srcFile, String destDirPath) throws RuntimeException {
        List<String> list = new ArrayList<>();
        long start = System.currentTimeMillis();
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
        }
        // 开始解压
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(srcFile, Charset.forName("GBK"));
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                log.info("解压" + entry.getName());
                // 如果是文件夹,就创建个文件夹
                if (entry.isDirectory()) {
                    String dirPath = destDirPath + File.separator + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                } else {
                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + File.separator + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
                    log.info(destDirPath + entry.getName());
                    list.add(destDirPath + entry.getName());
                    if (!targetFile.getParentFile().exists()) {
                        log.info("父文件不存在");
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    InputStream is = zipFile.getInputStream(entry);
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    // 关流顺序,先打开的后关闭
                    fos.close();
                    is.close();
                }
            }
            long end = System.currentTimeMillis();
            log.info("解压完成,耗时:" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("unzip error from ZipUtils", e);
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }

    /**
     * @param filePath 临时文件的删除
     *                 删除文件夹里面子目录
     *                 再删除文件夹
     */
    public static void deleteFiles(String filePath) {
        File file = new File(filePath);
        if ((!file.exists()) || (!file.isDirectory())) {
            log.info("file not exist");
            return;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (filePath.endsWith(File.separator)) {
                temp = new File(filePath + tempList[i]);
            } else {
                temp = new File(filePath + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                deleteFiles(filePath + "\\" + tempList[i]);
            }
        }
        // 空文件的删除
        file.delete();
    }
}


步骤3:在相同工具类编写方法shpToGeoJson(),解析shp文件成为jsonObject (geoJson)。

/**
     * @param zipFile:
      * @return JSONObject
     * @author pangshicheng
     * @description 通过shp压缩文件,将其转换为GeoJson格式
     * @date 2023/7/18 16:04
     */
    public static JSONObject shpToGeoJson(File zipFile) throws IOException {
        FeatureJSON fjson = new FeatureJSON();
        JSONObject geoJsonObject=new JSONObject();
        geoJsonObject.put("type","FeatureCollection");
        try {
            // 获取FeatureCollection
            FeatureCollection collection = getFeatureCollectionByShpFile(zipFile);

            FeatureIterator iterator = collection.features();
            List<JSONObject> array  = new ArrayList<JSONObject>();
            //遍历feature转为json对象
            while (iterator.hasNext()) {
                SimpleFeature feature = (SimpleFeature) iterator.next();
                StringWriter writer = new StringWriter();
                fjson.writeFeature(feature, writer);
                String temp = writer.toString();
                byte[] b = temp.getBytes("iso8859-1");
                temp = new String(b, "gbk");
                JSONObject json = JSONObject.parseObject(temp);
                array.add(json);
            }
            iterator.close();
            //添加到geojsonObject
            geoJsonObject.put("features",array);
            iterator.close();

        }catch (Exception e){
            throw e;
        }
        return geoJsonObject;
    }

步骤4:拿到你的jsonObject,供你使用。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/766938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

6.7Jmeter5.1,非GUI模式,通过命令行传递线程数和运行时间

原创文章&#xff0c;谢绝转载。 一、前提 本次做性能测试&#xff0c;需求是需要在Linux下的非GUI模式下执行。但用命令行执行时&#xff0c;线程数需要改变&#xff0c;为了执行方便&#xff0c;不需要每次都在脚本中修改线程数&#xff0c;那么线程数都需要通过参数传递&…

如何使用自有数据微调ChatGLM-6B

构建自己的数据集 数据格式&#xff1a;问答对 官网例子 ADGEN 数据集任务为根据输入&#xff08;content&#xff09;生成一段广告词&#xff08;summary&#xff09;。 { "content": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*衣样式#衬衫*衣袖型#泡泡袖…

【雕爷学编程】Arduino动手做(22)——8X8 LED点阵MAX7219屏2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#xff0c;这…

AI图像生成无需代码连接集简云数据表的方法

1 场景描述 人工智能的出现&#xff0c;各个领域都开始尝试将AI作为提高工作效率的必备工具。除了AI对话等&#xff0c;越来越多的AI图像生成工具也出现在市场上。这些AI图像生成工具可以自动创建惊人的图像、艺术作品和设计&#xff0c;从而帮助设计师和创意人员更快速地实现其…

下个月要备多少货?伙伴云零代码进销存系统让您一目了然

大量企业的商业模式是销售实体商品&#xff0c;他们需要进销存系统来帮助企业管理好采购、销售、仓储的业务流程&#xff0c;从而更高效稳定的获得利润&#xff0c;因此进销存是企业的核心业务场景。来看看伙伴云零代码进销存系统如何精准计算进货出货数量&#xff0c;让中小企…

unable to get local issuer certificate (_ssl.c:992)‘)]

操作系统mac os python 版本 python3.11 import edge_tts import asyncio TEXT "how are you"print(TEXT) voice zh-CN-YunxiNeural output 4.mp3 rate -4% volume 0% async def my_function():tts edge_tts.Communicate(text TEXT,voice voice,rate rate…

上海汽配IPO上会在即:由镇政府控股,募资还要偿还银行贷款?

近日&#xff0c;上海证券交易所披露的信息显示&#xff0c;上海汽车空调配件股份有限公司&#xff08;以下简称“上海汽配”&#xff09;将于7月21日接受上市委审议。据贝多财经了解&#xff0c;上海汽配已于7月13日更新了招股书&#xff08;上会稿&#xff09;。 本次冲刺IPO…

学Python编程为什么会对学好数学有帮助呢?

Python编程和数学有什么关系呢&#xff1f;Python的起源是怎样的呢&#xff1f; 我们先来简单认识一下Python&#xff0c;和Python交个朋友。 Python的全拼是P—Y—T—H—O—N&#xff0c;发音是Python&#xff0c;汉语解释是蟒蛇的意思。 我们再来看Python的图标&#xff0c…

STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现)

目录 模块选择 编程环境 MLX90614基本原理 通信协议&#xff08;SMBus通信&#xff0c;类IIC通信&#xff09; 代码实现 STM32与模块之间接线表 1.标准库实现温度采集 2.HAL库实现温度采集 模块选择 STM32F103C8T6 MLX90614 非接触式红外测温传感器 编程环境 KEIL5&…

了解交换机接口的链路类型(access、trunk、hybrid)

上一个章节中讲到了vlan的作用及使用&#xff0c;这篇了解一下交换机接口的链路类型和什么情况下使用 vlan在数据包中是如何体现的&#xff0c;在上一篇的时候提到测试了一下&#xff0c;从PC1去访问PC4的时候&#xff0c;只从E0/0/2发送给了E0/0/3这是&#xff0c;因为两个接…

手把手GDB调试

确保你的程序有可调式的信息 使用gcc编译一个程序 ,带上一些额外的参数 -o0 -g-o0 &#xff1a;避免编译器优化&#xff0c;使用最低的优化等级&#xff0c;默认的编译选项 -g &#xff1a;生产调试信息 如果你已经有一个工程demo&#xff0c;使用cmake时注意使用Debug模式&…

Java使用poi-tl生成word文档添加超链接及添加多个超链接情况

首先是生成单个超链接情况&#xff0c;很简单 就是通过字符替换就行&#xff0c;但是替换的value格式是 TextRenderData data.put("attachment",Texts.of("文件名").link("http://wenjianlj文件路径.com").create()); 就是在替换的data&#…

spring复习:(39)注解方式的ProxyFactoryBean

一、定义接口 package cn.edu.tju.study.service;public interface MyService {void myMethod(); }二、定义实现类&#xff1a; package cn.edu.tju.study.service;public class MyServiceImpl implements MyService{Overridepublic void myMethod() {System.out.println(&qu…

认识一个失意的李白:如何制作一个人物生平二维码?

电影《长安三万里》的火爆&#xff0c;又一次唤醒了我们对大唐盛世的憧憬和向往。 飞流直下的瀑布、洒落床前的月光、花间独酌的美酒、胡天八月的大雪、越过青天的白鹭、长河孤烟的大漠、钟鼓馔玉的宴会……每每读起&#xff0c;那景象如在眼前。 对于一代又一代读着唐诗、听…

小程序一码跳多端的实现架构。。。

以常用的小程序&#xff0c;微信&#xff0c;支付宝为例&#xff0c; 现在要实现一个二维码&#xff0c;通过微信扫跳转微信小程序&#xff0c;通过支付包扫&#xff0c;跳转支付宝小程序&#xff0c;&#xff08;其他小程序也如此&#xff09; 实现思路&#xff0c;H5页面周转…

社区生鲜超市数字化经营怎么做?社区生鲜超市系统一览

社区生鲜超市是一种以货架自助的形式、结合现代超市经营理念&#xff0c;来售卖果蔬、肉类、水产、粮油、熟食等生鲜产品的一种零售形式&#xff0c;通常为小规模的连锁生鲜超市、专营店&#xff0c;主要服务于一个社区、街区等。目前&#xff0c;社区生鲜超市通常拥有较好的区…

【数据结构】二叉树详解(1)

⭐️ 前言 ✨ 二叉树的概念性质 ⭐️ 二叉树链式结构的实现 结构定义&#xff1a; #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int BinaryTreeDataType;typedef struct BinaryTreeNode {BinaryTreeDataType value;struct Binary…

如何克服Leetcode做题的困境

文章目录 如何克服Leetcode做题的困境问题背景克服困境的建议实践与理论结合切忌死记硬背分析解题思路不要过早看答案迭代式学习寻求帮助坚持与耐心查漏补缺 结论 如何克服Leetcode做题的困境 问题背景 明明自觉学会了不少知识&#xff0c;可真正开始做Leetcode题目时&#x…

用WooCommerce创建一个多用户商城系统和多供应商市场

线上市场是下一波数字化商务。2020 年&#xff0c;超过60% 的线上支出是通过数字市场发生的。人们喜欢从市场上购物&#xff0c;因为它们使购物变得容易。出于同样的原因&#xff0c;企业喜欢通过它们进行销售。通过多用户商城系统和多供应商WooCommerce商城设置&#xff0c;每…

Vue3结果(Result)

可自定义设置以下属性&#xff1a; 结果的状态&#xff0c;决定图标和颜色&#xff08;status&#xff09;&#xff0c;类型&#xff1a;‘success’|‘error’|‘info’|‘warn’|‘404’|‘403’|‘500’&#xff0c;默认&#xff1a;‘info’标题文字&#xff08;title&…