如何使用 Postgres 扩展在半径范围内搜索?

用户6611764

在地球表面上寻找距离意味着使用大圆距离,用Haversine 公式计算出来,也称为球面余弦定律公式。

问题是这样的:给定一个带有纬度和经度的位置表,这些位置中哪些位置离给定位置最近?

我有以下查询:

 SELECT z.id,
        z.latitude, z.longitude,
        p.radius,
        p.distance_unit
                    * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                    * COS(RADIANS(z.latitude))
                    * COS(RADIANS(p.longpoint - z.longitude))
                    + SIN(RADIANS(p.latpoint))
                    * SIN(RADIANS(z.latitude)))) AS distance
 FROM doorbots as z
 JOIN (   /* these are the query parameters */
    SELECT 34.0480698 AS latpoint, -118.3589196 AS longpoint,
           2 AS radius,  111.045 AS distance_unit
      ) AS p ON 1=1
 WHERE z.latitude between ... and 
       z.longitude between ...

如何使用earthdistance扩展来更改查询中的复杂公式?

是等价的变化吗?

SELECT z.id,
       z.latitude, z.longitude,
       p.radius,
       round(earth_distance(ll_to_earth(p.latpoint, p.longpoint), ll_to_earth(z.latitude, z.longitude))::NUMERIC,0) AS distance
 FROM doorbots as z
 JOIN (   /* these are the query parameters */
    SELECT 34.0480698 AS latpoint, -118.3589196 AS longpoint,
           2 AS radius,  111.045 AS distance_unit
      ) AS p ON 1=1
 WHERE z.latitude between ... and 
       z.longitude between ...
姿势

您可以通过earthdistance以下查询充分利用:

位置足够近(即在 1000000.0 米内 - 621.371192 英里)到 (34.0480698, -118.3589196)

select *
from   doorbots z
where  earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(34.0480698, -118.3589196)) < 1000000.0; -- in meters

select *
from   doorbots z
where  point(z.longitude, z.latitude) <@> point(-118.3589196, 34.0480698) < 621.371192; -- in miles

最接近 (34.0480698, -118.3589196) 的前 5 个位置

select   *
from     doorbots z
order by earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(34.0480698, -118.3589196))
limit    5;

select   *
from     doorbots z
order by point(z.longitude, z.latitude) <@> point(-118.3589196, 34.0480698)
limit    5;

要使用索引,请将以下内容应用于您的表:

create index idx_doorbots_latlong
  on doorbots using gist (earth_box(ll_to_earth(latitude, longitude), 0));

使用索引: 位置足够接近(即在 1000000.0 米内 - 621.371192 英里)到 (34.0480698, -118.3589196)

with p as (
  select 34.0480698   as latitude,
         -118.3589196 as longitude,
         1000000.0    as max_distance_in_meters
)
select z.*
from   p, doorbots z
where  earth_box(ll_to_earth(z.latitude, z.longitude), 0) <@ earth_box(ll_to_earth(p.latitude, p.longitude), p.max_distance_in_meters)
and    earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(p.latitude, p.longitude)) < p.max_distance_in_meters;

使用索引:最接近 (34.0480698, -118.3589196) 的前 5 个位置

select   z.*
from     doorbots z
order by earth_box(ll_to_earth(z.latitude, z.longitude), 0) <-> earth_box(ll_to_earth(34.0480698, -118.3589196), 0)
limit    5;

http://rextester.com/WQAY4056

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用Google Maps API制作表单来搜索特定半径范围内的商品?

如何使用PHP在IP范围内搜索IP?

如何使用搜索数据过滤日期范围内的数据?

如何使用值在范围内搜索来查找文档?

如何在 Postgres 的时间范围内获得平均值?

postgres:如何选择一个范围内的每个值?

如何使用cgo构建Postgres扩展

如何设置Postgres扩展?

如何从系统Verilog接口范围内的类扩展?

如何在容器内创建postgres扩展?

使用Google API搜索服务范围内的公司

使用awk在十进制范围内搜索

搜索和使用范围内的字符

使用FSO在列范围内搜索Excel文件

如何查询Postgres数据库某些坐标方圆10公里范围内得到的所有点

如何加速 Postgres 查询,在该查询中我想查询日期范围内的所有条目

如何准确存储地理位置数据,在半径范围内过滤并计算距离?

如何为位于元素宽度范围内的框阴影添加边界半径?

Netlogo-使用AND&OR条件在半径范围内询问补丁

使用 GORM 和 PostgreSQL 查找半径 10 公里范围内的所有行

如何使用Angular在日期范围内创建搜索过滤器?

如何使用条件格式来搜索ms excel范围内的特定值?

如何在范围内使用合并?

在postgres中,如何在一个范围内找到记录,然后在两边找到范围外的单个记录?

(Excel)如何搜索数字范围内是否包含数字范围

使用数组搜索Postgres数组

使用Lower()索引的Postgres搜索

为多个搜索字符串搜索多列时如何在cross范围内使用str_detect

如何使用 Hasura 和 Postgres 中的视图扩展动态模式?