PostGIS与ArcSDE一样,也具有相关的空间函数,能够实现对空间表数据的增删查改操作,正确认识和掌握基于postgis的空间函数方法,能够更好的为GIS功能服务产品化服务。
1点线面几何
1.1点
st_geometryfromtext('point(117.32444 31.6422)', 4326)
--经度在前,纬度在后,中间使用空格连接
注:4326是坐标系,不写则默认为0;这点与sde不同。支持使用4490。
1.2线
st_geometryfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)', 4326)
--linestring 单线
st_geometryfromtext('Multilinestring((117.34 31.345,117.577 31.523, 117.876 31.234))', 4326)
--Multilinestring 多线
1.3面
st_geometryfromtext('Polygon((116.381486 31.996660,117.832230 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))', 4326)
--Polygon 单面
st_geometryfromtext('Multipolygon(((116.381486 31.996660,117.832230 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660)))', 4326)
--Multipolygon 多面
2测量
2.1两要素间距离
测量两个要素之间的距离,结果单位是米。
(1)函数定义
st_distance:用于返回两个几何之间的距离。这一距离是两个几何的最近折点之间的距离。
st_distance(geometry, geometry)--计算两个几何要素的距离,计算结果是几何坐标系的单位,比如几何要素是4326的坐标系,则单位是度。
st_distance(geography, geography, bool)--计算两个地理图形的距离,计算结果为米。Bool值是是否使用椭球,默认是true,可不写。若为false,会有误差。采用默认即可。
注:若想根据地理坐标系计算得到“米”结果,需要将geometry转换成geography。定义st_geography时,不需要定义坐标系。
(2)点到点距离
select st_distance(st_geometryfromtext('point(117.32444 31.6422)', 4326),st_geometryfromtext('point(117.5432 31.2344)', 4326));--笛卡尔坐标,计算结果是度
--0.4627707613927223
select st_distance(st_geographyfromtext('point(117.32444 31.6422)'),st_geographyfromtext('point(117.5432 31.2344)'));--地理坐标系,计算结果是米
--49768.85732439
select st_distance(st_geographyfromtext('point(117.32444 31.6422)'),st_geographyfromtext('point(117.5432 31.2344)'),false);--地理坐标系,不使用椭圆
--49869.15835121
(3)点到线距离
select st_distance(st_geometryfromtext('point(117.32444 31.6422)', 4326),st_geometryfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)', 4326));--笛卡尔坐标,计算结果是度
--0.246984019346877
select st_distance(st_geographyfromtext('point(117.32444 31.6422)'),st_geographyfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)'));--地理坐标系,计算结果是米
--25738.76536503
(4)点到面距离
select st_distance(st_geometryfromtext('point(116.32444 31.6422)', 4326),st_geometryfromtext('Polygon((116.381486 31.996660,117.832230 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))', 4326));--笛卡尔坐标,计算结果是度
--0.19300764497299291
select st_distance(st_geographyfromtext('point(116.32444 31.6422)'),st_geographyfromtext('Polygon((116.381486 31.996660,117.832230 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))'));--地理坐标系,计算结果是米
--18759.80611129
2.2线段长度
(1)函数定义
st_length:计算线要素的长度。
st_length(geometry)--计算线要素的长度,计算结果是几何坐标系的单位,比如几何要素是4326的坐标系,则单位是度
st_length(geography, bool)--计算线要素的长度,计算结果为米。
(2)计算
select st_length(st_geometryfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)', 4326));--笛卡尔坐标,计算结果是度
--0.712238978594611
select st_length(st_geographyfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)'));--地理坐标系,计算结果是米
--72798.26588195487
select st_length(st_geometryfromtext('linestring(117.34 31.345,117.577 31.523, 117.876 31.234)', 4326)::geography);--之间使用::geography将geometry转换。
--72798.26588195487
2.3多边形周长面积
(1)函数定义
st_perimeter:计算面要素的周长。
st_area:计算面要素的面积。
(2)周长计算
select st_perimeter(st_geometryfromtext('Polygon((116.381486 31.996660,117.83223 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))', 4326));--笛卡尔坐标,计算结果是度
select st_perimeter(st_geographyfromtext('Polygon((116.381486 31.996660,117.83223 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))'));--地理坐标系,计算结果是米
select st_perimeter(st_geographyfromtext('Multipolygon(((116.381486 31.996660,117.83223 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660)),((116.546 31.656,117.76764 31.233424, 117.3323 31.65788,116.6767 31.23246,116.546 31.656)))'));--地理坐标系,计算结果是米 【多面】
(3)面积计算
select st_area(st_geometryfromtext('Polygon((116.381486 31.996660,117.83223 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))', 4326));--笛卡尔坐标,计算结果是度的平方
select st_area(st_geographyfromtext('Polygon((116.381486 31.996660,117.83223 31.976322, 117.916157 31.266769,116.699211 31.261644,116.381486 31.996660))'));--地理坐标系,计算结果是平方米
select st_area(st_geographyfromtext('Multipolygon(((117.381486 32.996660,118.83223 32.976322, 118.916157 32.266769,117.699211 32.261644,117.381486 32.996660)),((114.546 29.656,115.76764 30.233424, 115.8323 29.65788,114.6767 29.23246,114.546 29.656)))'));--地理坐标系,计算结果是平方米 【多面】
3查询
查询包括属性查询和空间查询两种。属性查询直接是sql根据字段或者其他属性信息进行结构化查询;空间查询主要是给定空间要素(点、线、面)进行空间关系上的判断,筛选出相关数据,一般使用st_intersects(相交函数)。
3.1属性查询
select * from geo_onemap_2020 where di_lei='0111' and lin_zhong2='110'
3.2空间查询
(1)基于点查询
--查询点所在小班数据(空间查询--指定点)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( 'point(117.544523 29.627105)' ,4490 ) );
(2)基于点+缓冲半径查询
--查询点半径500米范围内的小班数据(空间查询--指定中心点、半径的圆)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( st_astext ( st_buffer ( st_geographyfromtext ( 'point(117.544523 29.627105)' ), 500 ) ),4490 ) );
(3)基于线查询
--查询线相交的小班数据(空间查询--指定线)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( 'linestring(117.54 29.645,117.577 29.623, 117.876 29.634)',4490 ) );
(4)基于线+缓冲半径查询
--查询线半径100米范围内的小班数据(空间查询--指定线、缓冲半径)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( st_astext ( st_buffer ( st_geographyfromtext ( 'linestring(117.54 29.645,117.577 29.623, 117.876 29.634)' ), 100 ) ),4490 ) );
(5)基于面查询
--查询面相交的小班数据(空间查询--指定面)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( 'Polygon((117.6139 29.8133,117.62 29.823, 117.628 29.877,117.625 29.812,117.6139 29.8133))',4490 ) );
(6)基于面+缓冲半径查询
--查询面半径100米范围内的小班数据(空间查询--指定面、缓冲半径)
SELECT
*
FROM
geo_onemap_2020 T
WHERE
st_intersects ( T.geom, st_geometryfromtext ( st_astext ( st_buffer ( st_geographyfromtext ( 'Polygon((117.6139 29.8133,117.62 29.823, 117.628 29.877,117.625 29.812,117.6139 29.8133))' ), 100 ) ),4490 ) );
4业务相关
4.1资源数据的任意范围筛选
--范围筛选:给定面要素范围【矩形、圆、任意多边形】,根据业务数据的经纬度筛选出对应表中的数据。
SELECT
*
FROM
( SELECT * FROM fire_alarms WHERE fire_alarms.longitude <> '' AND fire_alarms.latitude <> '' ) AS pnt
WHERE
st_intersects ( st_geometryfromtext ( 'point(' || pnt.longitude || ' ' || pnt.latitude || ')', 4326 ), st_geometryfromtext ( 'Polygon((116.2139 29.3133,116.62 32.823, 118.628 32.877,117.625 29.812,116.2139 29.3133))', 4326 ) );
4.2资源数据的点加缓冲半径筛选
--缓冲区分析:给定点要素和半径【点+半径】,根据业务数据的经纬度筛选出对应表中的数据。【点:117.344523 31.827105 半径:5000米】
SELECT
*
FROM
( SELECT * FROM fire_alarms WHERE fire_alarms.longitude <> '' AND fire_alarms.latitude <> '' ) AS pnt
WHERE
st_intersects (
st_geometryfromtext ( 'point(' || pnt.longitude || ' ' || pnt.latitude || ')', 4326 ),
st_geometryfromtext ( st_astext ( st_buffer ( st_geographyfromtext ( 'point(117.344523 31.827105)' ), 5000 ) ), 4326 )
);
注:点、线、面的缓冲区分析均能使用,即传入的geometry可以支持点、线、面。
4.3资源数据根据空间要素班块的查询
--县级区划责任区下的火点数量查询【资源数据的坐标系定义取决于所分析的责任区班块的坐标系,两者统一才能进行】
SELECT COUNT
( * ) AS shuliang,
plyo.xian_name
FROM
( SELECT * FROM fire_alarms WHERE fire_alarms.longitude <> '' AND fire_alarms.latitude <> '' ) AS pnt,
geo_xzqh_xian_anhui AS plyo
WHERE
st_intersects ( st_geometryfromtext ( 'point(' || pnt.longitude || ' ' || pnt.latitude || ')', 4490 ), plyo.geom ) = 't'
GROUP BY
plyo.xian_name
ORDER BY
shuliang DESC;
4.4查询火点周边5000米内的林地小班,计算离班块的距离并排序
--点周边5000米内的林地小班及距离排序【最终】
SELECT
*,
--距离计算时,将5000米内的小班筛选后,逐个与点进行距离计算,计算时使用geography重新定义才能得到单位为米
st_distance ( st_geographyfromtext(st_astext(T.geom)), st_geographyfromtext ( 'point(117.544523 29.627105)' )) AS juli
FROM
geo_onemap_2020 T
WHERE
--林地小班
dilei_2 LIKE'01%'
AND
--空间查询,5000米内的小班
st_intersects ( T.geom, st_geometryfromtext ( st_astext ( st_buffer ( st_geographyfromtext ( 'point(117.544523 29.627105)' ), 5000 ) ),4490 ) )
ORDER BY
juli;