Ganos H3地理网格能力解析与最佳实践

本文涉及的产品
对象存储 OSS,20GB 3个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Ganos H3地理网格是一种基于六边形结构的高效地理空间数据处理技术,适用于物流、社交网络、数据分析及应急响应等多种场景。Ganos H3利用独特的六边形网格体系实现更均匀的数据分布和固定邻居关系,优化了空间数据分析、路径规划等功能。Ganos地理网格引擎支持GeoSOT和H3两种网格,具备丰富的打码方式、高性能查询及聚合分析能力,并能与几何和栅格数据融合,大幅提升了数据处理效率和存储成本效益。借助Ganos H3,企业和开发者可以更好地管理和利用地理空间数据,提高位置相关决策的准确性和效率。

关于Ganos H3地理网格
地理网格是一种再现地球表面的多边形网格单元集合,可以用于表示地物在地理空间中的位置信息,融合其他各类时空数据。地理网格计算一般由粗到细,逐级地分割地球表面,将地球曲面用一定大小的多边形网格进行近似模拟,其目标是将地理空间的定位和地理特征的描述一体化,并将误差范围控制在网格单元的范围内。每个网格单元都会进行编码,网格与编码是一一对应的。三维地理网格不只考虑经纬度,还把高度维纳入剖分和编码范围。
Ganos地理网格引擎目前涵盖GeoSOT和H3两种地理网格。GeoSOT是我国提出的一套地球空间剖分理论,并在此基础上发展出的一种离散化、多尺度区域位置标识体系(关于GeoSOT网格的最佳实践可参考Ganos地理网格引擎支撑无人机路径规划能力实践)。H3是Uber研发的一种覆盖全球表面的二维地理网格,采用了一种全球统一的、多层次的六边形网格体系来表示地球表面。H3设计独特之处在于其采用六边形结构,相较于传统的四边形或三角形网格,六边形网格具有更均匀分布、邻居关系固定且无方向性等优点,这使得在进行空间数据分析、路径规划、地理编码以及地理围栏等领域时,能够更加精确和高效地组织和查询地理空间数据。
利用Ganos地理网格的函数可以将不同的空间范围转换为网格编码,可以求出网格编码的空间范围、层级和父子网格。Ganos支持退化网格计算(如下图),即充分利用网格的层级关系,用更精简的网格组合对空间范围进行表达。此外,Ganos自研地理网格索引,可用于高效查询网格码以及加速聚合计算。

  1. Ganos H3地理网格能力解析
    3.1 业务场景
    H3 地理网格技术在诸多业务场景中得到广泛应用,主要包括:
    • 物流与出行服务:基于地理网格开展路线规划、区域覆盖分析、配送范围界定、热点区域发现等功能建设;
    • 数据分析:基于地理网格开展人口密度分析、移动用户行为分析、地理市场细分等大数据分析领域;
    • 物联网(IoT):面向智能城市、环境监测、资产追踪等需要实时监控的数据,基于地理网格进行监测数据空间分布分析的场景;
    • 社交网络:基于地理网格构建面向位置服务(LBS)、好友位置分享、事件通知等社交场景的应用;
    • 应急响应与公共服务:基于地理网格开展灾害分布分析、灾害预警热力、应急资源分布、紧急救援区域划分等;
    总之,H3 网格技术为企业和开发者提供了一种强大的工具,能够更好地管理和利用地理空间数据,提高与位置相关的决策效率和准确性。
    3.2 能力解析
    Ganos H3地理网格包含网格输入/输出,网格父子关系判断,网格路径分析,网格查询等多种能力,地理网格还支持转为Ganos Geometry类型,与其它类型的空间数据进行联合分析。值得强调的是,Ganos H3地理网格也支持退化,用更精简的网格组合对空间范围进行表达,降低用户因打码带来的数据库存储成本。
    关于Ganos H3地理网格详细功能,可参见 Ganos地理网格用户手册。
  2. 最佳实践
    下面我们使用真实场景数据来介绍如何使用Ganos H3进行空间点数据的入库、打码、查询到最终显示等功能。这里我们选择的测试数据是Uber发布的2023年纽约出租车位置数据集FOIL进行测试。FOIL数据记录了纽约地区所有的出租车上下车的位置数据,详细信息参考。
    4.1 数据导入
    在使用Ganos H3前,需要先创建GeomGrid扩展,SQL如下:
    CREATE EXTENSION Ganos_GeomGrid CASCADE;
    GeomGrid中提供了h3grid字段类型,用于表示H3编码。下面的SQL语句创建了一个带有h3grid类型的数据表FOIL2013,这里字段h3_lev13代表我们使用的是第13层级的H3编码。H3不同层级网格具有不同分辨率,用户可以可以更具具体业务需求灵活定义。H3各个层级对应的空间分辨率请参考
    -- 创建表用来保存foil点数据,h3_lev13代表13级编码
    CREATE TABLE FOIL2013 (
    id text,
    lon float,
    lat float,
    h3_lev13 h3grid);
    FOIL文件是以csv文件格式保存的。用户可以通过编程方式从CSV中提取相关信息通过SQL入库,也可以通过FDW方式入库,这里我们使用Ganos FDW模块通过FDW方式实现数据快速入库。
    首先我们把目标文件上传到oss指定目录,比如这里我们文件路径为:
    • endpoint:oss-cn-hangzhou-internal.aliyuncs.com
    • bucket:dla-ganos-hz
    • path:FOIL/trip_data_1.csv
    首先我们创建Ganos FDW扩展
    CREATE EXTENSION ganos_fdw CASCADE;
    然后我们需要创建一个csvserver,负责管理csv文件,ak_id和ak_secret就是用户的OSS连接AK的id和secret信息,format为'CSV'代表管理的数据格式为CSV。
    CREATE SERVER csvserver
    FOREIGN DATA WRAPPER ganos_fdw
    OPTIONS (
    datasource 'OSS://@oss-cn-hangzhou-internal.aliyuncs.com/dla-ganos-hz/FOIL/trip_data_1.csv',
    format 'CSV' );
    CREATE USER MAPPING FOR CURRENT_USER SERVER csvserver OPTIONS (user '', password '');
    FDW服务创建成功后,我们就可以通过外表的形式,将OSS上的csv映射到数据库中作为一个普通表进行查询,详细SQL语句如下。这里我们只选择medallion、pickup_longitude、pickup_latitude三列数据,映射的外表名称为trip_data_1:
    CREATE FOREIGN TABLE trip_data_1 (
    medallion varchar,
    pickup_longitude varchar,
    pickup_latitude varchar)
    SERVER csvserver
    OPTIONS ( layer 'trip_data_1' );
    查询外表trip_data_1:
    SELECT FROM trip_data_1;
    结果如下:
    然后将外表数据导入到前面我们创建的FOIL3表中:
    INSERT INTO FOIL2013
    SELECT medallion as id ,cast (pickup_longitude as double precision) as lon, cast(pickup_latitude as double precision) as lat FROM trip_data_1;
    查询FOIL2013,可以看到CSV上的信息已经成功导入到FOIL2013表格中,后面我们就可以根据经纬度等位置信息进行打码了。
    SELECT
    FROM FOIL2013;
    4.2 对象打码
    数据入库后,我们可以对点数据进行打码。Ganos H3提供了多种编码方式,比如通过指定经纬度、标准H3字符串、Integer类型H3编码、二进制类型H3编码,以及直接从Point类型转换为H3等方式。详细内容请参考文档:ST_H3FromText,ST_H3FromInt,ST_AsH3Grid,ST_H3FromLatLng等。
    这里我们使用的是ST_H3FromLatLng函数,用户通过指定将经纬度和目标层级可以直接获得H3编码。比入下面SQL语句就是从FOIL表中的lat和lon字段,生成第13层级的H3编码,并保存在h3_lev13列中,并通过ST_AsText函数查询具体h3编码。
    -- Level 13
    UPDATE FOIL2013 SET h3_lev13 = ST_H3FromLatLng(lat,lon,13);
    --查询
    SELECT id,lon,lat,ST_AsText(h3_lev13) as h3 FROM FOIL2013 LIMIT 100;
    查询结果如下图:
    4.3 网格聚合
    使用网格的一个典型场景就是对空间数据按照格网码进行空间聚合统计分析,从而获取热力图等专题地图信息。比如下面我们就是根据h3_lev13列中的h3编码,从FOIL23表格中统计出每个网格内的点数量(count()):
    --按照h3_lev13进行统计
    CREATE TABLE h3_count_lev13 AS
    SELECT ST_AsText(h3_lev13) AS h3code,count(
    ) FROM FOIL2013 GROUP BY h3_lev13;
    -- 查询统计结果
    SELECT ST_AsText(h3_lev13), ST_AsText(geometry),count FROM h3_count_lev13 order by count desc;
    输出结果:
    4.4 网格查询
    Ganos H3提供了多种基于H3编码的操作,比如下面我们可以通过ST_GridDistance方法获取FOIL23中所有的与空间位置(40.71481749,-73.99100368)对应格网的距离小于10的格网点:
    SELECT * FROM foil2013
    WHERE
    ST_GridDistance(ST_H3FromLatLng(40.71481749,-73.99100368,13),h3_lev13)<10;
    输出结果如下:
    4.5 网格可视化
    Ganos支持像几何数据一样可视化H3网格,即可以把H3网格转化为矢量瓦片,再由前端渲染查看。Ganos提供了原生H3网格MVT函数和索引,用户可以很便捷地查询和可视化H3网格及其包含的统计信息。值得一提的是,Ganos支持可视化动态生成的H3网格,比如用户想可视化层级为10的H3网格,但是表格中并没有保存层级为10的H3网格,此时可以使用ST_AsMVT加ST_AsMVTGeom(ST_H3FromLatLng(lat, lon, 10), ...)的命令来动态生成层级为10的H3网格的可视化结果,但是在效率上会不如事先保存H3网格,因此下面主要介绍如何可视化保存在表格中的H3网格。
    创建H3网格的索引SQL指令如下(创建索引对可视化并不是必须的,但能有效提升可视化效率):
    CREATE INDEX ON h3_count_lev13 USING GIST(h3_lev13);
    下面的SQL指令是根据H3网格获取编号为(14,4826,6157)的矢量瓦片,该指令和获取基于矢量数据的矢量瓦片的指令基本一致。
    SELECT ST_AsMVT(tile) FROM
    (SELECT ST_AsMVTGeom(h3_lev13, ST_Transform(ST_TileEnvelope(14, 4826, 6157), 4326)) AS grid, count
    FROM h3_count_lev13
    WHERE h3_lev13 && ST_Transform(ST_TileEnvelope(14, 4826, 6157), 4326)) AS tile;
    下面的动图展示了在前端实时渲染在数据库端动态查询H3网格的矢量瓦片的结果,网格的颜色是根据网格对应的统计值动态决定的。前端部分只需要一个Python脚本和一个HTML文件,启动时只需要运行该Python脚本和打开浏览器输入localhost:5100即可看到结果。Python脚本会根据用户鼠标在地图上的位置和缩放层级自动生成相应的SQL查询发送给数据库,然后将数据库的查询结果显示在网页上。前端的具体代码见附录部分。
  3. 技术优势
    相比pg-h3等开源产品,Ganos H3具有如下技术优势:
    • 支持更加丰富的打码方式,比如用户可以直接将Ganos的点、线、面类型转换为H3编码
    • Ganos H3在打码效率和格网查询效率上都进行了大量性能优化。
    • Ganos H3支持与其他Ganos模型实现联合查询分析,比支持将几何(geometry)类型直接转换为h3编码,或者使用h3与栅格(raster)模型进行基于格网的像素统计等。
    • Ganos H3基于PolarDB底层的多态分层存储,可以实现基于OSS的海量数据点的打码与存储,显著降低存储成本。
  4. 总结
    本文重点介绍了Ganos H3地理网格的相关能力,并基于一个最佳实践介绍了如何使用H3地理网格进行矢量数据的聚合、空间关系判断与可视化。地理网格是移动对象相关应用场景的重要支撑,它与轨迹、矢量、栅格等数据类型融合之后可以带来十分巨大的业务价值与想象空间。Ganos作为全球首个支持移动对象(MOD)的数据库,相关能力已经在交通、物流、出行、汽车等多个客户侧得到有效验证。相较于传统中间键或业务代码实现的方式,Ganos从数据库系统最底层为大规模移动对象提供时空处理框架,计算效率与综合成本均有大规模改善。未来Ganos还将提供更多高效的面向移动对象的场景的库内原生分析能力,推动相关领域的空间信息应用全面走向“在线化”。
  5. 附录
    可视化前端Python脚本如下:
    from quart import Quart, send_file, render_template
    import asyncpg
    import io
    import re

    数据库连接参数

    CONNECTION = {"host": "YOUR-HOST-NAME-OR-IP", "port": PORT_NO, "database": "DATABASE_NAME",
           "user": "USER_NAME", "password": "PASSWORD"}
    

    目标表名/字段/ID

    TABLE = "h3_count_lev13"
    H3_COL = "h3_lev13"
    H3_GEOM_COL = "geometry"
    AGG_VAL_COL = "count"
    COL_SRID = 4326
    app = Quart(name, template_folder='./')
    @app.before_serving
    async def create_db_pool():
    app.db_pool = await asyncpg.create_pool(**CONNECTION)
    @app.after_serving
    async def close_db_pool():
    await app.db_pool.close()
    @app.route("/")
    async def home():
    sql = f'''
    SELECT ST_Extent(ST_Transform(ST_Envelope({H3_GEOM_COL}), 4326))
    FROM {TABLE};
    '''
    async with app.db_pool.acquire() as connection:
     box = await connection.fetchval(sql)
     box = re.findall('BOX\((.*?) (.*?),(.*?) (.*?)\)', box)[0]
     min_x, min_y, max_x, max_y = list(map(float, box))
     bounds = [[min_x, min_y], [max_x, max_y]]
     center = [(min_x + max_x) / 2, (min_y + max_y) / 2]
     return await render_template('./index.html', center=str(center), bounds=str(bounds))
    
    @app.route("/h3_mvt///")
    async def h3_mvt(z, x, y):
    sql = f'''
    SELECT ST_AsMVT(tile.*)
    FROM
    (SELECT ST_AsMVTGeom({H3_COL}, ST_Transform(ST_TileEnvelope($1,$2,$3),{COL_SRID}), 4096, 512, true) geometry,
    {AGG_VAL_COL} count
    
    FROM {TABLE}
    WHERE ({H3_COL} && ST_Transform(ST_TileEnvelope($1,$2,$3),{COL_SRID}))) tile'''
    async with app.db_pool.acquire() as connection:
     tile = await connection.fetchval(sql, z, x, y)
     return await send_file(io.BytesIO(tile), mimetype='application/vnd.mapbox-vector-tile')
    
    if name == "main":
    app.run(port=5100)
    index.html文件内容如下:
    <!DOCTYPE html>












