zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

【实战】如何通过PostGIS实现附近的人

2023-03-14 22:54:08 时间

|导言: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