PolarDB 开源版 使用PostGIS 以及泰森多边形 解决 "零售、配送、综合体、教培、连锁店等经营"|"通信行业基站建设功率和指向" 的地理最优解问题

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: 1、以KFC为例, 全国有很多家KFC连锁店, 每个店应该辐射哪些小区商圈? 开了新店之后, 与之相邻的老店辐射商圈应该怎么调整? KFC需要根据辐射小区商圈来预定销量、配置食材、配置多大的门店、多少营业员? 2、配送业务, 根据网点分布, 如何合理化每个网点负责的片区, 使得配送效率最高, 成本最低? 每一个写字楼有且只有一种选择到某个网点的距离最近. 3、基站建设, 每个基站应该对每个方向的功率调多大, 才能整体最优的解决网络质量和覆盖率问题.以上其实都在回答一个问题: - 在有限的资源情况下, 如何整体最优的解决地理位置上的业务覆盖问题.

背景

PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.

本文将介绍PolarDB 开源版 使用PostGIS 以及泰森多边形 解决 "零售、配送、综合体、教培、连锁店等经营"|"通信行业基站建设功率和指向" 的地理最优解问题

测试环境为macOS+docker, PolarDB部署请参考下文:

业务介绍

与地理位置、距离相关的业务:

  • 配送
  • 零售业务O2O
  • 线下教培
  • 综合体
  • 基站
  • 连锁店

1、以KFC为例, 全国有很多家KFC连锁店, 每个店应该辐射哪些小区商圈?
开了新店之后, 与之相邻的老店辐射商圈应该怎么调整?
KFC需要根据辐射小区商圈来预定销量、配置食材、配置多大的门店、多少营业员?

2、配送业务, 根据网点分布, 如何合理化每个网点负责的片区, 使得配送效率最高, 成本最低?
每一个写字楼有且只有一种选择到某个网点的距离最近.

3、基站建设, 每个基站应该对每个方向的功率调多大, 才能整体最优的解决网络质量和覆盖率问题.

以上其实都在回答一个问题:

  • 在有限的资源情况下, 如何整体最优的解决地理位置上的业务覆盖问题.

简化为数学问题, 就是:

  • 以基站、零售店、配送站、连锁店等为离散点, 划分泰森多边形, 每个离散点负责一个多边形, 在这个多边形内的点距离多边形内的离散点最近. 因此离散点只需要负责好这个多边形即可, 这样获得的就是地理位置上的最优解.

例子

《在PostgreSQL中生成和查看泰森多边形 - Voronoi diagram - 最强大脑题目》

《使用 PolarDB 开源版 部署 PostGIS 支撑时空轨迹|地理信息|路由等业务》

接下来的内容将以上面这篇文章为例进行讲解:

以PolarDB 和postgis 为例

create extension postgis;

创建生成随机离散点的函数

参数1,2:经度取值范围    
参数3,4:维度取值范围    
参数5:生成多少个离散点    

create or replace function gen_rand_multipoint(numeric, numeric, numeric, numeric, int) returns geometry as $$    
declare    
  res text;    
begin    
  res := 'MULTIPOINT (';    
  for i in 1..$5 loop    
    res := res||$1+random()*($2-$1)||' '||$3+random()*($4-$3)||',';    
  end loop;    
  res := rtrim(res,',');    
  res := res||')';    
  return res::geometry;    
end;    
$$ language plpgsql strict;

举例

