PostGIS Geography Type
地理类型为以“地理”坐标(有时称为“大地”坐标,或“lat/ lat”,或“lon/lat”)表示的空间特征提供了原生支持。地理坐标是用角单位(度)表示的球坐标。
PostGIS几何类型Geometry
的基础是一个平面。平面上两点之间的最短路径是一条直线。这意味着几何图形(面积、距离、长度、交点等)的计算可以使用笛卡儿数学和直线向量进行计算。
PostGIS地理类型Geographic
的基础是球体。球面上两点之间的最短路径是大圆弧。这意味着对地理位置(面积、距离、长度、交叉点等)的计算必须在球面上计算,使用更复杂的数学。为了更精确的测量,计算时必须考虑到世界的实际球形。
由于基础数学要复杂得多,为地理类型定义的函数比为几何类型定义的函数要少。随着时间的推移,随着新算法的添加,地理类型的功能将会扩展。
它使用一种名为geography的数据类型。GEOS函数都不支持地理类型。作为一种变通方法,我们可以在几何和地理类型之间来回转换。
在PostGIS 2.2之前,地理类型只支持WGS 84 long lat (SRID:4326)。对于PostGIS 2.2及以上版本,可以使用spatial_ref_sys表中定义的任何基于长/晚的空间参考系统。您甚至可以添加您自己的自定义球形空间参考系统描述的地理类型不限于地球。
无论您使用哪种空间参考系统,测量返回的单位(ST_Distance, ST_Length, ST_Perimeter, ST_Area)和输入的ST_DWithin都是以米为单位的。
地理类型使用PostgreSQL typmod定义格式,这样就可以在单个步骤中添加带有地理字段的表。除曲线
外,支持所有标准OGC格式。
1.1. Geography Basics 地理基础知识
地理类型不支持曲线、tin或多面体,但支持其他几何类型。如果是SRID 4326,标准几何类型数据将自动转换为地理数据。您还可以使用EWKT和EWKB约定来插入数据。
- POINT:在没有指定srid的情况下创建2D点地理表,默认为4326 WGS 84 long lat:
CREATE TABLE ptgeogwgs(gid serial PRIMARY KEY, geog geography(POINT) );
- 在NAD83 longlat中创建一个具有2D点地理的表:
CREATE TABLE ptgeognad83(gid serial PRIMARY KEY, geog geography(POINT,4269) );
- 创建具有z坐标点的表并显式指定srid
CREATE TABLE ptzgeogwgs84(gid serial PRIMARY KEY, geog geography(POINTZ,4326) );
- LINESTRING
CREATE TABLE lgeog(gid serial PRIMARY KEY, geog geography(LINESTRING) );
- POLYGON
--polygon NAD 1927 long lat
CREATE TABLE lgeognad27(gid serial PRIMARY KEY, geog geography(POLYGON,4267) );
- MULTIPOINT
- MULTILINESTRING
- MULTIPOLYGON
- GEOMETRYCOLLECTION
地理字段在geography_columns系统视图中注册。
现在,检查“geography_columns”视图,查看是否列出了您的表。
您可以使用create table语法创建一个带有GEOGRAPHY列的新表。
CREATE TABLE global_points (
id SERIAL PRIMARY KEY,
name VARCHAR(64),
location GEOGRAPHY(POINT,4326)
);
注意,location列的类型为GEOGRAPHY,并且GEOGRAPHY类型支持两个可选修饰符:一个类型修饰符限制列中允许的形状和尺寸的类型;SRID修饰符,它将坐标引用标识符限制为特定的数字。
类型修饰符允许的值是:POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON。修饰符还支持通过后缀:Z、M和ZM来限制维度。例如,’ LINESTRINGM ‘的修饰符只允许包含三个维度的行字符串,并将第三维度视为度量。类似地,’ POINTZM '也需要四维数据。
如果没有指定SRID,则SRID将默认为4326 WGS84 long/lat,所有计算都将使用WGS84进行。
一旦你创建了你的表,你可以在GEOGRAPHY_COLUMNS表中看到它:
-- See the contents of the metadata view
SELECT * FROM geography_columns;
你可以像使用GEOMETRY列一样将数据插入到表中:
-- Add some data into the test table
INSERT INTO global_points (name, location) VALUES ('Town', 'SRID=4326;POINT(-110 30)');
INSERT INTO global_points (name, location) VALUES ('Forest', 'SRID=4326;POINT(-109 29)');
INSERT INTO global_points (name, location) VALUES ('London', 'SRID=4326;POINT(0 49)');
创建索引的工作原理与GEOMETRY相同。PostGIS将注意到列类型为GEOGRAPHY,并创建一个适当的基于球的索引代替通常用于几何的平面索引。
-- Index the test table with a spherical index
CREATE INDEX global_points_gix ON global_points USING GIST ( location );
查询和测量功能使用米为单位。所以距离参数应该用米来表示,并返回值应该以米为单位(或以平方米为单位)。
-- 显示距离查询,伦敦在1000公里公差之外
SELECT name FROM global_points WHERE ST_DWithin(location, 'SRID=4326;POINT(-110 29)':: geography, 1000000);
通过计算一架从西雅图飞往伦敦的飞机有多近,你可以看到地理的力量在起作用(122.33 47.606, 0.0 51.5)到达雷克雅未克(POINT(-21.96 64.15))。
-- Distance calculation using GEOGRAPHY (122.2km)
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography, 'POINT(-21.96 64.15)'::geography);
-- Distance calculation using GEOMETRY (13.3 "degrees")
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geometry, 'POINT(-21.96 64.15)'::geometry);
测试不同的lon/lat项目。允许在spatial_ref_sys表中列出的任何长尾空间参考系统。
-- NAD 83 lon/lat
SELECT 'SRID=4269;POINT(-123 34)'::geography;
geography
----------------------------------------------------
0101000020AD1000000000000000C05EC00000000000004140
-- NAD27 lon/lat
SELECT 'SRID=4267;POINT(-123 34)'::geography;
geography
----------------------------------------------------
0101000020AB1000000000000000C05EC00000000000004140
-- NAD83 UTM zone meters, yields error since its a meter based projection
SELECT 'SRID=26910;POINT(-123 34)'::geography;
ERROR: Only lon/lat coordinate systems are supported in geography.
LINE 1: SELECT 'SRID=26910;POINT(-123 34)'::geography;
GEOGRAPHY类型计算从雷克雅未克到西雅图和伦敦之间的大圆航线的球面上的真实最短距离。
几何类型计算雷克雅未克和西雅图到伦敦的直线路径之间无意义的笛卡尔距离绘制在世界平面地图上。结果的名义单位可以称为“度”,但结果并不对应于点之间的任何真正的角度差,所以即使称它们为“度”也是不准确的。
1.2. 何时使用地理数据类型而不是几何数据类型
geography类型允许您以经度/纬度坐标存储数据,但需要付出一定的代价:在geography上定义的函数比在GEOMETRY上定义的函数少;那些被定义的函数需要更多的CPU时间来执行。
您所选择的类型应该取决于您正在构建的应用程序的预期工作区域。您的数据是跨越全球或一个大的大陆区域,还是一个州、县或直辖市的本地数据?
-
如果数据包含在一个小区域中,您可能会发现,就可用性能和功能而言,选择适当的投影并使用GEOMETRY是最佳的解决方案。
-
如果您的数据是全球性的或覆盖一个大陆地区,您可能会发现GEOGRAPHY允许您构建一个系统,而不必担心投影细节。将数据存储在经度/纬度上,并使用在GEOGRAPHY上定义的函数。
-
如果您不理解投影,也不想了解投影,并且准备接受地理学中可用功能的局限性,那么对您来说,使用地理学可能比使用几何学更容易。只需将数据加载为经度/纬度,然后从那里出发。
1.3. 地理几何的常见问题
1.3.1. 你是在球面上计算还是在球面上计算?
默认情况下,所有的距离和面积计算都在球体上完成。你会发现,局部区域的计算结果将与局部平面的结果相匹配,在良好的局部投影。在更大的范围内,球面计算将比在投影平面上进行的任何计算都更精确。所有地理函数都可以通过设置最终布尔参数为“FALSE”来选择使用球体计算。这将在一定程度上加快计算速度
1.3.2. 那日期变更线和极点呢?
所有的计算都没有日期变更线或极点的概念,坐标是球形的(经度/纬度),所以从计算的角度来看,穿过日期变更线的形状与其他形状没有区别。
1.3.3. 你能处理的最长弧是多少?
我们用大圆弧作为两点之间的“插补线”。这意味着任何两点实际上都有两种连接方式,这取决于你沿着大圆走的方向。我们所有的代码都假设这些点是由沿着大圆的两条路径中较短的一条连接起来的。因此,弧度大于180度的形状将无法正确建模。
1.3.4. 为什么计算欧洲/俄罗斯/插入大的地理区域的面积这么慢?
因为这个多边形太大了!大区域不好有两个原因:它们的边界很大,所以索引倾向于拉出功能,无论你运行什么查询;顶点的数量是巨大的,并且测试(距离、包容)必须至少遍历顶点列表一次,有时需要遍历N次(N是另一个候选特征中的顶点数量)。与GEOMETRY一样,我们建议,当您有非常大的多边形,但在小区域执行查询时,您可以“去正规化”