【GIS系列】挑战千万级数据:Java和Elasticsearch在GIS中的叠加分析实践

作者:后端小肥肠

创作不易,未经允许严禁转载。

目录

1. 前言

2. 叠加分析场景方案对比

2.1. Geotools

2.2. PostGIS

2.3. Elasticsearch

3. 基于ElastcSearch实现叠加分析代码实践

3.1. 开发环境搭建

3.1.1. 所需版本和工具

3.1.2. pom依赖

3.2. 数据导入

3.3. 返回结构设计

3.4. 核心代码讲解

3.4.1. 将面要素wkt转换为GeoPoint类型的数组

3.4.2. 编写叠加分析方法函数

3.5. 结果测试

4. 结语


1. 前言

在处理千万级图斑叠加分析时,传统的后端GIS工具,如Geotools和PostGIS,往往难以满足实时性和高效性的要求。在这一挑战背景下,引入Elasticsearch作为空间叠加查询的解决方案,成为了一种创新且高效的选择。本文将探讨如何利用Java和Elasticsearch实现GIS中的千万级图斑叠加分析,以项目场景为基础,通过对传统后端GIS工具与Elasticsearch的性能比较,旨在为读者展示Elasticsearch作为一种新兴的空间数据处理工具的价值和潜力,为解决类似问题的开发者提供新的思路和解决方案。

本文适合有Elasticsearch和GIS后台编程基础的jym,如本文对你有帮助和启示,请三连支持一下小肥肠~

2. 叠加分析场景方案对比

假设叠加分析的场景为求一个面要素下包含的点要素,点要素图层有1000万个点,要求在短时间内返回叠加分析结果以后端为JAVA的背景下,常用的叠加分析方案有Geotools,Postgis,ES,目前将从技术方案特点,性能,优缺点,以及处理千万级图斑的可行性这几个方面依次介绍这几种技术方案。

2.1. Geotools

  • 技术方案特点: Geotools是一个开源的Java GIS工具库,提供了丰富的地理信息处理功能。
  • 性能评估: 在处理大规模空间数据时,Geotools可能性能较差,因其设计更偏向于灵活性和功能的全面性,而不是针对大规模数据的优化。
  • 优缺点: Geotools拥有丰富的功能和灵活的定制性,但在处理千万级图斑等大规模数据时,可能表现不佳。
  • 处理千万级图斑的可行性:在处理大规模数据时可能性能较差,可能需要额外的优化和资源才能满足实时性和高效性的要求

2.2. PostGIS

  • 技术方案特点: PostGIS是一个基于PostgreSQL的空间数据库扩展,提供了丰富的空间分析功能。
  • 性能评估: PostGIS在处理大规模空间数据时性能较好,可以通过索引和优化查询来提高处理效率。
  • 优缺点: PostGIS具有成熟的空间数据处理功能和优秀的性能,但在某些情况下可能需要额外的硬件资源来支持高负载
  • 处理千万级图斑的可行性:PostGIS在处理大规模数据时性能较好,通过适当的索引和优化查询可以有效提高处理效率,但要在短时间内完千万级图斑成叠加分析可能存在一些限制,特别是在复杂的叠加条件或者硬件资源受限的情况下。

2.3. Elasticsearch

  • 技术方案特点

    • 分布式实时搜索与分析引擎: Elasticsearch是一个基于分布式架构的实时搜索和分析引擎,专注于快速、实时的数据处理和查询。
    • 地理空间支持: Elasticsearch通过地理空间索引和查询功能,能够有效地处理地理空间数据,包括点、线、面等要素。
    • 高度可扩展性: Elasticsearch具有良好的横向扩展能力,能够轻松地处理大规模数据,因此适合处理千万级图斑等大规模空间数据。
  • 性能评估

    • 实时性和高效性: Elasticsearch在处理大规模数据时表现出色,具有较快的响应速度和高效的查询性能,能够满足实时性和高效性的要求。
    • 水平扩展性: 通过横向扩展集群节点,Elasticsearch能够有效地处理大规模数据,保持良好的性能表现。
  • 优缺点

    • 优点:
      • 实时性高:Elasticsearch支持实时索引和查询,能够快速处理最新的空间数据。
      • 强大的查询功能:Elasticsearch提供丰富的查询语法和功能,能够灵活地满足各种空间分析需求。
      • 可扩展性强:Elasticsearch具有良好的横向扩展能力,能够轻松地处理大规模数据。
    • 缺点:
      • 学习曲线较陡:对于新手来说,可能需要一定时间来学习Elasticsearch的数据模型和查询语法。
      • 硬件资源需求较高:在处理大规模数据时,可能需要较多的硬件资源来支持高负载的查询请求。
  • 处理千万级图斑的可行性

    • 可行性: Elasticsearch在处理大规模数据时表现优异,尤其擅长于实时性和高效性要求较高的场景,因此对于处理千万级图斑是可行的选择。通过合适的索引设计和优化查询,Elasticsearch能够有效地处理千万级图斑数据,并提供快速准确的查询结果。

