PostGIS中geometry与geography的区别

作者:WuMY

摘要:除了geometry,PostGIS还定义了geography,用于不同的场景需求。以下通过实战对比介绍geometry与geography之间的差异、适用场景及互转方法。

geography基础介绍

与geometry不同的是,geography原生支持地理坐标(也称为大地坐标或经纬度坐标),基于球面模型进行函数分析和计算。下图为两个坐标系:
在这里插入图片描述

geometry与geography对比

以下列举了二者在各个维度间的对比:

对比项geometrygeography
名称几何对象地理对象
坐标系支持平面坐标系和球面坐标系仅支持球面坐标系
对象类型支持 POINT、MULTIPOINT、LINESTRING、LINEARRING、MULTILINESTRING、POLYGON、MULTIPOLYGON、POLYHEDRALSURFACE、TRIANGLE、TIN、GEOMETRYCOLLECTION等简单对象,还支持CIRCULARSTRING、COMPOUNDCURVE、CURVEPOLYGON、MULTICURVE、MULTISURFACE仅支持POINT、LINESTRING、POLYGON、MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION
函数限制类型较丰富支持类型较少,仅支持类型转换、长度面积距离计算、交并差运算函数
索引局限性几何索引不能正确处理极地地区查询地理索引可以正确处理覆盖极点或国际日期变更线的查询
元数据geometry_columns:提供了数据库中所有空间数据表的描述信息,分别是数据库名、模式名、空间数据表名,属性列名称,几何图形维度,空间参考标识符,几何图形类型无定义的元数据,需自定义

根据geometry与geography的特点,在使用时可根据以下情况选择:

geometrygeography
如果数据在地理范围上是紧凑的(包含在州、县或市内),推荐使用基于笛卡尔坐标的geometry类型如果需要测量在地理范围上是分散的数据集(覆盖世界大部分地区)距离,推荐使用geography类型。
当做数据存储时,推荐使用geometry由于地理坐标较为精确,因此在进行距离、面积等量算时,建议使用geography
如果用户较为了解投影信息知识,推荐使用geometrygeography不需要了解专业的投影知识只需要知道经纬度就可以进行计算,因此使用门槛较低
当场景需要运用大量复杂函数时,推荐使用geometrygeography的支持函数较少,且计算复杂,因此应用时需要占用较多计算资源。

geometry与geography应用实践

首先我们分别使用geometry和geography类型通过ST_Distance计算北京到昆明之间的距离,空间参考设置为SRID=4326

--geometry对象计算距离
SELECT ST_Distance(
  'SRID=4326;POINT(116.415767 39.916042)'::geometry,    -- Beijing
  'SRID=4326;POINT(102.833963 24.916456)'::geometry     -- Kunming
  );
--结果
20.234944528360142 

可以看到,采用geometry在平面坐标系上计算的结果并不正确

 --转成geography对象计算距离
 SELECT ST_Distance(
  'SRID=4326;POINT(116.415767 39.916042)'::geography,     -- Beijing
  'SRID=4326;POINT(102.833963 24.916456)'::geography      -- Kunming
  );
 --结果
2091929.28729987 

计算结果是2092千米,采用geography对象在球面坐标系计算的结果正确,两点的距离量算为大圆航线的一部分。但是该函数只适用于点对象。那我们可以尝试接入构造函数解决这一问题:

-- ST_GeographyFromText(text)
SELECT ST_Distance(
  ST_GeographyFromText('POINT(116.415767 39.916042)'),    -- Beijing
  ST_GeographyFromText('POINT(102.833963 24.916456)')     -- Kunming
);
--结果
2091929.28729987

可以看到,使用 ST_GeographyFromText(text) 函数计算,也得到了正确的结论。因此在加入其它几何对象的计算需求下,可使用这种方法进行计算,如计算北京到昆明航线离上海的最短距离时,可采用以下做法:

--北京到昆明航线离上海的最短距离,即垂线段距离:
SELECT ST_Distance(
  ST_GeographyFromText('LINESTRING(116.415767 39.916042, 102.833963 24.916456)'), -- Beijing to Kunming
  ST_GeographyFromText('POINT(121.452027 31.242725)')                        -- Shanghai
);
--结果
988436.03069308

得到正确的结果为988千米

geometry与geography互转

为了方便进行准确运算并且可以灵活运用丰富的函数类型,PostGIS提供了二者之间的互转,满足多场景应用。

  • geometry转为geography

为了将geometry数据加载到geography表中,首先需要将geometry转换到EPSG:4326(经度/纬度),然后再将其转换为geography。 ST_Transform(geometry, srid) 函数能将坐标转换为地理坐标,Geography(geometry) 函数能将基于EPSG:4326的geometry数据类型转换为geography数据类型,流程如下:
在这里插入图片描述

--使用ST_Transform(geometry, srid)和Geography(geometry)两个嵌套函数将nyc_subway_stations示例数据从geom转换为geog
CREATE TABLE nyc_subway_stations_geog AS
SELECT
  Geography(ST_Transform(geom,4326)) AS geog,
  name,
  routes
FROM nyc_subway_stations;

同时,当数据量大时,支持创建空间索引,在geography表上构建空间索引与在geometry表上构建空间索引的方法完全相同:

--创建GiST索引类型
CREATE INDEX nyc_subway_stations_geog_gix
ON nyc_subway_stations_geog USING GIST (geog);
  • geography转为geometry

虽然geography类型的空间函数可以解决许多问题,但有时仍需要使用geometry类型支持的其他空间函数,需要将对象从geography转换为geometry。以下city表为例:

--GEOGRAPHY的列名为geog
CREATE TABLE city (
    code VARCHAR(3),
    geog GEOGRAPHY(Point)
  );

INSERT INTO city
  VALUES ('BJ', 'POINT(116.41 39.916042)');
INSERT INTO city
  VALUES ('KM', 'POINT(102.833963 24.956)');
INSERT INTO city
  VALUES ('SH', 'POINT(121.452 31.245)');

利用SQL语句查询geography元数据,可以看到geography给city表的geog列指定了默认的srid=4326:

SELECT * FROM geography_columns;

结果如下:
在这里插入图片描述

利用类型转换方法,函数将geog转为geometry类型,并调用 ST_X 方法读取转换后的坐标:

SELECT code, ST_X(geog::geometry) AS longitude FROM city;

结果为如下图,可以看到采用类型转换的方法,并不会改变geometry本身的坐标值。

在这里插入图片描述

总结:

以上通过各类实战系统对比了geometry与geography从本质上的差别、二者的适用场景及相互转换的方法。更多信息可参考Yukon在线帮助

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值