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

嚴華  金牌会员 | 2024-6-13 20:39:03 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 786|帖子 786|积分 2358

作者:后端小肥肠
  创作不易,未经答应严禁转载。
  目次
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.3Java1.8以上Elasticsearch7.9.3 3.1.2. pom依赖

  1. <dependencies>
  2.     <dependency>
  3.         <groupId>org.springframework.boot</groupId>
  4.         <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  5.     </dependency>
  6.     <dependency>
  7.         <groupId>org.locationtech.jts</groupId>
  8.         <artifactId>jts-core</artifactId>
  9.     </dependency>
  10.     <dependency>
  11.         <groupId>org.springframework.boot</groupId>
  12.         <artifactId>spring-boot-starter-web</artifactId>
  13.     </dependency>
  14. </dependencies>
复制代码
3.2. 数据导入

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

留意看Shape字段类型要如上图才能支持面包含点类型的叠加分析。 
3.3. 返回布局计划

  1. {
  2.     "code": 200,
  3.     "status": "success",
  4.     "message": "OK",
  5.     "data": {
  6.         "list": [
  7.             {
  8.                 "name": "地类名称",
  9.                 "code": "地类编码",
  10.                 "count": 178,
  11.                 "hectares": 541213,
  12.                 "ares": 3243,
  13.                 "squareMetres": 32432
  14.             }
  15.         ]
  16.     }
  17. }
复制代码
由返回布局可看出,我们需要返回点要素的name,code和面积属性(平方米,公亩,公顷)。
3.4. 核心代码讲解

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

  1.     private List<GeoPoint> parseWKTGeometry(String wkt) {
  2.         List<GeoPoint> points = new ArrayList<>();
  3.         GeometryFactory geometryFactory = new GeometryFactory();
  4.         WKTReader reader = new WKTReader(geometryFactory);
  5.         try {
  6.             Geometry geometry = reader.read(wkt);
  7.             if (geometry instanceof Polygon) {
  8.                 Polygon polygon = (Polygon) geometry;
  9.                 LinearRing ring = (LinearRing) polygon.getExteriorRing();
  10.                 Coordinate[] coordinates = ring.getCoordinates();
  11.                 for (Coordinate coord : coordinates) {
  12.                     double lat = coord.y;
  13.                     double lon = coord.x;
  14.                     points.add(new GeoPoint(lat, lon));
  15.                 }
  16.             }
  17.         } catch (ParseException e) {
  18.             e.printStackTrace();
  19.         }
  20.         return points;
  21.     }
复制代码
3.4.2. 编写叠加分析方法函数

  1. public ResponseStructure overlayAnalysis(OverlayDTO overlayDTO) {
  2.         try {
  3.             if(StringUtils.isEmpty(overlayDTO.getGeometry())){
  4.                 return ResponseStructure.failed("空间范围不可为空");
  5.             }
  6.             String geometry=overlayDTO.getGeometry();
  7.             // 1. 指定检索 Index
  8.             SearchRequest request = new SearchRequest();
  9.             request.indices(ALIAS);
  10.             // 2. 指定检索方式
  11.             SearchSourceBuilder builder = new SearchSourceBuilder();
  12.             // 3. 解析 WKT 格式的多边形
  13.             List<GeoPoint> points = parseWKTGeometry(geometry);
  14.             // geoPolygonQuery 代表着的是多边形查询
  15.             builder.query(QueryBuilders.geoPolygonQuery("Shape", points)).trackTotalHits(true).size(0);
  16.             // 4. 添加聚合查询
  17.             TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("code").field(FIELD_CODE)
  18.                     .subAggregation(AggregationBuilders.sum("MJ").field("YJJBNTMJ")).size(500);
  19.             builder.aggregation(termsAggregationBuilder);
  20.             request.source(builder);
  21.             // 5. 执行查询
  22.             SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);
  23.             // 6.1 输出总数
  24.             long total = resp.getHits().getTotalHits().value;
  25.             // 6.2 聚合结果
  26.             List<DataVo> lists = new ArrayList<>();
  27.             Terms terms = resp.getAggregations().get("code");
  28.             List<? extends Terms.Bucket> buckets = terms.getBuckets();
  29.             for (Terms.Bucket bucket : buckets) {
  30.                 // 获取分组总面积
  31.                 Sum mj = bucket.getAggregations().get("MJ");
  32.                 Double sum = mj.getValue();
  33.                 log.info("面积:{}", sum);
  34.                 // 获取代码
  35.                 String code = bucket.getKeyAsString();
  36.                 log.info("代码:{}", code);
  37.                 QuickStatistics quickStatistics = quickStatisticsMapper.selectOne(new LambdaQueryWrapper<QuickStatistics>()
  38.                         .eq(QuickStatistics::getCode, code).eq(QuickStatistics::getType, FIELD_CODE));
  39.                 // 如果大数据库查到的代码没有在 pg 库的数据字典中,忽略不统计
  40.                 if (quickStatistics == null) {
  41.                     log.info("未统计的代码:{}", code);
  42.                     continue;
  43.                 }
  44.                 String name = quickStatistics.getName();
  45.                 lists.add(new DataVo(name, code, bucket.getDocCount(), sum, sum / 100, sum / 10000));
  46.             }
  47.             JBNTVO jbntvo = new JBNTVO(lists);
  48.             return ResponseStructure.success(jbntvo);
  49.         } catch (Exception e) {
  50.             log.error(e.getMessage(), e);
  51.             return ResponseStructure.failed("叠加分析异常");
  52.         }
  53.     }
复制代码
上述方法使用Elasticsearch进行查询,根据指定的几何图形执行地理多边形查询,并添加聚合查询以计算特定区域内的指标数据。最后,它将查询效果进行处理,包括统计各个区域的指标数据和计算相关指标,然后封装成特定的VO对象返回。如果在执行过程中出现异常,则记录错误信息并返回相应的错误响应。 
3.5. 效果测试


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

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表