转自于:PostGIS教程六:几何图形(geometry) - 知乎
在前面的章节中,我们已经往数据库中加载了数据,现在让我们来先看一些简单的例子。
在pgAdmin中,再次选择nyc数据库并打开SQL查询工具。将下面的SQL代码粘贴到pgAdmin SQL Editor窗口中(删除默认情况下可能存在的任何文本),然后执行。
CREATE TABLE geometries (name varchar, geom geometry);
INSERT INTO geometries VALUES
('Point', 'POINT(0 0)'),
('Linestring', 'LINESTRING(0 0, 1 1, 2 1, 2 2)'),
('Polygon', 'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
('PolygonWithHole', 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))'),
('Collection', 'GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))');
SELECT name, ST_AsText(geom) FROM geometries;
上面的示例创建了一个表(geometries),然后向该表中插入5个几何图形数据(geometry):
最后,查询表中的数据并输出。
为了符合Simple Features for SQL(SFSQL)规范,PostGIS提供了两张表用于追踪和报告数据库中的几何图形(这两张表中的内容相当于元数据):
geometry_columns视图的结构
让我们来看一下数据库中的geometry_columns表,像原先那样将以下命令粘贴到查询工具中:
SELECT * FROM geometry_columns;
通过查询该表,GIS客户端和数据库可以确定检索数据时的预期内容,并可以执行任何必要的投影、处理、渲染而无需检查每个几何图形(geometry)—— 这些就是元数据所带来的作用。
注意:如果nyc数据库的表没有指定26918的srid,那该怎么办呢?通过更新表很容易修复:
SELECT UpdateGeometrySRID('nyc_neighborhoods','geom',26918);
Simple Features for SQL(SFSQL)规范是PostGIS开发的原始指导标准,它定义了如何表示真实世界的对象。
通过形成连续的图形并以固定的分辨率对其进行数字化,实现了对真实世界的合理表示。
SFSQL只规定了对真实世界对象的二维表示,然而,PostGIS已自行扩展了3维和4维的表示。最近,SQL-Multimedia Part 3(SQL/MM)规范正式定义了它们自己的三维表示。
示例的表包含不同几何图形类型的混合。我们可以使用读取几何图形元数据的函数获取每个对象的基本信息:
SELECT name, ST_GeometryType(geom), ST_NDims(geom), ST_SRID(geom)
FROM geometries;
空间点(Point)表示地球上的单个位置。点由单个坐标表示(包括2维、3维或4维)。
当详细的细节(例如形状和大小)在目标空间尺度上不重要时,真实世界中的对象可以直接用点表示。例如,世界地图上的城市可以描述为点,而在一幅州地图中可以将城市表示为多边形。
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Point';
针对点的一些特定空间函数包括:
所以,我们这样来读取一个点图形的坐标值:
SELECT ST_X(geom), ST_Y(geom)
FROM geometries
WHERE name = 'Point';
纽约市地铁站(nyc_subway_stations)表是一个以点表示的数据集。以下SQL查询将返回一个点图形数据(在ST_AsText列中):
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
LIMIT 1;
线串(Linestring)是表示两个或多个位置之间的路径,它的形式是由两个或多个点组成的有序序列。道路和河流通常表示为线串。
如果线串的起始点和结束点是同一个点,则称其是闭合的(closed),可以使用ST_IsClosed函数进行测试。
如果线串不与自身交叉或接触(如果线串是闭合的,则排除结束点),则称其是简单的(simple),可以使用ST_IsSimple函数进行测试。
线串既可以是闭合的,也可以是简单的。
纽约的街道网络数据(nyc_streets)在前面的章节中已经加载到数据库中了,这个数据集包含名称和类型等详细信息。
一条真实的街道可能由许多线串组成,每条线串代表一段具有不同属性特征的道路。
以下SQL查询将返回一个线串图形的信息(在ST_AsText列中)
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Linestring';
用于处理线串的一些特定空间函数包括:
所以,我们的线串的长度为:
SELECT ST_Length(geom)
FROM geometries
WHERE name = 'Linestring';
多边形(Polygon)是区域的表示形式。多边形的外部边界由一个环(Ring)表示(外环),这个环是一个线串,如上面定义的,它既是闭合的,又是简单的。多边形中的孔(hole)也由环表示(内环)。
多边形用于表示重视大小和形状这两个特征的地理对象。城市边界、公园、建筑或水体都通常需要表示为多边形,当比例尺足够大时,可以观测它们的面积。道路和河流有时也可以表示为多边形。
以下SQL查询将返回两个多边形图形的信息(在ST_AsText列中):
SELECT ST_AsText(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
注意:我们不是在WHERE子句中使用"="符号,而是使用LIKE运算符执行字符串匹配操作。你可能习惯使用"*"符号作为模式匹配中的单字符或多字符匹配,但在SQL中,使用"%"符号和LIKE运算符来告诉系统执行全局匹配。
第一个多边形只有一个环(外环),第二个多边形有一个内部的"孔洞(hole)"(内环),大多数图形系统都包含多边形的概念,但GIS系统在允许多边形有内环方面是比较独特的。
关于多边形图形的一些特定空间函数包括:
我们可以使用空间函数计算多边形的面积:
SELECT name, ST_Area(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
请注意,带内环的多边形的面积是多边形外环的面积(10 x 10正方形)减去内环的面积(1 x 1正方形)
有四种图形集合(Collection)类型,它们将多个简单几何图形组合为图形集合:
集合更多地出现在GIS软件中,而不是在通用图形软件中。
集合对于将真实世界的对象直接建模为空间对象非常有用。例如,如何对被路权(路权指交通参与者的权利)分割的多个道路部分进行建模?答案是将其作为MultiPolygon建模,其组成部分位于路权的两侧。
使用MutiPolygon对路权建模
我们示例中的几何图形集合包含一个多边形和一个点:
SELECT name, ST_AsText(geom)
FROM geometries
WHERE name = 'Collection';
用于处理图形集合的一些特定空间函数:
在数据库中,几何图形(Geometry)以仅供PostGIS使用的格式存储在磁盘上。为了让外部程序插入和检索有用的几何图形信息,需要将它们转换为其他应用程序可以理解和解析的格式。
幸运的是,PostGIS支持以多种格式进行几何图形的输入和输出。
①Well-known text(WKT)
②Well-known binary(WKB)
③Geographic Mark-up Language(GML)
④Keyhole Mark-up Language(KML)
⑤GeoJson
⑥Scalable Vector Graphics(SVG)
以上函数最常见的用法是将几何图形的文本(text)表示形式转换为内部表示形式:
请注意,除了具有几何图形表示形式的文本参数外,还可以指定一个提供几何图形SRID的数字参数。
以下SQL查询展示了一个WKB表示形式的示例(将二进制输出转换为ASCII格式以进行打印时,需要调用encode()):
SELECT encode(
ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),
'hex');
在本教程中,将使用WKT,以确保你能够理解我们正在查看的几何图形。但是,在大多数实际生产环境中(如查看GIS应用程序中的数据、将数据传输到web客户端或远程处理数据),WKB是首选的格式。
由于WKT和WKB是在SFSQL规范中定义的,因此它们不能处理3维或4维的几何图形。对于这些情况,PostGIS定义了Extended Well Known Text(EWKT)和Extended Well Known Binary(EWKB)格式以用于处理3维或4维的几何图形。
它们提供了与WKT和WKB相同的格式化功能,并且是在增加了维度的情况下。
以下是WKT中三维(3D)线串示例:
SELECT ST_AsText(ST_GeometryFromText('LINESTRING(0 0 0,1 0 0,1 1 2)'));
注意:文本表示形式发生了变化!这是因为PostGIS的文本输入程序在使用方面是自由的。它可以使用:
但是在输出端,ST_AsText()只返回ISO标准的WKT格式。
除了ST_GeometryFromText函数之外,还有许多其他方式可以从WKT或类似的格式输入中创建几何图形:
-- Using ST_GeomFromText with the SRID parameter
SELECT ST_GeomFromText('POINT(2 2)',4326);
-- Using ST_GeomFromText without the SRID parameter
SELECT ST_SetSRID(ST_GeomFromText('POINT(2 2)'),4326);
-- Using a ST_Make* function
SELECT ST_SetSRID(ST_MakePoint(2, 2), 4326);
-- Using PostgreSQL casting syntax and ISO WKT
SELECT ST_SetSRID('POINT(2 2)'::geometry, 4326);
-- Using PostgreSQL casting syntax and extended WKT
SELECT 'SRID=4326;POINT(2 2)'::geometry;
除了用于各种格式(WKT、WKB、GML、KML、JSON、SVG、MVT等)的输出函数外,PostGIS还有各种格式(WKT、WKB、GML、KML、JSON等)的输入函数。
大多数应用程序使用WKT或WKB几何图形创建函数,但是也可以使用其他格式的几何图形创建函数。
下面是一个使用GML输入和输出JSON的示例:
SELECT ST_AsGeoJSON(ST_GeomFromGML('1,1 '));
到目前为止,我们看到的WKT字符串都是'text'类型,我们使用PostGIS的函数ST_GeomFromText()将它们转换为'gometry'类型。
PostgreSQL包含一个简短形式的语法,允许数据从一种类型转换到另一种类型,即类型转换语法:
olddata::newtype
例如,将double类型转换为文本字符串类型:
SELECT 0.9::text;
以下SQL语句将一个WKT字符串转换成一个几何图形(geometry):
SELECT 'POINT(0 0)'::geometry;
关于使用类型转换语法创建几何图形,需要注意一点:除非指定SRID,否则将得到一个包含未知SRID的几何图形。
可以使用EWKT形式指定SRID,该形式可以在前面包含一个SRID:
SELECT 'SRID=4326;POINT(0 0)'::geometry;
ST_Area: Returns the area of the surface if it is a polygon or multi-polygon. For “geometry” type area is in SRID units. For “geography” area is in square meters.
ST_AsText: Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata.
ST_AsBinary: Returns the Well-Known Binary (WKB) representation of the geometry/geography without SRID meta data.
ST_EndPoint: Returns the last point of a LINESTRING geometry as a POINT.
ST_AsEWKB: Returns the Well-Known Binary (WKB) representation of the geometry with SRID meta data.
ST_AsEWKT: Returns the Well-Known Text (WKT) representation of the geometry with SRID meta data.
ST_AsGeoJSON: Returns the geometry as a GeoJSON element.
ST_AsGML: Returns the geometry as a GML version 2 or 3 element.
ST_AsKML: Returns the geometry as a KML element. Several variants. Default version=2, default precision=15.
ST_AsSVG: Returns a Geometry in SVG path data given a geometry or geography object.
ST_ExteriorRing: Returns a line string representing the exterior ring of the POLYGON geometry. Return NULL if the geometry is not a polygon. Will not work with MULTIPOLYGON
ST_GeometryN: Returns the 1-based Nth geometry if the geometry is a GEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRING, MULTICURVE or MULTIPOLYGON. Otherwise, return NULL.
ST_GeomFromGML: Takes as input GML representation of geometry and outputs a PostGIS geometry object.
ST_GeomFromKML: Takes as input KML representation of geometry and outputs a PostGIS geometry object
ST_GeomFromText: Returns a specified ST_Geometry value from Well-Known Text representation (WKT).
ST_GeomFromWKB: Creates a geometry instance from a Well-Known Binary geometry representation (WKB) and optional SRID.
ST_GeometryType: Returns the geometry type of the ST_Geometry value.
ST_InteriorRingN: Returns the Nth interior linestring ring of the polygon geometry. Return NULL if the geometry is not a polygon or the given N is out of range.
ST_Length: Returns the 2d length of the geometry if it is a linestring or multilinestring. geometry are in units of spatial reference and geography are in meters (default spheroid)
ST_NDims: Returns coordinate dimension of the geometry as a small int. Values are: 2,3 or 4.
ST_NPoints: Returns the number of points (vertexes) in a geometry.
ST_NRings: If the geometry is a polygon or multi-polygon returns the number of rings.
ST_NumGeometries: If geometry is a GEOMETRYCOLLECTION (or MULTI*) returns the number of geometries, otherwise return NULL.
ST_Perimeter: Returns the length measurement of the boundary of an ST_Surface or ST_MultiSurface value. (Polygon, Multipolygon)
ST_SRID: Returns the spatial reference identifier for the ST_Geometry as defined in spatial_ref_sys table.
ST_StartPoint: Returns the first point of a LINESTRING geometry as a POINT.
ST_X: Returns the X coordinate of the point, or NULL if not available. Input must be a point.
ST_Y: Returns the Y coordinate of the point, or NULL if not available. Input must be a point.