GeoServer系列-geojson保存mongodb乱码问题

2023-11-12

前言

基于前一篇文章GeoServer系列-通过mongodb发布geojson数据,业务上可将常见的地理文件统一为geojson保存到mongodb,方便统一维护和发布geoserver,这一篇将解决mongodb中属性中文乱码问题。

1,解决思路

  • 因为很多空间数据是以压缩包上传,解压后转为geojson文件可能会很大(我的400+MB的gdb压缩包转换为geojson变为2.2GB),所以采用逐行读取的方式降低内存消耗
  • 文件上传过程中多次涉及io操作:保存分片->合并分片->格式转换->坐标转换->保存为geojson,这个过程中都不需要设置编码方式,因为最后一步都是以geojson格式入库,所以只需要解决geojson乱码
  • 文件乱码的问题核心是读取方式与文件本身的编码方式不一致导致,比如用户文件是GBK编码,gdal是用ISO8859-1读取文件,读取geojson属性又是用utf-8就必然乱码,所以核心问题是找到文件原来的编码方式,它怎么编码我们用什么编码读取

2,逐行读取geojson保存mongodb

    /**
     * 保存geojson数据到mongodb
     *
     * @param filePath geojson全路径
     * @param collect  集合名 = 文件md5标识
     * @return 属性列表
     */
    public List<String> geojsonToMongodb(String filePath, String collect) throws IOException {
        List<String> titleList = new ArrayList<>();
        // 1. 读取 GeoJSON 文件,判断文件的编码方式确定读取编码
        String chart = ReadUtil.detectCharset(new File(filePath)).name();
        if("ISO-8859-1".equals(chart)){chart="GB2312";}
        FileInputStream inputStream = new FileInputStream(filePath);
        InputStreamReader inputStreamReader = null;
        inputStreamReader = new InputStreamReader(inputStream, Charset.forName(chart));
        //2. 连接 MongoDB ,如果集合已存在先清空
        mongoTemplate2.dropCollection(collect);
        mongoTemplate2.createCollection(collect);
        //3 创建2dsphere索引
        GeospatialIndex index = new GeospatialIndex("geometry");
        index.typed(GeoSpatialIndexType.GEO_2DSPHERE);
        mongoTemplate2.indexOps(collect).ensureIndex(index);
        //4逐行读取feature,并写入Mongodb
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line;
        int successNum = 0;
        int failNum = 0;
        while ((line = bufferedReader.readLine()) != null) {
            // 判断当前行是否为一个 feature
            if (line.trim().startsWith("{") && (line.trim().endsWith("},") || line.trim().endsWith("}"))) {
                // 将当前行转换为 JSONObject
                JSONObject feature = new JSONObject(line);
                //自定义属性追加上feature唯一ID(用于地图联动)和集合类型
                int pid = (int) feature.get("id");
                String type = feature.getJSONObject("geometry").get("type") + "";
                feature.getJSONObject("properties").put("id", pid).set("type", type);
                Document document = Document.parse(feature.toString());
                try {
                    mongoTemplate2.insert(document, collect);
                    successNum++;
                } catch (Exception e) {
                    //忽略某些异常的Feature
                    //log.error("mongodb插入geojson数据失败:{}", e.getCause().getMessage());
                    failNum++;
                }
                //保存属性数据(仅第一列即可)
                if (successNum == 1) {
                    JSONObject jsonObject = feature.getJSONObject("properties");
                    Set<String> sIterator = jsonObject.keySet();
                    for (String key:sIterator) {
                        titleList.add(key);
                    }
                }
            }
        }
        log.warn("插入geojson数据{},成功{}条,失败{}条", collect, successNum, failNum);
        bufferedReader.close();
        inputStreamReader.close();
        return titleList;
    }

某些字符编码存在包含关系,如
GB2312 是 ISO-8859-1 的子集, GB2312 中的所有字符都在 ISO-8859-1 中存在,但是 ISO-8859-1 中有一些 GB2312 中不存在的字符,这种情况需要特殊

