Indexed Nearest Neighbour Search in PostGIS

news/2024/7/9 21:41:02 标签: search, distance, postgresql, query, types, less

原文出自:http://blog.opengeo.org/2011/09/28/indexed-nearest-neighbour-search-in-postgis/


An always popular question on the PostGIS users mailing list has been “how do I find the N nearest things to this point?”.

To date, the answer has generally been quite convoluted, since PostGIS supports bounding box index searches, and in order to get the N nearest things you need a box large enough to capture at least N things.  Which means you need to know how big to make your search box, which is not possible in general.

PostgreSQL has the ability to return ordered information where an index exists, but the ability has been restricted to B-Tree indexes until recently. Thanks to one of our clients, we were able to directly fund PostgreSQL developers Oleg Bartunov and Teodor Sigaev in adding the ability to return sorted results from a GiST index. And since PostGIS indexes use GiST, that means that now we can also return sorted results from our indexes.

Which is a very long way of saying that PostGIS (the development code in the source repository) now has the ability to do index-assisted nearest neighbour searching.

This feature (the PostGIS side of it) was funded by Vizzuality, and hopefully it comes in useful in theirCartoDB work.

You will need PostgreSQL 9.1 and the PostGIS source code from the repository, but this is what a nearest neighbour search looks like:

SELECT name, gid
FROM geonames
ORDER BY geom <-> st_setsrid(st_makepoint(-90,40),4326)
LIMIT 10;

Note the magic <-> operator in the ORDER BY clause. This is where the magic occurs. The <-> is a “distance” operator, but it only makes use of the index when it appears in the ORDER BY clause. Between putting the operator in the ORDER BY and using a LIMIT to truncate the result set, we can very very quickly (less than 10ms on a 2M record table, in this case) get the 10 nearest points to our test point.

“It can’t possibly be this easy!!” You’re right. It can’t. Because it is traversing the index, which is made of bounding boxes, the distance operator only works with bounding boxes. For point data, the bounding boxes are equivalent to the points, so the answers are exact. But for any other geometry types (lines, polygons, etc) the results are approximate.

There are actually two different approximations available for you to chose from.

  • Using the <-> operator, you get the nearest neighbour using the centers of the bounding boxes to calculate the inter-object distances.
  • Using the <#> operator, you get the nearest neighbour using the bounding boxes themselves to calculate the inter-object distances.

In general, because the box calculations are approximations of calculations on the objects themselves, getting a more exact “nearest N objects” is going to require a two-phase query, where the first phase grabs a larger candidate set, and the second phase does an exact test (just like all the other index-assisted predicates). So, for example:

with index_query as (
  select
    st_distance(geom, 'SRID=3005;POINT(1011102 450541)') as distance,
    parcel_id, address
  from parcels
  order by geom <#> 'SRID=3005;POINT(1011102 450541)' limit 100
)
select * from index_query order by distance limit 10;

The indexed query pulls the 100 nearest objects by box distance, and the second query pulls the 10 actual closest from that set.



http://www.niftyadmin.cn/n/1054436.html

相关文章

00077_集合

1、集合使用的回顾 &#xff08;1&#xff09;ArrayList集合存储5个int类型元素 1 public static void main(String[] args) {2 ArrayList<Integer> list new ArrayList<Integer>();3 list.add(111);4 list.add(222);5 list.add(…

ubnutu添加删除PPA

突然遇到了ubuntu的使用细节 记录下来 转自 http://blog.csdn.net/xunathan/article/details/7456926 Ubuntu里&#xff0c;PPA代表一种非稳定版本到发布&#xff0c;喜欢尝试鲜到人一般会加入很多PPA源。 关于PPA到详细说明&#xff0c;可以参考https://help.launchpad.net/…

axel多线程下载工具

axel 是命令行下的多线程下载工具&#xff0c;支持断点续传&#xff0c;速度通常会比 wget 来得快&#xff0c;可以在 : http://wilmer.gaast.net/main.php/axel.html 这里下载。如果是 opensuse 的用户&#xff0c;使用 webpin可以轻松的一键安装这个工具。 axel 的基本使用方…

二叉堆实现优先队列

优先队列支持两种操作&#xff1a;删除最大(小)元素和插入元素。 public class MaxPQ<Key extends Comparable<Key>> {private Key[] pq;private int N 0;public MaxPQ(int maxN) {pq (Key[]) new Comparable[maxN 1];}public boolean isEmpty() {return N 0;…

让元素出现在可视区域scrollIntoView 与 scrollIntoViewIfNeeded API 介绍(转载)

https://juejin.im/post/59d74afe5188257e8267b03f 转载于:https://www.cnblogs.com/raind/p/11126019.html

持续高温引发百姓热议 ***趁机放毒谋取暴利

持续高温引发百姓热议 ***趁机放毒谋取暴利7月7日&#xff0c;就在全国各地气象部门纷纷拉响高温黄色预警的同时&#xff0c;金山毒霸云安全监测中心也启动了病毒黄色预警。近一周&#xff0c;伴随着持续的高温&#xff0c;与天气相关的网页出现被大规模挂马迹象。仅7月6日一天…

HDU 5328 Problem Killer(尺取法)

You are a "Problem Killer", you want to solve many problems. Now you have nn problems, the ii-th problems difficulty is represented by an integer aiai (1≤ai≤1091≤ai≤109). For some strange reason, you must choose some integer ll and rr (1≤l≤…

Ubuntu 12.04 (Precise Pangolin) 安装 OpenStack Essex

转自&#xff1a;http://bbs.chinaunix.net/thread-3729514-1-1.html 这是我参考老外写的英文版本&#xff0c;整理一个中文的版本。也希望随着我的理解深入&#xff0c;不断完善。原文我下面的步骤&#xff0c;也就全部参考原文。 3月27日更新&#xff1a;基本完成文档内容 4月…