我猜想一般利用PostGreSQL数据库的都是想利用它的空间数据,地理信息相关的函数或功能的特性吧。一般做基于地理信息数据应用的才会考虑此中数据库。否则,还不如使用Mysql呢。
PostGreSQL想要处理复杂的地理信息系统的相关数据,有专门的扩展,PostGIS。里面具有丰富的数据类型和功能函数。而我目前的应用使用PostGIS太过于笨重。我的需求很简单:
查找某点附近某个半径范围内的某类商铺,并按照距离排序。举个具体例子:以我的位置为原点,查找半径1公里范围内的火锅,并按照距离排序。
这样的功能其实利用PostGreSQL的扩展包内的函数即可,无需安装PostGIS了,并且使用很方便。
Function Returns Description
earth() float8 Returns the assumed radius of the Earth.
sec_to_gc(float8) float8 Converts the normal straight line (secant) distance between two points on the surface of the Earth to the great circle distance between them.
gc_to_sec(float8) float8 Converts the great circle distance between two points on the surface of the Earth to the normal straight line (secant) distance between them.
ll_to_earth(float8, float8) earth Returns the location of a point on the surface of the Earth given its latitude (argument 1) and longitude (argument 2) in degrees.
latitude(earth) float8 Returns the latitude in degrees of a point on the surface of the Earth.
longitude(earth) float8 Returns the longitude in degrees of a point on the surface of the Earth.
earth_distance(earth, earth) float8 Returns the great circle distance between two points on the surface of the Earth.
earth_box(earth, float8) cube Returns a box suitable for an indexed search using the cube @> operator for points within a given great circle distance of a location. Some points in this box are further than the specified great circle distance from the location, so a second check using earth_distance should be included in the query.
上面的案例其实利用earthdistance扩展包中最重要的两个函数是earth_distance(earth, earth)和earth_box(earth, float8)。前一个是计算两点的距离,后一个是计算某个半径范围内球面范围内包含的点。利用这两个函数基本上就满足我的需求了。例子:
/*选择(40.059286,116.418773)点半径1000米范围内的记录,并按照距离排序*/
SELECT id,earth_distance(ll_to_earth(picture.lat, picture.lng), ll_to_earth(40.059286,116.418773))
AS dis FROM picture where earth_box(ll_to_earth(40.059286,116.418773),1000) @> ll_to_earth(picture.lat, picture.lng) order by dis desc;
PS:以上可参考文献:
<1> http://blog.youkuaiyun.com/wusuopubupt/article/details/21621477
<2> http://www.postgresql.org/docs/8.3/static/earthdistance.html
知道了怎么使用。就看看怎么安装earthdistance扩展包。其实,它需要安装两个扩展包:
<1> cube;<2>earthdistance;
如果你是源码安装,那就很简单了,如果不是,下载源码(下载9.x版本的,8.x版本的太老了)。
在源码包的contrib目录下有我们需要的两个扩展包。(我的是postgresql-9.3.5/contrib/)
这里有个问题,如果之前你已经安装了PostGreSQL。那么你直接在你之前执行安装的源码包目录中找到contrib目录。
然后,从第3步开始执行。如果你已经删除了之前安装的源码包的目录。那么你需要解压源码包,并在源码包的目录下,从<1>执行。
不过,总之,前提都是你之前已经安装了PostGreSQL。没有安装PostGreSQL,先看我之前的一篇关于PostGreSQL的安装博客。再从<3>执行即可。
首先你要利用这个源码包的目录执行以下操作:
<1> ./configure或(./configure --prefix==“安装目录”)
<2> make
<3> cd 到postgresql-9.x/contrib/cube目录下,执行./configure-->make-->make install;
<4>cd 到postgresql-9.x/contrib/earthdistance目录下,执行./configure-->make-->make install;
<5>然后利用psql命令进入到postgresql数据库(你要使用的数据库),然后执行如下操作即可:
CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;
再强调一下,你必须安装好了postgresql,另外,必须在执行过./configure和make后的源码包目录下,再去contrib目录下找curb和earthdistance执行编译和安装,
否则,编译总是不通过。