类型修饰符

通常,在声明列的数据类型时,需要指定类型修饰符。或者,可以在创建列后使用检查约束实现与类型修饰符相同的效果。例如,可以将列声明为character,然后添加一个检查约束,将长度限制为8.可以对列的任何属性添加约束,但请记住,并非所有约束都是类型修饰符,只有最常用的属性才会升级为类型修饰符。

子类型修饰符

在PostGIS中,geometry和geography数据类型都有子类型。虽然geography和geometry本身就是类型,但是应该避免将列声明为没有子类型修饰符的父类型。例如:geometry(POINT,4326),其中geometry时数据类型,POINT是子类型修饰符,4326时SRID类型修饰符,尽管PostGIS对类型和类型修饰符不区分大小写,但是为例将子类型和其他类型区分开来,通常会将子类型大写。

也可以将GEOMETRY, GEOMETRYZ, GEOMETRYZM用作类型修饰符。这些类型修饰符约束geometry的坐标维度。

在PostGIS中,只有geometry和geography数据类型支持类型修饰符,raster数据类型和topogeometry数据类型均不支持类型修饰符。

空间参考标识符

所有的PostGIS空间数据类型都有一个空间参考标识符。如果希望“叠加”两种PostGIS数据类型的数据,就必须使它们共用一个SRID。可以使用PostGIS函数ST_Transform()将数据类型从一种SRID转换为另一种。如果SRID未被指定但已知,你可以使用ST_SetSRID()进行设置。

PostGIS依赖于spatial_ref_sys表来确定一个SRID是否有效以及如何有效在SRID之间进行重投影转换。spatial_ref_sys表为在PostGIS安装过程中唯一创建和填充的表。大多数所需要的SRID已经包含在spatial_ref_sys中。可以添加缺少的SRID,需要确保包含重投影信息。

可将SRID保留为未知——对于geometry、raster和topogeometry类型,未知的SRID的值为0,geography类型数据的SRID不能是未知的;如果未指定,则假设为4326。未知的SRID任然意味着数据处于笛卡尔坐标空间中,即使他没有地理位置意义。

几何

在PostGIS诞生之初,几何是唯一可用的数据类型。geometry数据类型之所以如此命名,是因为它的基础是解析几何。所有geometry子类型

都假定一个笛卡尔坐标系:平行线永不相交,勾股定理适用,坐标之间的距离是一致的,等等。

点的子类型通过他们所在的笛卡尔空间(X,Y,Z)的维数区分。此外,它还可以包含measured(M)坐标值,该值可表示任何类型的测量值。

geometry和geography类型中的POINT子类型修饰符有以下几种。

  • POINT:2D空间中由X和Y坐标指定的点。

  • POINTZ:3D空间中由X、Y、Z坐标制定的点。

  • POINTM:2D空间中带测量值的点,由X和Y坐标加上M值指定。

  • POINTZM:3D空间中带测量值的点,由X、Y和Z坐标加上M值指定。

CREATE TABLE ch02.my_points (
 id serial PRIMARY KEY,
 p geometry(POINT),
 pz geometry(POINTZ),
 pm geometry(POINTM),
 pzm geometry(POINTZM),
 p_srid geometry(POINT,4269)
 );
 INSERT INTO ch02.my_points (p, pz, pm, pzm, p_srid)
 VALUES (
 ST_GeomFromText('POINT(1-1)'),
 ST_GeomFromText('POINT Z(1-1 1)'),
 ST_GeomFromText('POINT M(1-1 1)'),
 ST_GeomFromText('POINT ZM(1-1 1 1)'),
 ST_GeomFromText('POINT(1-1)',4269)
 );

除最后一个点未指定SRID。未指定时,SRID值为0。SRID4269代表是是1983北美标准Lon/Lat (NAD 83)

线串

两个或多个不通电之间连接的直线形成线串(linestring)。点和点之间的单单独线称为线段(segment)。在PostGIS中,线段不是数据类型或子类型,但一个线串可能只有一个线段。

