小功能实现(十九)生成shp文件

引入依赖

		<!--shp文件相关工具-->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>

使用方法

工具类

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * com.moxi.mogublog.utils
 *
 * @author yanao
 * @description shape工具类
 * @date 2023-10-24 09:41
 **/

public class ShapeUtil {

    public static final String DEF_GEOM_KEY = "the_geom";

    public static final String DEF_ENCODE = "uft-8";

    /**
     * 图形信息写入shp文件。shape文件中的geometry附带属性类型仅支持String(最大255)、Integer、Double、Boolean、Date(只包含日期,不包含时间);
     * 附带属性的name仅支持15字符,多余的自动截取。
     * @param shpPath shape文件路径,包括shp文件名称 如:D:\data\tmp\test.shp
     * @param geomType 图形信息类型 Geometry类型,如Point.class、Polygon.class等
     * @param data 图形信息集合
     */
    public static void createShp(String shpPath, Class<?> geomType, List<Map<String, ?>> data) {
        try {
            createShp(shpPath, DEF_ENCODE, geomType, data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 图形信息写入shp文件。shape文件中的geometry附带属性类型仅支持String(最大255)、Integer、Double、Boolean、Date(只包含日期,不包含时间);
     * 附带属性的name仅支持15字符,多余的自动截取。
     * @param shpPath shape文件路径,包括shp文件名称 如:D:\data\tmp\test.shp
     * @param encode shp文件编码
     * @param geomType 图形信息类型 Geometry类型,如Point.class、Polygon.class等
     * @param data 图形信息集合
     */
    public static void createShp(String shpPath, String encode, Class<?> geomType, List<Map<String, ?>> data) {

        try {
            if (StringUtils.isEmpty(shpPath)) {
                throw new Exception("shp文件的路径不能为空,shpPath: " + shpPath);
            }

            if (StringUtils.isEmpty(encode)) {
                throw new Exception("shp文件的编码不能为空,encode: " + encode);
            }

            if (Objects.isNull(geomType)) {
                throw new Exception("shp文件的图形类型不能为空,geomType: " + geomType);
            }

            if (CollectionUtils.isEmpty(data)) {
                throw new Exception("shp文件的图形数据不能为空,data: " + data);
            }

            if (!data.get(0).containsKey(DEF_GEOM_KEY)) {
                throw new Exception("shp文件的图形数据中必须包含the_geom的属性,data: " + data);
            }

            //创建shape文件对象+
            File file = new File(shpPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            Map<String, Serializable> params = new HashMap<>();
            params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
            ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);

            //定义图形信息和属性信息
            ds.createSchema(builderFeatureType(geomType, CollectionUtils.isEmpty(data) ? null : data.get(0)));

            //设置编码
            Charset charset = Charset.forName(encode);
            ds.setCharset(charset);

            //设置Writer
            String[] typeName=ds.getTypeNames();
            FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

            for (Map<String, ?> map : data) {
                //写下一条
                SimpleFeature feature = writer.next();

                for (String key : map.keySet()) {
                    if (DEF_GEOM_KEY.equals(key)) {
                        feature.setAttribute(key, map.get(key));
                    } else {
                        feature.setAttribute(key.toUpperCase(), map.get(key));
                    }
                }
            }

            writer.write();
            writer.close();
            ds.dispose();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 构建Feature模板
     * @param geomType 图形信息类型 Geometry类型,如Point.class、Polygon.class等
     * @param data 图形信息具体的属性
     * @return featureType
     */
    public static SimpleFeatureType builderFeatureType(Class<?> geomType, Map<String, ?> data) {
        //定义图形信息和属性信息
        SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
        ftb.setCRS(DefaultGeographicCRS.WGS84);
        ftb.setName("shapefile");

        ftb.add(DEF_GEOM_KEY, geomType);

        if (MapUtils.isNotEmpty(data)) {
            for (String key : data.keySet()) {
                if (Objects.nonNull(data.get(key))) {
                    ftb.add(key.toUpperCase(), data.get(key).getClass());
                }
            }
        }

        return ftb.buildFeatureType();
    }

    /**
     * 压缩shape文件
     *
     * @param shpPath shape文件路径(包含shape文件名称)
     */
    public static void zipShapeFile(String shpPath) {
        try {
            File shpFile = new File(shpPath);
            String shpRoot = shpFile.getParentFile().getPath();
            String shpName = shpFile.getName().substring(0, shpFile.getName().lastIndexOf("."));

            String zipPath = shpRoot + File.separator + shpName + ".zip";
            File zipFile = new File(zipPath);
            InputStream input = null;
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            // zip的名称为
            zipOut.setComment(shpName);
            //自行调节需要的相关文件
            String[] shpFiles = new String[]{
                    shpRoot + File.separator + shpName + ".dbf",
                    shpRoot + File.separator + shpName + ".prj",
                    shpRoot + File.separator + shpName + ".shp",
                    shpRoot + File.separator + shpName + ".shx",
                    shpRoot + File.separator + shpName + ".fix"
            };

            for (int i = 0; i < shpFiles.length; i++) {
                File file = new File(shpFiles[i]);
                input = new FileInputStream(file);
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOut.write(temp);
                }
                input.close();
            }
            zipOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

具体使用

	//返回文件流
    public void exportCornerShp(String evid,List<Map<String,String>> cornerDatas, HttpServletResponse httpServletResponse) throws Exception{
        EvGimcheckTask evGimcheckTask=evGimcheckTaskMapper.selectById(evid);
        String projectCode=evGimcheckTask.getSubProjectCode();
        String designCode=evGimcheckTask.getDesignStageCode();

        String url = "C:\\Users\\admin\\Desktop\\test\\ceshi2222.shp";
        //设置wkt文本
		String str = "LINESTRING (116.21278950384274 39.90557982319698, 116.21177234433465 39.90610963061354, 116.21106912279264 39.90264172209895, 116.21399502548638 39.902612822554126, 116.21629305278306 39.905011479365406, 116.21278950384274 39.90557982319698)";
        org.locationtech.jts.geom.Geometry geom = WKTUtil.wktToGeom(str);
        //添加参数
        Map<String, Object> m = new HashMap<>();
        m.put(ShapeUtil.DEF_GEOM_KEY, geom);
        m.put("name", evGimcheckTask.getGimName());

        List<Map<String, ?>> data = new ArrayList<>();
        data.add(m);

        //将geometry写入shape文件
        ShapeUtil.createShp(url, "utf-8", org.locationtech.jts.geom.LineString.class, data);
        //压缩shape文件
        ShapeUtil.zipShapeFile(url);
        //下载shape压缩包
        try {
            String downFile = url.replace(".shp",".zip");
            java.io.File file = new File(downFile);
            String filename = file.getName();// 获取日志文件名称
            InputStream fis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            httpServletResponse.reset();
            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
            httpServletResponse.setContentType("application/x-msdownload");
            httpServletResponse.setCharacterEncoding("utf-8");
            httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("ceshi111.zip", "UTF-8"));
            OutputStream os = new BufferedOutputStream(httpServletResponse.getOutputStream());
            os.write(buffer);// 输出文件
            os.flush();
            os.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

生成文件

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

矩阵连乘问题

1、求解矩阵连乘问题。 要求: 分别用自底向上的动态规划方法和自顶向下的备忘录方法计算最优值并构造最优解&#xff0c;通过实例比较两种方法的结果和效率。 思路 1)寻找最优子结构&#xff1a; 此问题最难就在于此&#xff0c;对于乘积的任意位置加括号都会将序列在某个…

Java 基础学习(三)循环流程控制与数组

1 循环流程控制 1.1 循环流程控制概述 1.1.1 什么是循环流程控制 当一个业务过程需要多次重复执行一个程序单元时&#xff0c;可以使用循环流程控制实现。 Java中包含3种循环结构&#xff1a; 1.2 for循环 1.2.1 for循环基础语法 for循环是最常用的循环流程控制&#xff…

智慧公厕为高速服务区公厕做出的贡献

在现代社会&#xff0c;科技的飞速发展改变了人们的生活方式&#xff0c;也深刻影响着城市的基础设施和公共服务。而在这个数字化时代的背景下&#xff0c;智慧公厕作为城市智能化管理的一部分&#xff0c;为高速服务区公厕带来了一系列的创新和贡献&#xff0c;为旅客的出行提…

C++基础 -10- 类的构造函数

类的构造函数类型一 使用this指针给类内参数赋值 class rlxy {public:int a;rlxy(int a, int b, int c){this->aa;this->bb;this->cc;cout << "rlxy" << endl;}protected:int b;private:int c; };int main() {rlxy ss(10, 20, 30); }类的构造…

\n\r:解析java中的\r、\n、\r\n、\n\r的区别

1 \r 1.1 内容 回车符,将光标定义到当前行行首 1.2 在idea中测试 1.2.1 表现形式 在\r后有新内容时,会先删除之前以前存在过的文本,即只打印\r后面的内容 1.2.2 示例代码 package Work; public class Test05 { public static void main(String[] args) { System.…

docker-compose Install OrangeHRM

OrangeHRM 前言 OrangeHRM 是一个全面的人力资源管理(HRM) 系统,它包含任何企业所需的所有基本功能。OrangeHRM旨在支持任何规模的团队,包括初创企业、中小企业以及大型跨国组织。 OrangeHRM 提前条件 OrangeHRMdocker & docker-composer 安装or

会议预告 | 求臻医学受邀参加2023·Inno China 产业创新大会

INNO CHINA 中国产业创新大会聚焦于数据驱动产业变革升级、医疗科技与产业转型升级、企业数字化转型升级、产业服务生态构建及商业智能融合发展等领域。如今&#xff0c;已成为中国新兴科技、热门赛道行业论坛、创新成果展示、参与、共创的高维度学术与产业年度相聚的节日&…

使用vue-admin-template时,需要注意的问题,包括一定要去除mock.js注释

在使用vue-admin-template等前端框架时&#xff0c;如果你没有打算用他们的mock数据&#xff0c;在生产环境下一定要注释mock引用的代码&#xff0c;虽然它没有被调用&#xff0c;但是如果你不注释&#xff0c;就会被打包进去。 找到main.js&#xff0c;看如下代码&#xff1a…

搭建一个可以发送邮箱验证码的接口,内含前端处理 接口返回、请求处理

环境搭建 在node安装好的情况下&#xff08;一般vue环境有的node也有 没有可以使用winr回车输入node -v 有版本号则已经安装好 找一个空文件夹作为此项目文件夹 点击上面的地址栏输入cmd回车 输入npm init -y 再输入npm install nodemailer安装发送邮件的插件 环境配置 使用v…

C++学习之路(十一)C++ 用Qt5实现一个工具箱(增加一个进制转换器功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《时间戳转换功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 进制转换 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具…

苹果提醒事项怎么用?几个简单步骤就能学会!

苹果提醒事项可以帮助你轻松管理待办事项&#xff0c;让你更好地安排自己的时间和工作。但是&#xff0c;有些小伙伴可能对如何使用这个功能还有一些疑问。苹果提醒事项怎么用&#xff1f;不要担心&#xff0c;小编将为大家提供使用提醒事项的方法&#xff0c;帮助你学会如何使…

轻量级web开发框架:Flask本地部署及实现公网访问界面

轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面 文章目录 轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面前言1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 前言 本篇文章讲解如何…

应用在智能手环距离检测领域的数字红外接近检测模块

智能手环是现代人日常生活中的一种智能配件&#xff0c;可以帮助我们记录运动数据、监测身体健康状况等。然而&#xff0c;对于许多用户来说&#xff0c;关注的问题之一就是智能手环的有效距离和精准度。智能手环通过内置传感器收集数据并将其发送到手机或其他设备上进行处理。…

【C++ Primer Plus学习记录】do while循环

do while循环是出口条件循环。这意味着这种循环将首先执行循环体&#xff0c;然后再判定测试表达式&#xff0c;决定是否应继续执行循环。如果条件为false&#xff0c;则循环终止&#xff1b;否则&#xff0c;进入新一轮的执行和测试。这样的循环通常至少执行一次&#xff0c;因…

接口响应时长几十秒问题排查以及解决

目录 背景 解决方案 总结 背景 线上系统运行几年后&#xff0c;被项目上提bug&#xff0c;有些接口响应很慢&#xff0c;加载页面要几十秒 解决方案 1、步骤一&#xff0c;加索引 性能优化成本高&#xff0c;需要开发周期&#xff0c;临时方案先分析慢sql&#xff0c;通过增…

Hive数据库与表操作

文章目录 一、准备工作二、Hive数据库操作&#xff08;一&#xff09;Hive数据存储&#xff08;二&#xff09;创建数据库&#xff08;三&#xff09;查看数据库&#xff08;四&#xff09;修改数据库信息 一、准备工作 二、Hive数据库操作 &#xff08;一&#xff09;Hive数据…

根据端口查找进程

关闭kibana kibana自带命令 kibana没有提供关闭命令&#xff0c;通过命令 ps -ef|grep kibana查找不到kibana相关的信息。 可以通过进程暴露的端口来查找 netstat -anltp|grep 5601获取到进程号&#xff0c;然后kill掉进程 kill -9 进程号Docker管理Kibana 但是如果使用D…

数据库实验7

实验报告&#xff08;七&#xff09;数据更新 1、实验目的 &#xff08;1&#xff09; 掌握插入、更新和删除表数据的方法 &#xff08;2&#xff09; 掌握更新操作与子查询结合的用法 2、实验预习与准备 &#xff08;1&#xff09; Update&#xff0c;Delete&am…

随笔(持续更新)

随笔&#xff08;持续更新&#xff09; 1、某个网络有没有连通 要获取某个网站的ip地址&#xff0c;可以通过ping它的域名就可以得到IP地址 例如&#xff1a;我想获取百度的ip地址&#xff08;Windows环境&#xff09; C:\Users\tq>ping www.baidu.com正在 Ping www.a.s…

04、基于高斯分布的异常检测算法

04、基于高斯分布的异常检测算法原理与实践 开始学习机器学习啦&#xff0c;已经把吴恩达的课全部刷完了&#xff0c;现在开始熟悉一下复现代码。对这个手写数字实部比较感兴趣&#xff0c;作为入门的素材非常合适。 数据的严重偏斜往往会导致监督学习算法面临巨大的挑战——…