PostgreSQL PostGIS 的5种空间距离排序(knn)算法

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

标签

PostgreSQL , PostGIS , operator , ops , knn


背景

PostgreSQL GiST索引支持排序接口,可以支撑空间、标准、数组、文本向量、文本等类型的排序。

分别表示:

1、给定一空间位置,按空间距离排序输出

2、给定一数组、全文检索值、字符串,按数组、全文检索、字符串相似度排序输出

3、给定一标准类型的值,按标准类型的距离排序

数据库目前支持哪些排序操作符,可以参考:《PostgreSQL 如何确定某个opclass支持哪些操作符(支持索引),JOIN方法,排序》

postgres=# select oprleft::regtype,oprright::regtype,oprresult::regtype,oprname,oprkind,oprcode from pg_operator where oid in (select amopopr  from pg_amop where amopsortfamily<>0);    
           oprleft           |          oprright           |    oprresult     | oprname | oprkind |              oprcode                 
-----------------------------+-----------------------------+------------------+---------+---------+------------------------------------  
 point                       | point                       | double precision | <->     | b       | point_distance  
 circle                      | point                       | double precision | <->     | b       | dist_cpoint  
 polygon                     | point                       | double precision | <->     | b       | dist_polyp  
 geometry                    | geometry                    | double precision | <->     | b       | geometry_distance_centroid  
 geometry                    | geometry                    | double precision | <#>     | b       | geometry_distance_box  
 geometry                    | geometry                    | double precision | <<->>   | b       | geometry_distance_centroid_nd  
 geometry                    | geometry                    | double precision | |=|     | b       | geometry_distance_cpa  
 geography                   | geography                   | double precision | <->     | b       | geography_distance_knn  
  
oprcode是这个操作符对应的函数,要知道操作符的算法,可以下载postgis源码根据函数找到其C代码。

安装了PostGIS后,对于空间排序,目前支持5种算法

PostGIS 空间排序算法

1、2D平面,两个对象实际距离

<-> — Returns the 2D distance between A and B.    

pic

pic

2、计算两条有效轨迹类型的距离(如果两个轨迹没有交集, 返回空)

|=| — Returns the distance between A and B trajectories at their closest point of approach.  

pic

pic

3、2D平面,两个对象bound box实面的距离(所以如果BOUND BOX与另一对象 相交,包含,说明距离为0)

<#> — Returns the 2D distance between A and B bounding boxes.    

pic

pic

4、与1类似,多维对象,返回两个bound box 中心点的距离

<<->> — Returns the n-D distance between the centroids of A and B bounding boxes.  

5、与3类似,多维对象,返回两个bound box 实体的距离

<<#>> — Returns the n-D distance between A and B bounding boxes.  

例子

1、点和线段的实际距离

postgres=# select st_setsrid(st_makepoint(1,2),4326) <-> st_setsrid(ST_MakeLine(ST_MakePoint(0,0.9), ST_MakePoint(3,4)),4326);  
      ?column?        
--------------------  
 0.0463614285010702  
(1 row)  

2、点和线段(BOUND BOX实体)的距离

postgres=# select st_setsrid(st_makepoint(1,2),4326) <#> st_setsrid(ST_MakeLine(ST_MakePoint(0,0.9), ST_MakePoint(3,4)),4326);  
 ?column?   
----------  
        0  
(1 row)  

3、两个不相交轨迹(范围没有相交)的距离

postgres=# WITH inp AS ( SELECT  
  ST_AddMeasure('LINESTRING Z (0 0 0, 10 0 5)'::geometry,  
    extract(epoch from '2015-05-26 10:01'::timestamptz),  
    extract(epoch from '2015-05-26 11:01'::timestamptz)  
  ) a,  
  ST_AddMeasure('LINESTRING Z (0 2 10, 12 1 2)'::geometry,  
    extract(epoch from '2015-05-25 01:00'::timestamptz),  
    extract(epoch from '2015-05-25 13:00'::timestamptz)  
  ) b  
)  
SELECT ST_DistanceCPA(a,b) distance FROM inp;  
 distance   
----------  
           
(1 row)  

4、两个有相交(范围有交集)的距离 (lower1upper1 与 lower2upper2 有相交)

postgres=# WITH inp AS ( SELECT  
  ST_AddMeasure('LINESTRING Z (0 0 0, 10 0 5)'::geometry,  
    extract(epoch from '2015-05-26 10:01'::timestamptz),   -- lower  
    extract(epoch from '2015-05-26 11:01'::timestamptz)    -- upper  
  ) a,  
  ST_AddMeasure('LINESTRING Z (0 2 10, 12 1 2)'::geometry,  
    extract(epoch from '2015-05-25 01:00'::timestamptz),   -- lower  
    extract(epoch from '2015-05-26 13:00'::timestamptz)    -- upper  
  ) b  
)  
SELECT ST_DistanceCPA(a,b) distance FROM inp;  
     distance       
------------------  
 3.07479618495659  
(1 row)  

5、两个有相交(范围有交集)的距离

postgres=# WITH inp AS ( SELECT  
  ST_AddMeasure('LINESTRING Z (0 0 0, 10 0 5)'::geometry,  
    extract(epoch from '2015-05-26 10:01'::timestamptz),  
    extract(epoch from '2015-05-26 11:01'::timestamptz)  
  ) a,  
  ST_AddMeasure('LINESTRING Z (0 2 10, 12 1 2)'::geometry,  
    extract(epoch from '2015-05-25 01:00'::timestamptz),  
    extract(epoch from '2015-05-26 10:10'::timestamptz)  
  ) b  
)  
SELECT ST_DistanceCPA(a,b) distance FROM inp;  
    distance       
-----------------  
 10.621322893124  
(1 row)  

排序用法

select * from tbl order by geom <-> 某个空间对象常量; 

参考

http://workshops.boundlessgeo.com/postgis-intro/knn.html

http://postgis.net/docs/manual-2.4/reference.html#Operators

http://postgis.net/docs/manual-2.4/geometry_distance_cpa.html

http://postgis.net/docs/manual-2.4/ST_DistanceCPA.html

《PostgreSQL 如何确定某个opclass支持哪些操作符(支持索引),JOIN方法,排序》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
4月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
1月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
104 8
|
1月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
123 7
|
2月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
79 9
|
2月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
41 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
2月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
2月前
|
机器学习/深度学习 算法 API
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
|
3月前
|
算法 Python
KNN
【9月更文挑战第11天】
59 13
|
2月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
34 0
|
2月前
|
关系型数据库 PostgreSQL Docker
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
47 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版