虽然线串是用一组有限的点来定义的,但实际上它由无数个点构成,每个线段定义一条直线。当需要确定线串上距离多边形或其它几何形状最近的点时,这种区别就变得清晰起来。最近的点很少与用于定义线串的任何点重合,但介于两点之间。

像点一样,线串也因维度不同而有以下四种变体。

LINESTRING:由两个或多个不同POINT指定的2D线串。

LINESTRINGZ:由两个或多个不同的POINTZ指定的3D空间线串。

LINESTRINGM:由两个或多个不同的POINTM指定的带测量值的2D空间线串。

LINGSTRINGZM:由两个或多个不同的POINTZM指定的带测量值的3D空间线串。

CREATE TABLE ch02.my_linestrings (
 id serial PRIMARY KEY,
 name varchar(20),
 my_linestrings geometry(LINESTRING)
 );                                    

 INSERT INTO ch02.my_linestrings (name, my_linestrings)
 VALUES
 ('Open', ST_GeomFromText('LINESTRING(0 0, 1 1, 1-1)')),  
('Closed', ST_GeomFromText('LINESTRING(0 0, 1 1, 1-1, 0 0)'))
 ;

在开放线串中,起点和终点不同。而在闭合线串中,起点和终点是同一个点,线串形成一个环。

描述线串时,也可以用简单和非简单几何图形的概念。对于简单线串,除非在起点和终点,否则不能自相交(不能与自身交叉)。线串中每个点都会强制执行此限制。自相交的线串不是简单线串。

多边形

闭合线串时多边形的构成要素。

多边形包含所有封闭区域及其边界(构成周长的线串)。组成多边形边界的闭合线串称为多边形的环,具体来讲是外环。

 ALTER TABLE ch02.my_geometries ADD COLUMN my_polygons geometry(POLYGON);
 INSERT INTO ch02.my_geometries (name, my_polygons)
 VALUES (
 'Triangle',
 ST_GeomFromText('POLYGON((0 0, 1 1, 1-1, 0 0))')
 );

在地理建模中,一个环围绕着大多数多边形,但多边形可以有多个环,从而雕刻出孔洞。准确地说,一个多边形必须只有一个外环,并且可以有一个或多个内环。每个内部环在整个多边形中创建一个孔。这就是为什么在多边形的文本表示中需要一组看似冗余的括号。众所周知,多边形的文本表示(WKT)是一组封闭的线串。第一个表示外环,后面所有的都表示内环。总是在WKT中包含额外的圆括号,即使多边形只有一个环。有些工具可以容忍只有一对括号的单环多边形,但PostGIS不行。

多边形具有有效性的概念。有效多边形的环只能在不同的点相交——环不能重叠,他们不能共享一个边界。如果一个多边形的内环有一部分位于外环外,那么该多边形也是无效的。

PostGIS有处理无效几何图形的函数。可以使用ST_IsValid()

,如果几何图形有效,该函数将返回true。ST_IsValidReason详细描述了几何图形无效的原因,如果几何图形有效,该函数则返回Valid Geometry。对于具有几种无效原因的几何图形,可以使用函数ST_IsValidDetail,它详细说明了几何图形无效的原因,每行列出一个原因。如果几何图形有效,它将返回true,但不提供额外的细节。最后可以使用函数ST_MakeValid将无效的几何图形转换为有效的几何图形。此过程可能会更改几何图形的类型,例如将多边形更改为多边形几何或几何图形集合。它会尽可能地保留原始几何图形中的点。

几何图形集合

几何图形集合将逻辑上应在一起的不同几何图形分成一组。

在PostGIS中,每个geometry子类型都有一个对应的几何:点集合、线串集合和多边形集合。

此外PostGIS还包含一种名为geometrycollection的数据类型。只要集合中的所有几何图形具有相同的空间参考系和相同的坐标维度,该数据类型就可以包含任何类型的geometry图形。

点集合

点集合:若干点的集合

如果点集合只有X和Y坐标,那么每个逗号分隔的值将有两个坐标。

 SELECT ST_GeomFromText('MULTIPOINT(-1 1, 0 0, 2 3)');

