目录
前言
一、基础数据
1、数据结构准备
2、基础数据构造
二、常用空间函数
1、st_srid 获取空间对象SRID
2、st_asgeojson geojson转换
3、st_aswkt wkt支持
4、st_area 面积计算
5、ST_Buffer 缓冲区
6、其它函数
总结
近些年,面向GIS的应用如雨后春笋般涌现,其底层的时空数据库在地理信息和时空数据管理系统在系统建设过程中发挥着举足轻重的重要作用。空间数据库中存储了空间信息,与传统的关系型数据库在数据的管理方面有自己的独特性,比如有别于传统索引的空间索引等。
众所周知,函数是数据库中专门处理一种问题的功能方法集,比如关系数据库中的时间函数、数字函数、字符串函数,而在空间数据库中,不仅包含了这些关系数据库中所有函数,也集成了更加丰富的空间函数,尤其以PostGIS空间库实现的最为标准和丰富。
本文将围绕PostGIS空间数据库,重点讲解在空间数据库中几个常用的空间函数,通过实例的讲解带读者了解函数的基础使用。
在进行空间数据查询前,首先进行数据结构的定义,除了常见的关系数据库的结构定义,在空间数据库字段设计中,必须要包含空间字段。详细数据库结构参考以下设计:
-- ----------------------------
-- Table structure for dltb4326
-- ----------------------------
DROP TABLE IF EXISTS "dltb4326";
CREATE TABLE "dltb4326" (
"gid" int4 NOT NULL DEFAULT nextval('dltb4326_gid_seq'::regclass),
"objectid" int4,
"qsxz" varchar(2),
"qsdwdm" varchar(19),
"qsdwmc" varchar(60),
"zldwdm" varchar(19),
"zldwmc" varchar(60),
"tbmj" numeric,
"kcdlbm" varchar(5),
"kcxs" numeric,
"kcmj" numeric,
"tbdlmj" numeric,
"gdlx" varchar(2),
"gdpdjb" varchar(2),
"gddb" int4,
"frdbs" varchar(1),
"czcsxm" varchar(4),
"sjnf" int4,
"mssm" varchar(2),
"hdmc" varchar(100),
"bz" varchar(254),
"shape_leng" numeric,
"shape_area" numeric,
"geom" "geometry"
)
;
-- ----------------------------
-- Indexes structure for table dltb4326
-- ----------------------------
CREATE INDEX "dltb4326_geom_idx" ON "dltb4326" USING gist (
"geom" "public"."gist_geometry_ops_2d"
);
-- ----------------------------
-- Primary Key structure for table dltb4326
-- ----------------------------
ALTER TABLE "dltb4326" ADD CONSTRAINT "dltb4326_pkey" PRIMARY KEY ("gid");
在设计好数据库表结构后,需要进行数据初始化,如何在数据库中进行数据初始化这里不做大量讲解,数据展示如下:
可以在pgAdmin中进行空间字段的展示,在查询出来的最后一个空间字段有一个预览的按钮,鼠标左键点击即可完成数据预览,效果如下所示:
在空间数据库中,可以使用st_srid()函数查看空间数据的srid信息。在postgis中可以看到其具体的函数定义:
CREATE OR REPLACE FUNCTION "public"."st_srid"("geom" "public"."geometry")
RETURNS "pg_catalog"."int4" AS '$libdir/postgis-3', 'LWGEOM_get_srid'
LANGUAGE c IMMUTABLE STRICT
COST 1
在调用函数时仅需要传入空间数据就可以,值得注意的是,st_srid不仅支持geometry,同时也支持geography,关于geography和geometry的区别,大家可以查找相关的资料。
select st_srid(geom) from dltb4326 limit 1;
函数运行之后得到的结果如下:
在空间数据库中,为了保持存储的高效性,通常来说,数据是存储为二进制的,比如以下的格式:
以上的格式虽然对于数据存储来说是最高效的,但是对用户来讲,可读性是较差的,geojson是一种面向地理数据格式的json数据格式,具有可读性高的优点。在postGIS中,通过st_asgeojson进行数据转换。
CREATE OR REPLACE FUNCTION "public"."st_asgeojson"(text)
RETURNS "pg_catalog"."text" AS $BODY$ SELECT public.ST_AsGeoJson($1::public.geometry, 9, 0); $BODY$
LANGUAGE sql IMMUTABLE STRICT
COST 500
select st_asgeojson(geom) from dltb4326;
其中一条geojson数据如下所示:
{"type":"MultiPolygon","coordinates":[[[[112.948902049,28.031646521],[112.948934463,28.031602495],[112.948947087,28.03160557],[112.948990862,28.031516143],[112.948970512,28.031507049],[112.948915856,28.031482624],[112.948953672,28.031411773],[112.948989778,28.031426021],[112.949058815,28.031135666],[112.948993581,28.031122934],[112.948972683,28.031147219],[112.948939525,28.031192802],[112.948837509,28.031234815],[112.948830726,28.031238787],[112.948818769,28.031259925],[112.948799172,28.031296293],[112.948793881,28.031313083],[112.948783858,28.031341866],[112.948778722,28.031356612],[112.948761457,28.031402316],[112.948760048,28.031405735],[112.948759101,28.031427842],[112.948823424,28.031465486],[112.948871536,28.031498082],[112.948876579,28.031532736],[112.948861376,28.031574397],[112.94883146,28.031607591],[112.948813904,28.031614619],[112.94878463,28.03162494],[112.948777458,28.031627469],[112.948740873,28.031654644],[112.948627326,28.031849531],[112.948564719,28.031924253],[112.9485632,28.031942145],[112.948503091,28.032004376],[112.948436182,28.032106517],[112.948384475,28.032166996],[112.94830902,28.032192929],[112.948370033,28.032250988],[112.948396715,28.032267267],[112.94840872,28.032274592],[112.948418868,28.032262969],[112.948557256,28.032104472],[112.948640482,28.032009154],[112.948787309,28.031840991],[112.94880614,28.031819424],[112.948808544,28.031816671],[112.948832592,28.031789129],[112.94885082,28.03173793],[112.948851228,28.031737165],[112.948893567,28.031658044],[112.948902049,28.031646521]]]]}
在拿到geojson后,许多前端gis框架,比如leaflet、cesium、openlayers都可以直接进行展示。
在空间数据中,除了可以直接将空间数据转为json外,还可以将数据格式转换为wkt。支持函数为st_aswkt
CREATE OR REPLACE FUNCTION "public"."st_asewkt"("public"."geometry", int4)
RETURNS "pg_catalog"."text" AS '$libdir/postgis-3', 'LWGEOM_asEWKT'
LANGUAGE c IMMUTABLE STRICT
COST 500
在上面的空间表中进行查询验证。
select st_asewkt(geom) from dltb4326;
SRID=4326;MULTIPOLYGON(((112.94890204932419 28.03164652145915,112.94893446282308 28.03160249461021,112.94894708668416 28.03160556961373,112.94899086229839 28.03151614262633,112.94897051189844 28.03150704851138,112.94891585590196 28.03148262432319,112.94895367222296 28.0314117725388,112.94898977797723 28.031426021004112,112.94905881545756 28.031135666053835,112.94899358110835 28.031122933916585,112.94897268274052 28.03114721949028,112.94893952469715 28.03119280160087,112.94883750860863 28.031234815284318,112.94883072625771 28.031238786653255,112.94881876908642 28.03125992489088,112.94879917174167 28.0312962928862,112.94879388059157 28.031313082613508,112.94878385840406 28.031341866228075,112.94877872235762 28.031356611674585,112.9487614574029 28.031402316249164,112.94876004837538 28.031405735030464,112.9487591013953 28.03142784174355,112.94882342369294 28.031465486161448,112.94887153560425 28.03149808188427,112.94887657902083 28.031532736410973,112.94886137589438 28.03157439741858,112.9488314598062 28.031607590745498,112.94881390363874 28.03161461870683,112.94878462976982 28.031624939649983,112.94877745771588 28.031627468898503,112.94874087256784 28.031654643500215,112.94862732553705 28.031849531246586,112.94856471938606 28.031924252558934,112.94856320015934 28.031942144854593,112.94850309122222 28.032004375600756,112.9484361819004 28.03210651665418,112.94838447535787 28.032166996273293,112.94830902032196 28.032192928521404,112.94837003282403 28.03225098804355,112.94839671459228 28.03226726728849,112.94840871962174 28.032274591850808,112.94841886802325 28.032262968778635,112.94855725634616 28.032104472143654,112.94864048184257 28.032009153963696,112.94878730879185 28.03184099148005,112.94880613958024 28.031819424476836,112.94880854374979 28.031816671071233,112.94883259161806 28.03178912893942,112.94885081958518 28.03173792962929,112.94885122816191 28.031737165367048,112.94889356660211 28.0316580440782,112.94890204932419 28.03164652145915)))
针对空间数据中的面类型数据,很多情况下需要查询空间面积,在postgis中可以使用st_area函数进行面积计算。
CREATE OR REPLACE FUNCTION "public"."st_area"("public"."geometry")
RETURNS "pg_catalog"."float8" AS '$libdir/postgis-3', 'ST_Area'
LANGUAGE c IMMUTABLE STRICT
COST 50
select st_area(geom::geography),st_area(geom) from dltb4326;
这里讲一个有趣的例子,在上述语句运行完成后,可以看到以下结果:
空间函数是一样的,不同的是传进去的参数不一样,一个是geography,另一个是geometry,可以看到两者运行的结果不太一样。先讲一下原因,在postGIS中,默认情况下,如果传入geometry进行面积求解,在srid是4326的时候,出来的结果是按度来进行展示的。而geography是按米为单位进行展示的,大家在工作中,按照自己的需要进行合理选型。
在很多应用中,我们需要对原始的数据进行范围计算,比如建立一个公交站,需要覆盖周全2公里的范围,我们可以构建出一个2公里的缓冲面出来,直接返回给前端。
CREATE OR REPLACE FUNCTION "public"."st_buffer"("geom" "public"."geometry", "radius" float8, "quadsegs" int4)
RETURNS "public"."geometry" AS $BODY$ SELECT public.ST_Buffer($1, $2, CAST('quad_segs='||CAST($3 AS text) as text)) $BODY$
LANGUAGE sql IMMUTABLE STRICT
COST 10000
select st_asgeojson(st_buffer(geom,2)) from dltb4326;
除了上述常见的函数,postgis还提供了丰富的空间函数给大家。感兴趣的朋友可以去postgis的官网进行查看,这里简单列一些常用的函数,大家可以在空间数据中深度使用。正是这些功能丰富的函数让空间分析变得更加方便,快捷。
拓扑关系
ST_3DIntersects —如果两个几何在3D中在空间上相交,则返回true-仅用于点,线串,多边形,多面曲面(区域)。
ST_Contains —当且仅当B的点不位于A的外部且B的内部的至少一个点位于A的内部时,才返回true。
ST_ContainsProperly —如果B与A的内部而不是边界(或外部)相交,则返回true。 A本身不包含自身,但是包含自身。
ST_Covers —如果B中没有点在A之外,则返回true
ST_CoveredBy —如果Geometry / Geography A中没有点在Geometry / Geography B之外,则返回true
ST_Crosses —如果两个几何具有一些但不是全部内部相同的点,则返回true。
ST_LineCrossingDirection —返回一个数字,指示两个LineString的交叉行为。
ST_Disjoint —如果两个几何在空间上不相交(它们没有共同点),则返回true。
ST_Equals —如果两个几何在空间中包含相同的点集,则返回true。
ST_Intersects —如果两个“几何” /“地理”在2D空间上相交(至少有一个共同点),则返回true。
ST_OrderingEquals —如果两个几何表示相同的几何并且具有相同的方向顺序的点,则返回true。
ST_Overlaps —如果两个几何相交且具有相同的尺寸,但彼此之间不完全包含,则返回true。
ST_Relate —测试两个几何是否具有与给定“交集矩阵”模式匹配的拓扑关系,或计算它们的“交集矩阵”
ST_RelateMatch —测试DE-9IM交集矩阵是否与交集矩阵模式匹配
ST_Touches —如果两个几何至少有一个共同点,但它们的内部不相交,则返回true。
ST_Within —如果几何A完全在几何B内,则返回true
距离关系
ST_3DDWithin —如果两个3D几何形状在给定的3D距离内,则返回true
ST_3DDFullyWithin —如果两个3D几何完全在给定的3D距离内,则返回true
ST_DFullyWithin —如果两个几何完全在给定距离内,则返回true
ST_DWithin —如果两个几何在给定距离内,则返回true
ST_PointInsideCircle —测试点几何是否在由中心和半径定义的圆内。
测量功能
ST_Area —返回多边形几何的面积。
ST_Azimuth —返回以北为基准的方位角,以弧度为单位,从点A的垂直方向到点B的角度以弧度为单位。
ST_Angle —返回3个点之间或2个向量之间的角度(4个点或2条线)。
ST_ClosestPoint —返回g1上最接近g2的2D点。这是最短线的第一点。
ST_3DClosestPoint —返回g1上最接近g2的3D点。这是3D最短线的第一点。
ST_Distance —返回两个几何或地理值之间的距离。
ST_3DDistance —以投影单位返回两个几何之间的3D笛卡尔最小距离(基于空间参考)。
ST_DistanceSphere —使用球形地球模型返回两个lon / lat几何之间的最小距离(以米为单位)。
ST_DistanceSpheroid —使用球形地球模型返回两个lon / lat几何之间的最小距离。
ST_FrechetDistance —返回两个几何之间的Fréchet距离。
ST_HausdorffDistance —返回两个几何之间的Hausdorff距离。
ST_Length —返回线性几何的2D长度。
ST_Length2D —返回线性几何的2D长度。 ST_Length的别名
ST_3DLength —返回线性几何的3D长度。
ST_LengthSpheroid —返回球体上lon / lat几何图形的2D或3D长度/周长。
ST_LongestLine —返回两个几何之间的2D最长线。
ST_3DLongestLine —返回两个几何之间的3D最长线
ST_MaxDistance —以投影单位返回两个几何之间的最大二维距离。
ST_3DMaxDistance —以投影单位返回两个几何之间的3D笛卡尔最大距离(基于空间参考)。
ST_MinimumClearance —返回几何图形的最小间隙,度量几何图形的鲁棒性。
ST_MinimumClearanceLine —返回跨越几何最小间隙的两点LineString。
ST_Perimeter —返回多边形几何或地理边界的长度。
ST_Perimeter2D —返回多边形几何的2D周长。 ST_Perimeter的别名。
ST_3DPerimeter —返回多边形几何的3D周长。
ST_Project —返回从起点投影一个距离和方位角(方位角)的点。
ST_ShortestLine —返回两个几何之间的2D最短线
几何处理
这些函数计算几何结构,或改变几何尺寸或形状
ST_Buffer —返回一个几何图形,该几何图形覆盖距几何图形给定距离内的所有点。
ST_BuildArea —创建由几何的线条构成的多边形几何。
ST_Centroid —返回几何的几何中心。
ST_ConcaveHull —计算可能包含所有输入几何顶点的凹形几何
ST_ConvexHull —计算几何的凸包。
ST_DelaunayTriangles —返回几何顶点的Delaunay三角剖分。
ST_FilterByM —根据顶点的M值移除顶点
ST_GeneratePoints —生成多边形或多多边形中包含的随机点。
ST_GeometricMedian —返回MultiPoint的几何中间值。
ST_MaximumInscribedCircle —计算完全包含在几何图形内的最大圆。
ST_MinimumBoundingCircle —返回包含几何的最小圆形多边形。
ST_MinimumBoundingRadius —返回包含几何的最小圆的中心点和半径。
ST_OrientedEnvelope —返回包含几何的最小面积的矩形。
ST_OffsetCurve —返回距输入线给定距离和边距的偏移线。
ST_PointOnSurface —返回保证位于多边形或几何图形上的点。
ST_Polygonize —计算由一组几何图形的线条形成的多边形的集合。
ST_ReducePrecision —返回一个有效的几何图形,所有点均四舍五入到提供的网格公差。
ST_SharedPaths —返回包含两个输入线串/多线串共享的路径的集合。
ST_Simplify —使用Douglas-Peucker算法返回几何的简化版本。
ST_SimplifyPreserveTopology —使用Douglas-Peucker算法返回几何的简化和有效版本。
ST_SimplifyVW —使用Visvalingam-Whyatt算法返回几何的简化版本
ST_ChaikinSmoothing —使用Chaikin算法返回几何的平滑版本
ST_SetEffectiveArea —使用Visvalingam-Whyatt算法设置每个顶点的有效面积。
ST_VoronoiLines —返回几何顶点的Voronoi图的边界。
ST_VoronoiPolygons —返回几何顶点的Voronoi图的像元。
仿射变换
这些函数使用仿射变换改变几何图形的位置和形状.
ST_Affine —将3D仿射变换应用于几何图形。
ST_Rotate —围绕原点旋转几何。
ST_RotateX —绕X轴旋转几何。
ST_RotateY —围绕Y轴旋转几何。
ST_RotateZ —绕Z轴旋转几何。
ST_Scale —按给定因子缩放几何。
ST_Translate —按给定的偏移量转换几何图形。
ST_TransScale —按给定的偏移量和系数平移和缩放几何。
以上就是本文的主要内容,本文将围绕PostGIS空间数据库,重点讲解在空间数据库中几个常用的空间函数,通过实例的讲解带读者了解函数的基础使用。行文仓促,难免有误,欢迎在评论区留言批评指正。