3. 基于ElastcSearch实现叠加分析代码实践

3.1. 开发环境搭建

3.1.1. 所需版本和工具
依赖版本
Spring Boot2.6.3
Java1.8以上
Elasticsearch7.9.3
3.1.2. pom依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <dependency>
        <groupId>org.locationtech.jts</groupId>
        <artifactId>jts-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

3.2. 数据导入

基于工具将点要素图层导入Elasticsearch,这里怎么导入的不细讲,相关资料可自行百度:

注意看Shape字段类型要如上图才能支持面包含点类型的叠加分析。 

3.3. 返回结构设计

{
    "code": 200,
    "status": "success",
    "message": "OK",
    "data": {
        "list": [
            {
                "name": "地类名称",
                "code": "地类编码",
                "count": 178,
                "hectares": 541213,
                "ares": 3243,
                "squareMetres": 32432
            }
        ]
    }
}

由返回结构可看出,我们需要返回点要素的name,code和面积属性(平方米,公亩,公顷)。

3.4. 核心代码讲解

3.4.1. 将面要素wkt转换为GeoPoint类型的数组
    private List<GeoPoint> parseWKTGeometry(String wkt) {
        List<GeoPoint> points = new ArrayList<>();
        GeometryFactory geometryFactory = new GeometryFactory();
        WKTReader reader = new WKTReader(geometryFactory);

        try {
            Geometry geometry = reader.read(wkt);
            if (geometry instanceof Polygon) {
                Polygon polygon = (Polygon) geometry;
                LinearRing ring = (LinearRing) polygon.getExteriorRing();
                Coordinate[] coordinates = ring.getCoordinates();
                for (Coordinate coord : coordinates) {
                    double lat = coord.y;
                    double lon = coord.x;
                    points.add(new GeoPoint(lat, lon));
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return points;
    }
3.4.2. 编写叠加分析方法函数
 public ResponseStructure overlayAnalysis(OverlayDTO overlayDTO) {
        try {
            if(StringUtils.isEmpty(overlayDTO.getGeometry())){
                return ResponseStructure.failed("空间范围不可为空");
            }
            String geometry=overlayDTO.getGeometry();
            // 1. 指定检索 Index
            SearchRequest request = new SearchRequest();
            request.indices(ALIAS);

            // 2. 指定检索方式
            SearchSourceBuilder builder = new SearchSourceBuilder();

            // 3. 解析 WKT 格式的多边形
            List<GeoPoint> points = parseWKTGeometry(geometry);

            // geoPolygonQuery 代表着的是多边形查询
            builder.query(QueryBuilders.geoPolygonQuery("Shape", points)).trackTotalHits(true).size(0);

            // 4. 添加聚合查询
            TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("code").field(FIELD_CODE)
                    .subAggregation(AggregationBuilders.sum("MJ").field("YJJBNTMJ")).size(500);
            builder.aggregation(termsAggregationBuilder);

            request.source(builder);

            // 5. 执行查询
            SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);

            // 6.1 输出总数
            long total = resp.getHits().getTotalHits().value;

            // 6.2 聚合结果
            List<DataVo> lists = new ArrayList<>();
            Terms terms = resp.getAggregations().get("code");
            List<? extends Terms.Bucket> buckets = terms.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                // 获取分组总面积
                Sum mj = bucket.getAggregations().get("MJ");
                Double sum = mj.getValue();
                log.info("面积:{}", sum);

                // 获取代码
                String code = bucket.getKeyAsString();
                log.info("代码:{}", code);
                QuickStatistics quickStatistics = quickStatisticsMapper.selectOne(new LambdaQueryWrapper<QuickStatistics>()
                        .eq(QuickStatistics::getCode, code).eq(QuickStatistics::getType, FIELD_CODE));

                // 如果大数据库查到的代码没有在 pg 库的数据字典中,忽略不统计
                if (quickStatistics == null) {
                    log.info("未统计的代码:{}", code);
                    continue;
                }

                String name = quickStatistics.getName();
                lists.add(new DataVo(name, code, bucket.getDocCount(), sum, sum / 100, sum / 10000));
            }

            JBNTVO jbntvo = new JBNTVO(lists);
            return ResponseStructure.success(jbntvo);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseStructure.failed("叠加分析异常");
        }
    }

上述方法使用Elasticsearch进行查询,根据指定的几何图形执行地理多边形查询,并添加聚合查询以计算特定区域内的指标数据。最后,它将查询结果进行处理,包括统计各个区域的指标数据和计算相关指标,然后封装成特定的VO对象返回。如果在执行过程中出现异常,则记录错误信息并返回相应的错误响应。 

3.5. 结果测试

由上图可知,只需要输入叠加面要素的wkt格式数据,便可在短时间内拿到叠加分析结果。 

4. 结语

本文以千万级图斑叠加分析为背景,首先对比了常规技术栈和ES的优缺点,最后以实际代码讲解了如何基于ES实现千万级图斑叠加分析,如有更好的想法欢迎在评论区留言进行讨论~

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

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

相关文章

基于数据驱动的自适应性小波构造(MATLAB)

以地震领域为例&#xff0c;时频变换能够刻画地震资料的时频特征&#xff0c;进而辅助地质构造解释。在各种时频分析工具中&#xff0c;连续小波变换CWT是描述地震资料时频特征的常用工具。选择合适的基小波是CWT的关键问题。对于不同类型的信号前人有针对性的设计了许多基小波…

Virtualbox中对SD卡进行格式化和分区

系统&#xff1a;Ubuntu 22.04.4 LTS 方法一&#xff1a;在虚拟机的ubuntu系统中使用fdisk命令方式分区&#xff0c;具体请参考&#xff1a; imx6ull - 制作烧录SD卡-CSDN博客 方法二&#xff1a;使用Ubuntu自带GUI工具Disks Disks相比命令行工具更加简单无脑&#xff0c;用…

esp8266刷micropython固件

硬件&#xff1a;ESP-01 1M FLASH 乐鑫官方刷写工具&#xff1a;https://www.espressif.com.cn/sites/default/files/tools/flash_download_tool_3.9.6_2.zip 最新micropython固件: flash<512:https://micropython.org/resources/firmware/ESP8266_GENERIC-FLASH_512K-20…

【智能制造1005】智能制造试点企业名单及工具变量数据,助力深入研究!

今天给大家分享的是国内顶级期刊金融研究2022年发表的论文《智能制造赋能企业创新了吗&#xff1f;——基于中国智能制造试点项目的准自然实验》使用到的重要数据集——智能制造试点企业名单以及该政策对应的工具变量数据。该论文以中国智能制造示范项目的推广为准自然实验&…

C语言基础:字符函数和字符串函数

重点介绍处理字符和字符串的库函数的使用和注意事项 求字符串长度&#xff08;strlen&#xff09;长度不受限制的字符串函数(strcpy strcat strcmp)长度受限制的字符串函数介绍(strncpy strncat strncmp)字符串查找(strstr strtok)错误信息报告(strerror) C语言中对字…

路由策略实验1

先把地址全部配通 对R1 对R2 对R4 对R3 对R5 对R6 对R7 然后起路由协议 对R1 对R2 对R3 对R4 对R5 对R6 对R7

Ubuntu——配置安装服务

目录 一、安装JDK 二、安装IntelliJ IDEA 三、安装Docker-ce 1.环境清理以免有遗留组件 2.安装Docker 3.测试 #检查版本 sudo cat /etc/issue 一、安装JDK Ubuntu提供了一个名为apt的软件包管理工具&#xff0c;通过它可以使用命令行的方式安装、更新和删除软件包。 使用…

C++ : 模板初阶

标题&#xff1a;C : 模板初阶 水墨不写bug 正文开始&#xff1a; C语言的问题 &#xff1a; 写不完的swap函数 在学习C语言时&#xff0c;我们有一个经常使用的函数swap函数&#xff0c;它可以将两个对象的值交换。 我们通常这样实现它&#xff1a; void swap(int t1,int t…

2024年西安交通大学程序设计竞赛校赛

2024年西安交通大学程序设计竞赛校赛 文章目录 2024年西安交通大学程序设计竞赛校赛D瑟莉姆的宴会E: 雪中楼I: 命令行(待补)J&#xff1a;最后一块石头的重量(待补)K: 崩坏&#xff1a;星穹铁道(待补)M&#xff1a;生命游戏N: 圣诞树 D瑟莉姆的宴会 解题思路&#xff1a; ​ …

基于Android Studio 实现的鲜花(购物)商城App--原创

一、高质量源码&#xff08;非开源&#xff09; 关注公众号&#xff1a;《编程乐学》 后台回复&#xff1a;24060201 二、项目演示视频 基于Android Studio 实现的鲜花商城App--原创 三、开发环境 四、设计与实现 1.启动页 启动页我们需要用到倒计时和跳转功能。 2.注册登录 …

Vue中引入elementUI中的container组件失效

1.不用修改官网中任何css或者html 2.按需引入&#xff0c;不是只是引入官网的就可以 import Vue from vue import Router from vue-router import HelloWorld from /components/HelloWorld import First from /components/views/First import Second from /components/views/…

多元联合分布建模 Copula python实例

多元联合分布建模 Copula python实例 目录 库安装 实例可视化代码 库安装 pip install copulas 实例可视化代码 import numpy as np import pandas as pd from copulas.multivariate import GaussianMultivariate# Generate some example data np.random.seed(42) data = …

反向配置教程

注意&#xff0c;Openai、Gemini、claude和pika接口在国内直连不通&#xff0c;都需要配置反向 一、配置openai反向 1、在海外宝塔添加反向 将海外宝塔升级到最新 在海外宝塔添加一个新站点&#xff08;可以解析一个域名来用&#xff0c;也可以用ip端口形式&#xff09; 打开…

大模型应用:Prompt-Engineering优化原则

1.Prompt-Engineering 随着大模型的出现及应用&#xff0c;出现了一门新兴“技术”&#xff0c;该技术被称为Prompt-Enginerring。Prompt Engineering即提示工程&#xff0c;是指在使用大语言模型时&#xff0c;编写高效、准确的Prompt(提示词)的过程。通过不同的表述、细节和…

安全风险 - 组件导出风险

在安全审查中关于组件导出风险是一种常见问题&#xff0c;不同组件都有可能遇到这种问题&#xff0c;而且从一定角度来看的话&#xff0c;如果涉及到三方业务&#xff0c;基本处于无法解决的场景&#xff0c;所以我们需要说明为何无法避免这种风险 组件导出风险能不能规避&…

设计模式(十)结构型模式---享元模式

文章目录 享元模式简介结构UML图具体实现UML图代码实现 享元模式简介 享元模式&#xff08;fly weight pattern&#xff09;主要是通过共享对象来减少系统中对象的数量&#xff0c;其本质就是缓存共享对象&#xff0c;降低内存消耗。享元模式将需要重复使用的对象分为两个状态…

Nginx配置详细解释:(2)events事件配置

在nginx核心配置文件conf/nginx.conf中&#xff0c;有全局配置&#xff0c;events模块&#xff0c;http模块&#xff0c;(http模块中有嵌套多个模块)。常见配置项&#xff0c; events模块中&#xff0c;如下图&#xff1a; events是nginx与用户之间处理事件的功能。 如单个wo…

selenium自动化介绍

文章目录 一、selenium原理 安装二、selenium使用1.创建浏览器对象&#xff0c;访问网址2.消除警告提示3.不显示浏览器中受控制字样4.防检测5.设置延时5.1强制延时5.2隐式延时 6.设置浏览器窗口大小 三、案例实战&#xff1a;百度搜索四、iframe标签五、案例实战&#xff1a;Q…

SpringBoot+百度地图+Mysql实现中国地图可视化

通过SpringBoot百度地图Mysql实现中国地图可视化 一、申请百度地图的ak值 进入百度开发者平台 编辑以下内容 然后申请成功 二、Springboot写一个接口 确保数据库里有数据 文件目录如下 1、配置application.properties文件 #访问端口号 server.port9090 # 数据库连接信息 spr…

【Vue】响应式特性

响应式&#xff1a;简单理解就是数据改变&#xff0c;视图会自动更新。 如何访问 和 修改 data中的数据&#xff08;响应式演示&#xff09; data中的数据, 最终会被添加到实例上 例如这里&#xff0c;app身上就会拥有msg属性&#xff0c;修改msg的值&#xff0c;界面的值也会…