如果有记录高度的坐标,则可以用Z坐标;如果有记录非空间性质的坐标,呢么可以使用M坐标。M坐标被称为度量坐标,通常用于度量时间或其他类型,如英里标记位置。

由X Y Z M的点集合,会有四个坐标:

SELECT ST_GeomFromText('MULTIPOINT ZM(-1 1 3 4, 0 0 1 2, 2 3 1 2)');

由X Y Z组成的常规3D点集合,代码如下:

SELECT ST_GeomFromText('MULTIPOINT Z(-1 1 3, 0 0 1, 2 3 1)');

由X Y M组成的点的集合,必须写成MULTIPOINT M,以区别X Y Z组成的点集合

SELECT ST_GeomFromText('MULTIPOINT M(-1 1 4, 0 0 2, 2 3 2)');

另一种可接受的用WKT表示点集合的方法是使用括号分隔每个点,比如:MULTIPOINT ( (-1 1), (0 0), (2 3) )

PostGIS支持这种多括号格式和更加简单的MULTIPOINT (-1 1, 0 0, 2 3)。

ST_AsText 和 ST_AsEWKT之类的输出函数会返回无括号格式

线串集合

线串集合是线串组成的集合。

注意线串WKT表示形式中每个单独线串外的额外圆符号。

 SELECT ST_GeomFromText('MULTILINESTRING((0 0,0 1,1 1), (-1 1,-1-1))');
 SELECT ST_GeomFromText('MULTILINESTRING ZM ((0 0 1 1,0 1 1 2,1 1 1 3), (-1 1 1 1,-1-1 1 2))');
 SELECT ST_GeomFromText('MULTILINESTRING M((0 0 1,0 1 2,1 1 3), (-1 1 1,-1 -1 2))');

因为M坐标无法可视化显示,所以MULTILINESTRING 和 MULTILINESTRING M代码具有相同的可视化图形。

简单性适用于所有线串类型的几何图形。如果组成线串集合的所有线串都是简单的,且除了边界点之外的任何点都不相交,则线串集合被认为是简单的。如果使用两个相交的简单线串创建一个线串集合,那么生成的线串集合不是简单的。

多边形集合

多边形集合WKT中的括号比单个多边形的括号还要多。因为使用括号表示多边形的每个环,所以需要用另一组外括号表示多边形集合。对于多边形集合,强烈建议遵循PostGIS惯例,对于单环多边形,不要省略任何内括号。

SELECT 'MULTIPOLYGON(
 ((2.25 0,1.25 1,1.25-1,2.25 0)),
 ((1-1,1 1,0 0,1-1))
 )'::geometry;
 SELECT 'MULTIPOLYGON Z(
 ((2.25 0 1,1.25 1 1,1.25-1 1,2.25 0 1)),
 ((1-1 2,1 1 2,0 0 2,1-1 2))
 )'::geometry;
 SELECT 'MULTIPOLYGON ZM(
 ((2.25 0 1 1,1.25 1 1 2,1.25-1 1 1,2.25 0 1 1)),
 ((1-1 2 1,1 1 2 2,0 0 2 3,1-1 1 4))
 )'::geometry;
 SELECT 'MULTIPOLYGON M(
 ((2.25 0 1,1.25 1 2,1.25-1 1,2.25 0 1)),
 ((1-1 1,1 1 2,0 0 3,1-1 4))
 )'::geometry;

可以使用函数ST_GeomFromText 或 'somewktwkb'::geometry将WKT转换为geometry。这两种方法几乎是等价的,只是 ::geometry编写起来稍微短一点,并且可以与其它集合字符串表达式一起使用。从PostGIS 3.1开始,::geometry可以用于将geoJSON字符串格式转换为PostGIS geometry类型。

一个有效的多边形集合必须秀以下两个条件:

  • 组成多边形集合的每个多边形本身必须有效

  • 组成多边形集合的多边形不能重叠。一旦你放置了一个多边形,后续的多边形就不能覆盖在它上面。