3,获取文件的编码方式

import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;

public static Charset detectCharset(File file) throws IOException {
    CharsetDetector detector = new CharsetDetector();
    byte[] buffer = new byte[4096];
    try (FileInputStream input = new FileInputStream(file)) {
        int nread;
        while ((nread = input.read(buffer)) != -1) {
            detector.setText(buffer);
            CharsetMatch match = detector.detect();
            if (match != null) {
                return Charset.forName(match.getName());
            }
        }
    }
    return Charset.defaultCharset();
}
    <dependency>
        <groupId>com.ibm.icu</groupId>
        <artifactId>icu4j</artifactId>
        <version>72.1</version>
    </dependency>

4,查看所有编码方式

    @Test
    public void test(){
        Map<String, Charset> charsets = Charset.availableCharsets();
        for (Map.Entry<String, Charset> entry : charsets.entrySet()) {
            String name = entry.getKey();
            Charset charset = entry.getValue();
            System.out.println(name + ": " + charset.displayName() + ", " + charset.aliases());
        }
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GeoServer系列-geojson保存mongodb乱码问题 的相关文章

  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 如何使用 Java 和 Selenium WebDriver 在 C 目录中创建文件夹并需要将屏幕截图保存在该目录中?

    目前正在与硒网络驱动程序和代码Java 我有一种情况 我需要在 C 目录中创建一个文件夹 并在该文件夹中创建我通过 selenium Web 驱动程序代码拍摄的屏幕截图 它需要存储在带有时间戳的文件夹中 如果我每天按计划运行脚本 所有屏幕截
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O

随机推荐

  • 检测到“RuntimeLibrary”的不匹配项: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”

    来源 http blog csdn net wpc320 article details 8496957 生成错误 error LNK2038 检测到 RuntimeLibrary 的不匹配项 值 MT StaticRelease 不匹配值
  • Selenium成长之路-15设置等待时间

    为了保证运行的脚本正常加载 我们需要的是设置等待时间 具体有以下几种 sleep 设置固定等待时间 主要由time包提供 也可叫强制等待 也就是说不管页面是否加载完成 都会等待这些时间 代码如下 coding utf 8 from sele
  • Java Thread类简介说明

    转自 Java Thread类简介说明 下文讲述Thread类的简介说明 如下所示 线程Thread 通俗的讲就是一个程序的多个并行的运行分支 路径 线程Thread 是CPU执行调度的单位 一个进程内的所有线程可以共享进程的资源 内存 设
  • vue elementUI select下拉框设置默认值

    关于element select框默认值赋值不成功问题 注意两点 v model里面的数据和遍历出来value值数据类型不一样 例 item provinces类型是number province类型是String 类型不一样导致赋值不成功
  • yolo-车辆测距+前车碰撞预警(追尾预警)+车辆检测识别+车辆跟踪测速(原创算法-毕业设计)

    目录 前言 一 环境配置 二 车辆检测 实时跟踪测速算法及代码解读 1 主函数各参数含义 2 算法实现 3 核心代码 4 效果展示 三 跟车距离测量算法及代码解读 1 主函数各参数含义 2 算法实现 3 效果展示 四 前车碰撞预警 追尾预警
  • seo的1000+篇文章总结

    seo的1000 篇文章总结 本文收集和总结了有关seo的1000 篇文章 由于篇幅有限只能总结近期的内容 想了解更多内容可以访问 http www ai2news com 其分享了有关AI的论文 文章 图书 query 08 外链 07
  • 今日面试题-2022-2-7

    Java序列化 反序列化 Java序列化就是指将对象转换为字节序列的过程 反序列化是指将字节序列转换成目标对象的过程 什么情况需要Java序列化 当Java对象需要在网络上传输或者持久化存储到文件中时 序列化的实现 让类实现Serializ
  • mysql 所有列_mysql怎么查询表中所有列(字段)?

    mysql查询表中所有列的方法 1 通过 查询表的所有列 语法 SELECT FROM 表名 2 通过列出表的所有字段来查询表的所有列 语法 SELECT 字段列表 FROM 表名 MySQL 数据表是由行和列构成的 通常把表的 列 称为字
  • 使用sqlite时遇到的错误 read-only

    在模拟器上运行没有问题 在真机上报如下错误 Attempt to add read only file at path file localhost var mobile Applications A80208B7 36C8 4CD0 94
  • 【BZOJ3309】DZY Loves Math 解题报告

    BZOJ3309 DZY Loves Math Description 对于正整数 n 定义 f n 为 n 所含质因子的最大幂指数 例如 f 1960 f 2 3 5 1 7 2 3 f 10007 1 f 1 0 给定正整数 a b 求
  • 可以单机运行的ChatGLM-6B发布

    清华技术成果转化的公司智谱 AI 开源了 GLM 系列模型 ChatGLM 6B 这是一个支持中英双语的对话语言模型 基于 General Language Model GLM 架构 具有 62 亿参数 结合模型量化技术 用户可以在消费级的
  • Qt 学习:comboBox编程时使用currentIndexChanged老是出现 assert failure错误

    Qt5 学习新手 所以用comboBox的 indexChanged槽时不知为何总是出现 ASSERT failure 错误 在程序中由于还使用了QList的对象 起初以为是它出了问题 反复检查也没有 后来在网上搜了半天才发现原来是在另外一
  • 1.PCB设计流程

    1 设计流程 笔记参考了郭天祥的PCB学习视频 1 总流程 SCH设计 SCH仿真 生成网表 PCB设计 信号完整性分析 低速信号即低于50Mhz的信号 不需要信号完整性分析 文件存储及打印 PS 加工时要注意加工厂的制作能力 比如最小线宽
  • itunes备份和恢复速度一样吗_Mac技巧分享:如何从加密的iTunes备份中恢复数据?...

    为了增强iTunes备份的安全性 您可以在iTunes中选中 加密iPhone备份 选项 但是 如果您忘记 丢失或忘记了备份密码 则在取回密码之前 不能取消选中 加密iPhone备份 选项 现在 我们的数据恢复软件 PhoneRescue可
  • 经典算法-动态规划

    一 基本概念 动态规划过程是 每次决策依赖于当前状态 又随即引起状态的转移 一个决策序列就是在变化的状态中产生出来的 所以 这种多阶段最优化决策解决问题的过程就称为动态规划 二 基本思想与策略 基本思想与分治法类似 也是将待求解的问题分解为
  • c# datagridview合并单元格

    region 合并单元格的测试 private int nextrow null private int nextcol null private void dataGridView1 CellFormatting object sende
  • 程序员情感三部曲之程序员如何找女朋友

    我的公众号 码农之屋 id Spider1818 分享的内容包括但不限于 Linux 网络 云计算虚拟化 容器Docker OpenStack Kubernetes SDN OVS DPDK Go Python C C 编程技术等内容 欢迎
  • mysqldump备份恢复数据库

    备份单库 单表 mysqldump u username p dbname tbname gt filename sql 备份单库多表 mysqldump u username p dbname tbname1 tbname2 gt fil
  • python二级题库(百分之九十原题) 刷题软件推荐 第二套

    目录 一 选择题 二 基本操作 三 简单应用 四 综合应用 刷题软件 文末有联系方式 注明来意 一 选择题 1 下列叙述中正确的是 A 在栈中 栈中元素随栈底指针与栈顶指针的变化而动态变化 B 在栈中 栈顶指针不变 栈中元素随栈底指针的变化
  • GeoServer系列-geojson保存mongodb乱码问题

    前言 基于前一篇文章GeoServer系列 通过mongodb发布geojson数据 业务上可将常见的地理文件统一为geojson保存到mongodb 方便统一维护和发布geoserver 这一篇将解决mongodb中属性中文乱码问题 1