|导言:PostGIS是业界功能最全面,能力最强大的空间地理数据库引擎。现实业务开发中,经常会遇到有附近的某某的需求,如何快速实现呢,PostGIS PostgreSQL可以帮到你。
本文就讲解如何通过PostGIS实现附近的对象这个功能,实际很简单就一条SQL可以搞定。
首先,我们准备一个PostgreSQL数据库实例,并且此数据库实例需要支持PostGIS插件,版本不挑剔,此为基本能力。
第一步:创建插件,登录到数据库实例中,在业务database执行如下命令:
c test
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;
第二步:创建测试表与索引:
CREATE TABLE t_user(uid int PRIMARY KEY,name varchar(20),location geometry);
CREATE INDEX t_user_location on t_user USING GIST(location);
第三步:插入测试数据:
# 创建一个自动名字生成函数:
create or replace function random_string(length integer) returns text as
$$
declare
chars text[] := '{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}';
result text := '';
i integer := 0;
length2 integer := (select trunc(random() * length 1));
begin
if length2 < 0 then
raise exception 'Given length cannot be less than 0';
end if;
for i in 1..length2 loop
result := result || chars[1 random()*(array_length(chars, 1)-1)];
end loop;
return result;
end;
$$ language plpgsql;
# 插入一千万条测试数据
insert into t_user select generate_series(1,10000000), random_string(20),st_setsrid(st_makepoint(150-random()*100, 90-random()*100), 4326);
第四步:进行附近的人查询。
首先我们在百度地图拾取坐标系统中随便找一个坐标 http://api.map.baidu.com/lbsapi/getpoint/ 。 此处用 天安门广场的坐标作为示例:116.404177,39.909652
第五步:明确好要查询的坐标,就直接在数据库中找到这个坐标最近的5个对象,并且输出这五个对象离此地的距离,此处单位是 百公里。
注意:WGS84 是目前最流行的地理坐标系统。在国际上,每个坐标系统都会被分配一个 EPSG 代码,EPSG:4326 就是 WGS84 的代码。GPS是基于WGS84的,所以通常我们得到的坐标数据都是WGS84的。一般我们在存储数据时,就仍然按WGS84存储。
select uid, name, ST_AsText(location), ST_Distance(ST_GeomFromText('POINT(116.404177 39.909652)',4326), location) from t_user order by location <-> 'SRID=4326;POINT(116.404177 39.909652)'::geometry limit 5;
第六步:查看此对象 1000米以内的所有对象与距离:
select uid, name, ST_AsText(location),ST_Distance(ST_GeomFromText('POINT(116.404177 39.909652)',4326), location) from users where ST_DWithin(location::geography, ST_GeographyFromText('POINT(116.404177 39.909652)'), 1000.0);
第七步: 大功告成,是不是很简单。
补充内容:国内使用的是火星坐标系,下面链接中的内容可以在几种坐标系间互相转换,https://github.com/geocompass/pg-coordtransform/blob/master/geoc-pg-coordtransform.sql