几何图形集合

几何图形集合是一个可以包含异构集合图形的PostGIS geometry子类型。几何图形集合可以包含点、线串、多边形、和这几类集合图形的集合。他甚至可以包含其它集合图形集合。简而言之,可以将PostGIS中已知的任何geometry子类型塞进几何图形集合中。

几何图形集合不使用ST_GeomFromText 和 WKT 表示形式构建几何图形集合,而是通过使用函数 ST_Collect收集更简单的几何图形来构建。

 SELECT ST_AsText(ST_Collect(g))
 FROM (
 SELECT ST_GeomFromText('MULTIPOINT(-1 1, 0 0, 2 3)') As g
 UNION ALL
 SELECT ST_GeomFromText(
 'MULTILINESTRING((0 0, 0 1, 1 1), (-1 1,-1-1))'
 ) As g
 UNION ALL
 SELECT ST_GeomFromText(
 'POLYGON(
 (-0.25-1.25,-0.25 1.25, 2.5 1.25, 2.5-1.25,-0.25-1.25),
 (2.25 0, 1.25 1, 1.25-1, 2.25 0),
 (1-1, 1 1, 0 0, 1-1)
 )'
 ) As g
 ) x;

在实际的使用中,很少会将数据列定义为geometrycollection。尽管对于存储目的来说集合的使用是完全合理的,不应在函数中使用它,这几乎没有任何意义。

如果geometrycollection中的所有几何图形都有效,则认为该集合有效。如果其中任意一个集合图形都无效,则集合无效。

M坐标

M坐标是为了方便记录空间坐标中各点的测量值而设置的附加坐标。

M坐标不需要任何空间含义,因此不收X Y Z这些空间坐标的参考系统的影响。它可以使正的,也可以是负的,它的单位与空间坐标的单位没有关系。将geometry装换为另一空间参考系统时,M坐标不发生改变。所有与M有关的PostGIS函数都将M坐标视为线性的,可以沿M维进行插值。

使用建议:

  • M坐标的支持今年有所增加,但仍然相当有限。

  • M坐标经常用于表示时间,因此你会发现函数ST_IsValidTrajectory可以确定M是否沿着矢量递增,而函数ST_ClosestPointOfApproach和ST_LocateAlong可以确定两条轨迹何时在哪个店最接近。

  • 不要将M用于稀疏的数据。一旦引入了M维,所有的集合对象都必须有M坐标。如果大多数数据点没有M值,则需要采用一些约定的做法标记丢失的数据。坐标不能有空值。

  • 对M值的使用应当保持一致。例如,如果使用 M坐标表示温度或海洋深度,则必须保持单位的一致性。

  • 虽然可以自由地使用任何数值填充坐标,但尽量使用M表示线性测量值,而不是对数测量值。

  • 引入M坐标后,应避免使用疑问函数和应用空间概念。

Z坐标

不能仅凭geometry有Z坐标就认为它是一个立体几何图形。三维空间坐标中的多边形仍然是2D几何图形,它有面积但没有体积 。

PostGIS 2引入了新的以ST_3D为前缀的关系和测量函数,专门用于处理X Y Z坐标空间中的子类型。常见的有ST_3DIntersects、ST_3DDinstance、用于3D半径搜索的ST_3DDWithin、ST_3DMaxDistance和ST_3DClosestPoint。PostGIS 2还引入了n维空间索引,它考虑了Z坐标和M坐标。默认空间索引忽略了Z坐标和M坐标。

多面体表面和TIN

假设3D空间中存在若干多边形,将他们的边缘粘在一起,会形成一个名为多面体表面的拼接图形。

索然多边形集合和多面体表面都是由多边形组成的,但他们之间有一个根本区别:多边形集合中的多边形不能共享边,而多面体表面中的多边形必定共享边。

多面体表面的构造中还有两个限制:

多边形不能重叠,而且每个边最多只能与另一条边重合

在PostGIS及后续版本中,有一个ST_MakeSolid函数,它能够将闭合的多面体表面标记为立体图形

