@code33
2021-07-26T08:21:46.000000Z
字数 5894
阅读 928
create by jyo
contact code0515@outlook.com
Postgres
PostGIS
首先安装运行PostgreSQL 服务端,然后在服务端上安装依赖类库
以下库 默认都安装到
/usr/local/lib
这个路径下,如安装后未在该目录下检查到对应so文件,请重新检查or 在 ./configure 后添加路径后缀
--prefix=/usr/local
GIS 坐标转换库 proj4
介绍及使用参考
http://www.cnblogs.com/oloroso/p/5672837.html
wget http://xyzsetup.dlhis.com/proj-4.7.0.tar.gz
tar xzvf proj-4.7.0.tar.gz
cd proj-4.7.0
./configure
sudo make
sudo make install
介绍
http://www.kaiyuanba.cn/html/1/131/227/8010.htm
wget http://xyzsetup.dlhis.com/geos-3.6.1.tar.bz2
cd geos-3.6.1
./configure
sudo make
sudo make install
介绍
http://www.cnblogs.com/shanzhizi/archive/2012/07/09/2583739.html
wget http://xyzsetup.dlhis.com/libxml2-2.9.4.tar.gz
tar xzvf libxml2-2.9.4.tar.gz
cd libxml2-2.9.4
./configure
sudo make
sudo make install
添加系统环境变量
文件
/etc/profile
export LD_LIBRARY_PATH=/usr/local/lib
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export PATH=${LD_LIBRARY_PATH}:${PKG_CONFIG_PATH}:${PATH}
介绍及使用
http://www.cnyubin.com/technical_life/cc/304
先安装依赖
sudo apt-get install autoconf
环境要求:
c语言的编译器要有,不过官网页上没有指明gcc的版本
本机的gcc版本号是4.8.4
gcc, clang, or another C compiler
libtool>=2.2.6b
wget http://qiniu-aladin.dlhis.com/json-c-json-c-0.12.1-20160607.zip
unzip json-c-json-c-0.12.1-20160607.zip
cd ./json-c-json-c-0.12.1-20160607
./configure --prefix=/usr/local
sudo make
sudo make install
PS:
0.12 版本这代码在编译的过程中於Ubuntu14.04 64bit会有异常错误,导致无法编译安装成功 ,可以联系本文档作者debug分析手工排查
可能涉及到一个C语言文件源码的地方需要将其注释only on ubuntu >= 14.04
不过0.12.1版本已经修复了这个问题
wget http://xyzsetup.dlhis.com/gdal-1.9.2.tar.gz
tar xzvf gdal-1.9.2.tar.gz
cd gdal-1.9.2
./configure
sudo make
sudo make install
使之生效
sudo ldconfig
wget http://xyzsetup.dlhis.com/postgis-2.2.4.tar.gz
如果PostgreSQL安装在非普通用户目录下要添加sudo 编译
注意这里需要使用到原PostgreSQL的服务端程序路径
export PGPATH=/usr/local/pgsql
tar zxvf postgis-2.2.4.tar.gz
cd postgis-2.2.4
./configure --with-pgconfig=${export}/bin/pg_config
make
make install
通过这条语句查询插件安装成功
select * from pg_available_extensions where name like 'postgis%';
成功的查询结果:
一个普通标题 | 一个普通标题 | 一个普通标题 |
---|---|---|
postgis_tiger_geocoder | 2.2.4 | PostGIS tiger geocoder and reverse geocoder |
postgis_topology | 2.2.4 | PostGIS topology spatial types and functions |
postgis | 2.2.4 | PostGIS geometry, geography, and raster spatial types and functions |
对某DB启用该插件
psql --dbname=${urdb} -c "CREATE EXTENSION postgis;"
psql --dbname=${urdb} -c "CREATE EXTENSION postgis_topology;"
如果有发生插件装载异常,请联系作者,应该是某个库
空间数据库已经建立,现在可以建立具有空间信息的表格。
首先建立一个常规的表格存储有关城市(cities)的信息。这个表格有两栏,一个是 ID 编号,一个是城市名:
SQL
demo=# CREATE TABLE cities ( id int4, name varchar(50) );
现在添加一个空间栏用于存储城市的位置。习惯上这个栏目叫做 the_geom 。它记录了数据为什么类型(点、线、面)、有几维(这里是二维)以及空间坐标系统。此处使用 EPSG:4326 坐标系统:
demo=# SELECT AddGeometryColumn ('cities', 'the_geom', 4326, 'POINT', 2);
完成后,查询 cities 表单应当显示这个新栏目。同时页面将显示当前表达没有记录(0 rows)。
SQL
demo=# SELECT * from cities;
RESULT
id | name | the_geom
----+------+----------
(0 rows)
为添加记录,需要使用 SQL 命令。对于空间栏,使用 PostGIS 的 ST_GeomFromText 可以将文本转化为坐标与参考系号的记录:
SQL
demo=# INSERT INTO cities (id, the_geom, name) VALUES (1,ST_GeomFromText('POINT(-0.1257 51.508)',4326),'London, England');
demo=# INSERT INTO cities (id, the_geom, name) VALUES (2,ST_GeomFromText('POINT(-81.233 42.983)',4326),'London, Ontario');
demo=# INSERT INTO cities (id, the_geom, name) VALUES (3,ST_GeomFromText('POINT(27.91162491 -33.01529)',4326),'East London,SA');
当然,这样的输入方式难以操作。其它方式可以更快的输入数据。就目前来说,表格内已经有了一些城市数据,可以先进行查询等操作。
简单查询
标准的 SQL 操作都可以用于 PostGIS 表单:
demo=# SELECT * FROM cities;
id | name | the_geom
----+-----------------+----------------------------------------------------
1 | London, England | 0101000020E6100000BBB88D06F016C0BF1B2FDD2406C14940
2 | London, Ontario | 0101000020E6100000F4FDD478E94E54C0E7FBA9F1D27D4540
3 | East London,SA | 0101000020E610000040AB064060E93B4059FAD005F58140C0
(3 rows)
这里的坐标是无法阅读的 16 进制格式。要以 WKT 文本显示,使用 ST_AsText(the_geom) 或 ST_AsEwkt(the_geom) 函数。也可以使用 ST_X(the_geom) 和 ST_Y(the_geom) 显示一个维度的坐标:
SQL
demo=# SELECT id, ST_AsText(the_geom), ST_AsEwkt(the_geom), ST_X(the_geom), ST_Y(the_geom) FROM cities;
result
id | st_astext | st_asewkt | st_x | st_y
----+------------------------------+----------------------------------------+-------------+-----------
1 | POINT(-0.1257 51.508) | SRID=4326;POINT(-0.1257 51.508) | -0.1257 | 51.508
2 | POINT(-81.233 42.983) | SRID=4326;POINT(-81.233 42.983) | -81.233 | 42.983
3 | POINT(27.91162491 -33.01529) | SRID=4326;POINT(27.91162491 -33.01529) | 27.91162491 | -33.01529
(3 rows)
空间查询:
PostGIS 为 PostgreSQL 扩展了许多空间操作功能。以上已经涉及了转换空间坐标格式的 ST_GeomFromText 。多数空间操作以 ST(spatial type)开头,在 PostGIS 文档相应章节有罗列。这里回答一个具体的问题:以米为单位并假设地球是完美椭球,上面三个城市相互的距离是多少?
sql
demo=# SELECT p1.name,p2.name,ST_Distance_Sphere(p1.the_geom,p2.the_geom) FROM cities AS p1, cities AS p2 WHERE p1.id > p2.id;
result
name | name | st_distance_sphere
-----------------+-----------------+--------------------
London, Ontario | London, England | 5875766.85191657
East London,SA | London, England | 9789646.96784908
East London,SA | London, Ontario | 13892160.9525778
(3 rows)
输出显示了距离数据。注意 ‘WHERE’ 部分防止了输出城市到自身的距离(0)或者两个城市不同排列的距离数据(London, England 到 London, Ontario 和 London, Ontario 到 London, England 的距离是一样的)。尝试取消 ‘WHERE’ 并查看结果。
这里采取不同的椭球参数(椭球体名、半主轴长、扁率)计算:
SQL
demo=# SELECT p1.name,p2.name,ST_Distance_Spheroid(p1.the_geom,p2.the_geom,'SPHEROID["GRS_1980",6378137,298.257222]') FROM cities AS p1, cities AS p2 WHERE p1.id > p2.id;
result
name | name | st_distance_spheroid
-----------------+-----------------+----------------------
London, Ontario | London, England | 5892413.63776489
East London,SA | London, England | 9756842.65711931
East London,SA | London, Ontario | 13884149.4140698
(3 rows)
根据距离范围查询城市列表
100公里外 按近远排列
SELECT
full_name as n1,
ar_code,
'上海' as n2,
ST_Distance_Sphere(ST_AsEwkt(p1.ar_location),
ST_AsEwkt(( select ar_location FROM area_t where ar_code = '310000'))
) as sds
FROM area_t AS p1
WHERE
-- ar_code like '330%' and
ST_Distance_Sphere(ST_AsEwkt(p1.ar_location),
ST_AsEwkt(( select ar_location FROM area_t where ar_code = '310000'))
)>100*1000 and ar_code !='310000' ORDER BY sds asc limit 100;
100公里内 按近远排列
SELECT
full_name as n1,
ar_code,
'上海' as n2,
ST_Distance_Sphere(ST_AsEwkt(p1.ar_location),
ST_AsEwkt(( select ar_location FROM area_t where ar_code = '310000'))
) as sds
FROM area_t AS p1
WHERE
-- ar_code like '330%' and
ST_Distance_Sphere(ST_AsEwkt(p1.ar_location),
ST_AsEwkt(( select ar_location FROM area_t where ar_code = '310000'))
)<100*1000 and ar_code !='310000' ORDER BY sds asc limit 100;
感谢诸位