digoal=# select st_astext(gen_rand_multipoint(120,121,70,71,10));    
-[ RECORD 1 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
st_astext | MULTIPOINT(120.942558704875 70.0857633580454,120.821791284718 70.5374327567406,120.60653472133 70.7641549357213,120.966732177418 70.1589297447354,120.494935501367 70.5906278314069,120.999914915301 70.6718445569277,120.941853619181 70.6390802050009,120.022797878832 70.7509728162549,120.612626708578 70.7740727034397,120.310972961597 70.0668104588985,120.741411157884 70.2521727122366,120.031697474886 70.8502694196068,120.77547144331 70.7255614278838,120.18382552173 70.0531326876953,120.045804018155 70.279703093227,120.709843394347 70.9883627230301,120.365466451272 70.5316346790642,120.525795479771 70.9720011726022,120.295789614785 70.4925276571885,120.130930917338 70.7907251161523,120.083155489061 70.1308458326384,120.462569673546 70.0250091082416,120.769926037639 70.4853675523773,120.775981924497 70.3825527466834,120.259440256283 70.0869548860937,120.449363205582 70.0008514141664,120.33912759833 70.4810606804676,120.851120833773 70.1145990416408,120.206622108817 70.0349463559687,120.167731729802 70.2524261269718,120.314649449196 70.8775751241483,120.240788850002 70.6801159004681,120.409209803678 70.7665843297727,120.65211707307 70.7049994184636,120.259111986961 70.7830479904078,120.495724535082 70.3422674760222,120.913893823046 70.9582942086272,120.367276584264 70.6838198606856,120.443661761004 70.1432585087605,120.066372607369 70.7031020172872,120.230213394854 70.5157358134165,120.703953431919 70.5693409931846,120.996796493884 70.5550742656924,120.683940035291 70.2034186027013,120.590020621661 70.8516717650928,120.455844729673 70.9046700708568,120.729246889241 70.6966335796751,120.584785971325 70.1384566929191,120.463217909448 70.2369030443951,120.843456111848 70.7223298968747,120.019951034803 70.3391806469299,120.064597372897 70.9338448578492,120.297474855557 70.4318739576265,120.617664719 70.7411366165616,120.575132466387 70.6840373263694,120.444238634314 70.8053458617069,120.199773139786 70.1481920662336,120.374686854891 70.1965696341358,120.703266331926 70.0586268901825,120.399988236837 70.2932869540527,120.910298655275 70.8558329669759,120.19795702491 70.639545544982,120.552466546651 70.7827429967001,120.778002237901 70.0156844565645,120.019646041095 70.6214583497494,120.738014353439 70.0395970763639,120.960638996679 70.8026117263362,120.973441934213 70.2581138522364,120.234485683963 70.5911066532135,120.999250469264 70.8096181508154)

使用PostGIS生成随机离散点的泰森多边形

Synopsis    
geometry ST_VoronoiPolygons( g1 geometry , tolerance float8 , extend_to geometry );

用法如下

select st_astext(ST_VoronoiPolygons(x)) from gen_rand_multipoint(120,121,70,71,10) x;

使用PostGIS生成随机离散点的泰森多边形的边

Synopsis    
geometry ST_VoronoiLines( g1 geometry , tolerance float8 , extend_to geometry );

用法如下

select st_astext(ST_VoronoiLines(x)) from gen_rand_multipoint(120,121,70,71,10) x;

使用pgadmin,观察泰森多边形,离散点

1、建表,存储泰森多边形

create table tb (id serial, mp geometry, vp geometry, vl geometry, mp_vl geometry);

2、写入一些泰森多边形数据

insert into tb (mp,vp,vl,mp_vl)     
select x, ST_VoronoiPolygons(x), ST_VoronoiLines(x), st_union(x,ST_VoronoiLines(x)) from gen_rand_multipoint(120,121,70,71,10) x;    

insert into tb (mp,vp,vl,mp_vl)     
select x, ST_VoronoiPolygons(x), ST_VoronoiLines(x), st_union(x,ST_VoronoiLines(x)) from gen_rand_multipoint(120,121,70,71,100) x;    

insert into tb (mp,vp,vl,mp_vl)     
select x, ST_VoronoiPolygons(x), ST_VoronoiLines(x), st_union(x,ST_VoronoiLines(x)) from gen_rand_multipoint(120,121,70,71,1000) x;    

insert into tb (mp,vp,vl,mp_vl)     
select x, ST_VoronoiPolygons(x), ST_VoronoiLines(x), st_union(x,ST_VoronoiLines(x)) from gen_rand_multipoint(120,125,70,75,100) x;

3、使用pgadmin显示泰森多边形

几何数据

20190421_01_pic_003.jpg

离散点对应的泰森多边形的边(multiline对象)

20190421_01_pic_005.jpg

离散点对应的泰森多边形(multipolygon对象)(bound默认为一个BOX,包住所有离散点)

20190421_01_pic_006.jpg

离散点以及对应的泰森多边形的边

20190421_01_pic_004.jpg

放大后的离散点以及对应的泰森多边形的边

20190421_01_pic_007.jpg

4、将得到的泰森多边形multigeometry解析出来,每个多边形一条记录存储,为下一篇文档四色猜想做准备。

《PostgreSQL中的四色猜想(Four color theorem) - 最强大脑题目》

创建测试表,并写入1000个泰森多边形。

create table tc (id serial, poy geometry);    

insert into tc (poy) select ST_GeometryN(x,i) from     
  (select generate_series(1,ST_NumGeometries(x)) i, x     
    from ST_VoronoiPolygons(gen_rand_multipoint(120,121,70,71,1000)) x    
  ) t;

例子

digoal=# select st_astext(poy) from tc;    
-[ RECORD 1 ]--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
st_astext | POLYGON((120.0068907121 70.0827667811785,120.017136860027 70.1185103197699,120.024032512908 70.1163465285133,120.032180593165 70.1011610062082,120.033703815237 70.0870002751683,120.012202949892 70.0813630370411,120.0068907121    
 70.0827667811785))    
-[ RECORD 2 ]--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
st_astext | POLYGON((119.001530315262 70.1396284378468,119.001530315262 70.2071267817079,119.757509890494 70.2155274483723,119.788978615847 70.2125452904718,119.9209381714 70.1687296375826,120.017136860027 70.1185103197699,120.0068907121    
 70.0827667811785,119.952343492619 70.0692099186264,119.001530315262 70.1396284378468))    
-[ RECORD 3 ]--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
st_astext | POLYGON((119.781778114247 69.0017473017801,119.001530315262 69.0017473017801,119.001530315262 70.1396284378468,119.952343492619 70.0692099186264,120.008027433811 70.0545962635351,120.013949018811 70.0504765592871,120.03048513    
9271 70.0273653734516,120.039308399546 69.9936444173583,119.781778114247 69.0017473017801))    
-[ RECORD 4 ]--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
st_astext | POLYGON((120.080290328964 69.0017473017801,119.781778114247 69.0017473017801,120.039308399546 69.9936444173583,120.057510105642 70.0145600250777,120.122918984211 70.0308393983058,120.127907151293 70.0314308457492,120.13710363    
4016 70.0261242124239,120.153895004164 69.9966006333282,120.080290328964 69.0017473017801))    
..............

5、输入任意一个泰森多边形ID搜索与之相邻的泰森多边形。

select st_collect(tc.poy)   
from tc,   
  (select * from tc where id=80) t   
where st_intersects(tc.poy, t.poy)   
and GeometryType(ST_Intersection(tc.poy, t.poy)) <> 'POINT'   
;

20190421_01_pic_008.jpg

只有一个点相邻也会认为相邻,所以需要使用GeometryType过滤.

digoal=# select st_intersects(poyx, poyy), GeometryType(ST_Intersection(poyx, poyy)) from   
(values(  
  ST_MakePolygon(ST_GeomFromText('LINESTRING(1 2, 2 2, 2 3, 1 2)'))  
,  
  ST_MakePolygon(ST_GeomFromText('LINESTRING(2 2, 3 2, 3 3, 2 2)'))  
)) as t (poyx, poyy)  
;  
 st_intersects | geometrytype   
---------------+--------------  
 t             | POINT  
(1 row)

参考

https://en.wikipedia.org/wiki/Voronoi_diagram

https://baike.baidu.com/item/%E6%B3%B0%E6%A3%AE%E5%A4%9A%E8%BE%B9%E5%BD%A2

http://postgis.net/docs/manual-2.5/ST_VoronoiLines.html

http://postgis.net/docs/manual-2.5/ST_VoronoiPolygons.html

http://postgis.net/docs/manual-2.5/reference.html

https://stackoverflow.com/questions/21719941/postgis-convert-multipolygon-to-single-polygon

https://baike.baidu.com/tashuo/browse/content?id=d967b9032e228a4e4a39827e&fr=qingtian&lemmaId=3428661

《PostgreSQL中的四色猜想(Four color theorem) - 最强大脑题目》

《在PostgreSQL中生成和查看泰森多边形 - Voronoi diagram - 最强大脑题目》

《使用 PolarDB 开源版 部署 PostGIS 支撑时空轨迹|地理信息|路由等业务》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
SQL 关系型数据库 MySQL
开源新发布|PolarDB-X v2.4.2开源生态适配升级
PolarDB-X v2.4.2开源发布,重点完善生态能力:新增客户端驱动、开源polardbx-proxy组件,支持读写分离与高可用;强化DDL变更、扩缩容等运维能力,并兼容MySQL主备复制及MCP AI生态。
开源新发布|PolarDB-X v2.4.2开源生态适配升级
|
2月前
|
SQL 关系型数据库 MySQL
开源新发布|PolarDB-X v2.4.2开源生态适配升级
PolarDB-X v2.4.2发布,新增开源Proxy组件与客户端驱动,支持读写分离、无感高可用切换及DDL在线变更,兼容MySQL生态,提升千亿级大表运维稳定性。
574 24
开源新发布|PolarDB-X v2.4.2开源生态适配升级
|
4月前
|
人工智能 关系型数据库 MySQL
开源PolarDB-X:单节点误删除binlog恢复
本文由邵亚鹏撰写,分享了在使用开源PolarDB-X过程中,因误删binlog导致数据库服务无法启动的问题及恢复过程。作者结合实践经验,详细介绍了在无备份情况下如何通过单节点恢复机制重启数据库,并提出了避免类似问题的几点建议,包括采用高可用部署、定期备份及升级至最新版本等。
|
7月前
|
供应链 关系型数据库 分布式数据库
2025开源之夏火热报名|一起来设计PolarDB Dashboard
2025开源之夏正在火热报名中,PolarDB邀请全球学子参与云原生与Web开发的前沿项目。活动由中国科学院软件研究所发起,旨在鼓励高校学生通过实际开发维护开源软件,培养优秀开发者,推动开源生态发展。PolarDB项目聚焦设计与开发PolarDB-X Dashboard,要求掌握K8S Client-go和Web开发技术。参与者将根据项目难度获得税前8000至12000元人民币报酬,并获取结项证书。每位学生仅可申请一个项目,详情见官网。
2025开源之夏火热报名|一起来设计PolarDB Dashboard
|
存储 关系型数据库 MySQL
开源PolarDB- X|替换Opengemini时序数据场景下产品力校验
本文作者:黄周霖,数据库技术专家,就职于南京北路智控股份有限公司,负责数据库运维及大数据开发。
|
7月前
|
存储 Cloud Native 关系型数据库
PolarDB开源:云原生数据库的架构革命
本文围绕开源核心价值、社区运营实践和技术演进路线展开。首先解读存算分离架构的三大突破,包括基于RDMA的分布式存储、计算节点扩展及存储池扩容机制,并强调与MySQL的高兼容性。其次分享阿里巴巴开源治理模式,涵盖技术决策、版本发布和贡献者成长体系,同时展示企业应用案例。最后展望技术路线图,如3.0版本的多写多读架构、智能调优引擎等特性,以及开发者生态建设举措,推荐使用PolarDB-Operator实现高效部署。
379 3
|
7月前
|
SQL 关系型数据库 分布式数据库
PolarDB开源数据库入门教程
PolarDB是阿里云推出的云原生数据库,基于PostgreSQL、MySQL和Oracle引擎构建,具备高性能、高扩展性和高可用性。其开源版采用计算与存储分离架构,支持快速弹性扩展和100%兼容PostgreSQL/MySQL。本文介绍了PolarDB的安装方法(Docker部署或源码编译)、基本使用(连接数据库、创建表等)及高级特性(计算节点扩展、存储自动扩容、并行查询等)。同时提供了性能优化建议和监控维护方法,帮助用户在生产环境中高效使用PolarDB。
2245 21
|
7月前
|
Cloud Native 关系型数据库 分布式数据库
PolarDB开源:云原生数据库的新篇章
阿里云自研的云原生数据库PolarDB于2023年5月正式开源,采用“存储计算分离”架构,具备高性能、高可用及全面兼容性。其开源版本提供企业级数据库解决方案,支持MySQL、PostgreSQL和Oracle语法,适用于高并发OLTP、核心业务系统等场景。PolarDB通过开放治理与开发者工具构建完整生态,并展望更丰富的插件功能与AI集成,为中国云原生数据库技术发展贡献重要力量。
594 17
|
7月前
|
存储 关系型数据库 分布式数据库
PolarDB开源进阶篇:深度解析与实战优化指南
PolarDB是阿里云开源的云原生数据库,采用计算-存储分离架构,结合高性能共享存储与Parallel Raft多副本一致性协议,实现微秒级延迟和卓越性能。本文深入解析其架构设计,涵盖智能调度层、性能优化技巧(如查询优化器调优和分布式事务提升)、高可用与容灾配置、扩展功能开发指南以及监控运维体系。同时,通过电商平台优化案例展示实际应用效果,并展望未来演进方向,包括AI结合、多模数据库支持及Serverless架构发展。作为云原生数据库代表,PolarDB为开发者提供了强大支持和广阔前景。
443 16
|
10月前
|
关系型数据库 分布式数据库 数据库
喜报|PolarDB开源社区荣获“2024数据库国内活跃开源项目”奖
喜报|PolarDB开源社区荣获“2024数据库国内活跃开源项目”奖
201 1

相关产品

  • 云原生数据库 PolarDB