ST_Dimension将闭合的多面体表面返回数值3.

TIN代表不规则三角网。他是多面体表面的子集,组成它的所有多边形都必须是三角形。TIN被广泛用于描述地形表面。

生成三面多面体表面的两种方法。

SELECT ST_GeomFromText(
 'POLYHEDRALSURFACE Z (
 ((12 0 10, 8 8 10, 8 10 20, 12 2 20, 12 0 10)),
 ((8 8 10, 0 12 10, 0 14 20, 8 10 20, 8 8 10)),
 ((0 12 10,-8 8 10,-8 10 20, 0 14 20, 0 12 10))
 )'
 );-- Which can be generated using-
SELECT ST_Extrude(ST_GeomFromText(
 'LINESTRING(12 0 10, 8 8 10, 0 12 10,-8 8 10)'),
 0, 2, 10
 );

功能解析:

  • ST_GeomFromText:这是 PostGIS 中最基础的几何构造函数,用于将 WKT (Well-Known Text) 格式的字符串转换为 PostgreSQL 中的几何对象。

  • POLYHEDRALSURFACE Z:表示这是一个三维 (Z) 的多面体表面。多面体由多个闭合的多边形环组成,每个环定义一个面。

  • 坐标结构:每个点由X Y Z三个值表示,例如12 0 10代表 X=12,Y=0,Z=10 的点。

  • 几何结构:这段 WKT 定义了一个由三个四边形面组成的立体结构:

    1. 第一个面:由点 (12,0,10)、(8,8,10)、(8,10,20) 和 (12,2,20) 构成

    2. 第二个面:由点 (8,8,10)、(0,12,10)、(0,14,20) 和 (8,10,20) 构成

    3. 第三个面:由点 (0,12,10)、(-8,8,10)、(-8,10,20) 和 (0,14,20) 构成

这个多面体实际上是一个三棱柱的一部分,底面是一个三角形,每个面都是一个四边形。

  • ST_Extrude:这是一个高级函数,用于将二维或三维的线串或多边形沿指定方向拉伸生成三维几何体。

  • 输入参数

    • 第一个参数:ST_GeomFromText('LINESTRING(...)')创建了一个三维线串,定义了拉伸的路径。这个线串与前面多面体的底面边缘一致。

    • 后三个参数:0, 2, 10定义了拉伸的方向向量,表示沿 X 轴移动 0 单位,Y 轴移动 2 单位,Z 轴移动 10 单位。

生成TIN

TIN是由名为TRIANGLE的geometry子类型形成的集合子类型。

由4个三角形组成的TIN

 SELECT ST_GeomFromText(
 'TIN Z (
 ((12 2 20, 8 8 10, 8 10 20, 12 2 20)),
 ((12 2 20, 12 0 10, 8 8 10, 12 2 20)),
 ((8 10 20, 0 12 10, 0 14 20, 8 10 20)),
 ((8 10 20, 8 8 10, 0 12 10, 8 10 20))
 )'
 );

曲线几何图形

圆弧串

一个简单的五点圆弧串。WKT表示为CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3)

一个弧的终点是另一个弧的起点,这样的一个或一系列圆弧组成的几何图形名为圆弧串。

圆弧串只包含圆弧,是所有曲线集合图形中最简单的,