当前网格计数:
0



相关文章
|
20天前
|
机器学习/深度学习 安全 大数据
揭秘!企业级大模型如何安全高效私有化部署?全面解析最佳实践,助你打造智能业务新引擎!
【10月更文挑战第24天】本文详细探讨了企业级大模型私有化部署的最佳实践,涵盖数据隐私与安全、定制化配置、部署流程、性能优化及安全措施。通过私有化部署,企业能够完全控制数据,确保敏感信息的安全,同时根据自身需求进行优化,提升计算性能和处理效率。示例代码展示了如何利用Python和TensorFlow进行文本分类任务的模型训练。
60 6
|
14天前
|
PHP 开发者 容器
PHP命名空间深度解析与最佳实践####
本文深入探讨了PHP中命名空间(namespace)的机制、应用场景及最佳实践,旨在帮助开发者有效避免命名冲突,提升代码的组织性和可维护性。通过实例讲解,本文将引导您理解如何在实际项目中灵活运用命名空间,以及如何遵循业界公认的最佳实践来优化您的PHP代码结构。 ####
|
12天前
|
PHP 开发者
PHP 7新特性深度解析及其最佳实践
【10月更文挑战第31天】本文将深入探讨PHP 7带来的革新,从性能提升到语法改进,再到错误处理机制的变革。我们将通过实际代码示例,展示如何高效利用这些新特性来编写更加健壮和高效的PHP应用。无论你是PHP新手还是资深开发者,这篇文章都将为你打开一扇窗,让你看到PHP 7的强大之处。
|
21天前
|
监控 安全 Serverless
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
50 1
|
24天前
|
监控 安全 Java
构建高效后端服务:微服务架构深度解析与最佳实践###
【10月更文挑战第19天】 在数字化转型加速的今天,企业对后端服务的响应速度、可扩展性和灵活性提出了更高要求。本文探讨了微服务架构作为解决方案,通过分析传统单体架构面临的挑战,深入剖析微服务的核心优势、关键组件及设计原则。我们将从实际案例入手,揭示成功实施微服务的策略与常见陷阱,为开发者和企业提供可操作的指导建议。本文目的是帮助读者理解如何利用微服务架构提升后端服务的整体效能,实现业务快速迭代与创新。 ###
58 2
|
1月前
|
存储 缓存 监控
深入解析:Elasticsearch集群性能调优策略与最佳实践
【10月更文挑战第8天】Elasticsearch 是一个分布式的、基于 RESTful 风格的搜索和数据分析引擎,它能够快速地存储、搜索和分析大量数据。随着企业对实时数据处理需求的增长,Elasticsearch 被广泛应用于日志分析、全文搜索、安全信息和事件管理(SIEM)等领域。然而,为了确保 Elasticsearch 集群能够高效运行并满足业务需求,需要进行一系列的性能调优工作。
84 3
|
2月前
|
安全 网络安全 开发工具
深入探索Git:全面解析Git的用法与最佳实践
深入探索Git:全面解析Git的用法与最佳实践
57 2
|
4天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
16 2
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
67 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
52 0

推荐镜像

更多