ALTER TABLE ch02.my_geometries
 ADD COLUMN my_circular_strings geometry(CIRCULARSTRING);
 INSERT INTO ch02.my_geometries(name, my_circular_strings)
 VALUES
 ('Circle',
 ST_GeomFromText('CIRCULARSTRING(0 0, 2 0, 2 2, 0 2, 0 0)')),
 ('Half circle',
 ST_GeomFromText('CIRCULARSTRING(2.5 2.5, 4.5 2.5, 4.5 4.5)')),
 ('Several arcs',
 ST_GeomFromText('CIRCULARSTRING(5 5, 6 6, 4 8, 7 9, 9.5 9.5, 11 12, 12 12
 )'));

一个圆弧串必定有奇书个点

复合曲线

圆弧串和线串组成一个名为复合曲线(COMPOUNDCURVE)的geometry集合子类型。

使用复合曲线构造的多边形称为曲线多边形(CURVEPOLYGON)。

闭合复合曲线是由圆弧串和规则的线段线串组成的几何图形,其中一段的终点是下一段的起点。

ALTER TABLE ch02.my_geometries
 ADD COLUMN my_compound_curves geometry(COMPOUNDCURVE);
 INSERT INTO ch02.my_geometries (name, my_compound_curves)
 VALUES (
 'Road with curve',
 ST_GeomFromText(
 'COMPOUNDCURVE(
 (2 2, 2.5 2.5),
 CIRCULARSTRING(2.5 2.5, 4.5 2.5, 3.5 3.5),
 (3.5 3.5, 2.5 4.5, 3 5)
 )'
 )
 );

曲线多边形

曲线多边形是外环和内环由圆弧串构成的多边形。

ALTER TABLE ch02.my_geometries
 ADD COLUMN my_curve_polygons geometry(CURVEPOLYGON);
 INSERT INTO ch02.my_geometries (name, my_curve_polygons)
 VALUES
 ('Solid circle',
 ST_GeomFromText('CURVEPOLYGON(
 CIRCULARSTRING(0 0, 2 0, 2 2, 0 2, 0 0)
 )')),
 ('Circles with triangle hole',
 ST_GeomFromText('CURVEPOLYGON(
 CIRCULARSTRING(2.5 2.5, 4.5 2.5, 4.5 3.5, 2.5 4.5, 2.5 2.5),
 (3.5 3.5, 3.25 2.25, 4.25 3.25, 3.5 3.5)
 )')),
 ('Triangle with arcish hole',
 ST_GeomFromText('CURVEPOLYGON(
 (-0.5 7,-1 5, 3.5 5.25,-0.5 7),
 CIRCULARSTRING(0.25 5.5,-0.25 6.5,-0.5 5.75, 0 5.75, 0.25 5.5)
 )'));

几何图形的空间目录

PostGIS附带名为geometry_columns的只读视图,该视图列出了数据库中所有geometry列。geometry_columns视图从PostgreSQL系统目录中读取信息,所有其中的信息与表中定义的更改或geometry列的添加保持同步。

PostGIS还将自动注册视图、物化视图和包含geometry数据类型列的外部表格。

geometry_columns视图的结构如图所示

coord_dimension

coord_dimension是geometry列的坐标维度,允许值2、3、4。

PostGIS最多允许4个维度:X Y Z M。

空间维度有两种——坐标维度和几何维度

空间维度定义空间中线性无关轴的数量。

几何维度描述集合图形的大小和形状。

SRID

SRID表示空间参考标识符,它是与spatial_ref_sys表的主键相关的一个整数。

管理geometry列

更改现有geometry列的SRID

ALTER TABLE us_states
 ALTER COLUMN geom TYPE geometry(MULTIPOLYGON,4326)
 USING ST_SetSRID(geom,4326);

将geometry列转换为geography列

首选转换SRID,然后将其类型强制转换为geography

 ALTER TABLE osm_roads
 ALTER COLUMN way TYPE geography(MULTIPOLYGON,4326)
 USING ST_Transform(way,4326)::geography;

地理

geography和geometry

与geometry不同,geography类型假设所有数据都基于一个大地坐标系(具体来说就是SRID为4326的WGS 84 lon/lat)。

在PostGIS 2.2 之前,geography只支持SRID 4326。在PostGIS 2.2中,geography开始支持任何基于lon/lat的空间参考系统。这意味着PostGIS甚至可以用于探索火星等其他星球。4326目前仍然是默认值。

geography数据类型专门用于大地测量应用程序,因此除了点、线串和多边形等基本类型之外,它不支持其它子类型,也不支持2D以上的空间。

因为geography数据子类型的结构模仿了geometry数据子类型的结构,所以关于geometry的所有内容都适用于geography,仅需要再数据类型和函数名称中将术语geometry替换为geography。

 CREATE TABLE ch02.my_geogs (
 id serial PRIMARY KEY,
 name varchar(20),
 my_point geography(POINT)
 );
 INSERT INTO ch02.my_geogs (name, my_point)
 VALUES
 ('Home',ST_GeogFromText('POINT(0 0)')),
 ('Pizza 1',ST_GeogFromText('POINT(1 1)')),
 ('Pizza 2',ST_GeogFromText('POINT(1-1)'));

geography空间目录

geography_columns视图与geometry_columns视图非常相似,只不过它列出的是数据库中geography类型的列。geography_colums中的大多数列与geometry_columns中的相同,不同的只有一列,在geography——columns视图中,f_geometry_column被替换为f_geography_columns.

栅格

栅格使用像素组织信息;像素,有时称为单元格,是构成栅格的基础。与彩色电视不同,在数据库应用程序中,像素的实际大小和形状并不重要。实际上,每个像素只是数据的空间占位符,仅此而已。

像素按行和列的形式进行组织,形成切片。为了简化操作,每个切片都是矩形的。当谈及栅格切片的带下是,我们值得是水平像素和垂直像素的数量。

像素是未知标识,而不是数据。实际的数据元素是以波段表示。RGB电视栅格内有三个数据波段,每种原色一个。在PostGIS 2.0中,PostGIS栅格可以有多大255个波段,在后续的版本中甚至更多。

栅格的属性

PostGIS栅格数据存储在带有ratser类型列的表中。数据通常是均匀地分成切片的,每行包含大小相同的矩形像素。建议每行的宽度和高度都保持在50~500像素。如果大的栅格不是保存在单个行,而是分成切片以存储在多行中,处理速度会更快。

与其他数据类型不同,栅格数据既可以存储在数据库中,又可以存储在数据库外。当存储在数据库外时,栅格字段只包含定义宽度、高度和几何边界框的元数据,以及栅格切片涉及的文件和文件区域的引用。

栅格宽度和高度

每个栅格切片都有以像素为单位的宽度和高度。

波段

每个栅格可以有多个波段,但至少必须有一个。数据库内的栅格切片最多有65535个波段,数据库外的栅格切片最多有255个波段。

波段像素类型

栅格只能在像素中存储数值。波段的数量决定了每个像素可以存储的值的数量。

像素类型描述像素中指定的波段可以容纳的数字类型。有几种可能的选择:

  • 1位布尔值,缩写为1BB

  • 2 8 16 32位无符号整数,缩写为2BUI 8BUI 16BUI 32BUI

  • 8 16 32位有符号整数,缩写为8BSI 16BSI 32BSI

  • 32 64位浮点类型,缩写为32BF 64BF

目前最常见的像素类型是8BUI。每个波段都为像素定义了唯一的像素类型。除非跨波段,否则不能改变像素类型。可以使用函数ST_BandPixelType获取指定波段的像素类型。

栅格和SRID

地理参考栅格有在空间参考系统中定义的空间坐标,因此有SRID。转换函数可用于将栅格从一个空间参考系统转换到另一个空间参考系统。

像素宽度和高度

对于地理参考栅格,像素用高度和宽度反映测量单位。

读取像素宽度和高度要用到的函数为ST_PixelWidth和ST_PixelHeight。

X和Y的倾斜值

倾斜值通常为0。一般情况下,栅格与空间参考坐标轴对齐,但有时他们会旋转,倾斜角表示栅格相对于地理坐标轴的旋转角度

创建栅格

从PostGIS 3.0开始,栅格类型及其配套函数不在包含在PostGIS 扩展中。要在PostGIS 3+中使用栅格类型,需要执行额外的步骤

 CREATE EXTENSION postgis_raster SCHEMA postgis;

通常使用raster2pgsql之类的加载器在数据库中导入或注册外部栅格。

函数AddRasterConstrains有内置的智能,不必指定要添加的特定约束。

 CREATE TABLE ch02.my_rasters (
 rid SERIAL PRIMARY KEY,
 name varchar(150),
 rast raster
 );
 INSERT INTO ch02.my_rasters (name, rast)
 SELECT
 'quad ' || x::text || ' ' || y::text,
 ST_AddBand(           
ST_MakeEmptyRaster(
 90, 45,
 (x-2) * 90,
 (2-y) * 45,
 1,-1, 0, 0,
 4326
 ),            
'16BUI'::text,
 0
 )
band.
raster rows, WGS 
84 lon/lat.
 FROM generate_series(0,3) As x CROSS JOIN generate_series(0,3) As y;

栅格数据表结构

sql

CREATE TABLE ch02.my_rasters (
 rid SERIAL PRIMARY KEY,
 name varchar(150),
 rast raster
 );

解析:

  • ch02.my_rasters:在ch02模式下创建名为my_rasters的表

  • rid:自增主键,用于唯一标识每条记录

  • name:存储栅格名称的文本字段

  • rast:PostGIS 的核心栅格数据类型,用于存储栅格图像数据

栅格数据插入与生成

sql

INSERT INTO ch02.my_rasters (name, rast)
SELECT
 'quad ' || x::text || ' ' || y::text,
 ST_AddBand(           
ST_MakeEmptyRaster(
 90, 45,
 (x-2) * 90,
 (2-y) * 45,
 1,-1, 0, 0,
 4326
 ),            
'16BUI'::text,
 0
 )
FROM generate_series(0,3) As x CROSS JOIN generate_series(0,3) As y;

解析:

这段代码使用两个嵌套的generate_series函数生成一个 4×4 的网格,共 16 个栅格。让我们分步解析:

生成网格坐标:

sql

FROM generate_series(0,3) As x CROSS JOIN generate_series(0,3) As y
  • generate_series(0,3)生成 0 到 3 的整数序列

  • CROSS JOIN将两个序列组合,生成 16 个坐标对 (x,y)

栅格命名规则:

sql

'quad ' || x::text || ' ' || y::text
  • 为每个栅格生成名称,格式为 "quad X Y",如 "quad 0 0"、"quad 1 2" 等

创建空栅格:

sql

ST_MakeEmptyRaster(
 90, 45,
 (x-2) * 90,
 (2-y) * 45,
 1,-1, 0, 0,
 4326
)
  • 参数说明:

    • 90, 45:栅格的宽度和高度(像素数)

    • (x-2) * 90, (2-y) * 45:栅格左上角的 X 和 Y 坐标,形成一个覆盖全球的网格

    • 1, -1:X 和 Y 方向的像素尺寸(度 / 像素)

    • 0, 0:旋转参数(这里不旋转)

    • 4326:空间参考系统 ID(WGS 84 地理坐标系)

添加栅格波段:

sql

ST_AddBand(..., '16BUI'::text, 0)
  • '16BUI':指定波段数据类型为 16 位无符号整数

  • 0:初始值,所有像素初始化为 0

添加波段

使用UPDATE语句完成此操作。一般情况下,最好在创建栅格时添加所有波段。

UPDATE ch02.my_rasters SET rast = ST_AddBand(rast, '8BUI'::text,0);

应用约束

添加完波段后,需要添加约束,使raster表中的各列正确地注册到raster_columns视图中。

SELECT AddRasterConstraints('ch02', 'my_rasters'::name, 'rast'::name);

栅格空间目录

raster_columns视图时数据库中栅格类型的所有列的目录。

当创建具有raster列数据类型的表或使用raster2pgsql程序导入栅格时,可以在raster_columns视图中看到条目。当使用函数AddRasterContraints添加附加约束时,该视图显示相关的约束信息。raster_columns视图利用应用于栅格列的约束推断键属性。

 SELECT
 r_table_name As tname,r_raster_column As cname,
 srid,
 scale_x As sx, scale_y As sy,
 blocksize_x As bx, blocksize_y As by,
 same_alignment As sa,
 num_bands As nb,
 pixel_types As ptypes
 FROM raster_columns
 WHERE r_table_schema = 'ch02';