九月 23, 2024
摘要:地理空间数据在许多领域变得越来越重要,从城市规划到环境科学。在本教程中,我们将演示用于处理此类数据的基础 PostGIS 查询。
目录
地理空间数据和 PostGIS 简介
地理空间数据包含了有关地球上位置的信息,需要专门的工具才能有效使用。PostGIS 是一个功能强大的 PostgreSQL 扩展,可将 PostgreSQL 数据库转换为一个功能齐全的地理信息系统(GIS)。使用 PostGIS,您可以直接用 SQL 来存储地理对象、运行空间查询和执行高级分析。对于任何需要处理基于位置的数据的人员,这使其成为了他们的必备工具。
安装 PostGIS 允许您执行空间操作,这通常需要专用的 GIS 软件来完成。无论您是需要计算距离、测量面积还是分析空间关系,PostGIS 都能为您提供高效处理复杂空间数据所需的工具。
在本教程中,我们将向您介绍 PostGIS 的基础知识。我们将从简单的空间查询开始,然后转向邻近分析和网络分析等高级技术。
我们的地理空间样例数据
在本文中,我们将使用从加利福尼亚 San Francisco 提取的空间数据集。我们将会使用到几个表:
-
sf_tram_stops
:此表包含了全市有轨电车站的位置;它还存储了位置坐标,以及该停靠点是否可以在线路之间换乘。它包含以下列:id
– 每个停靠点的唯一标识符。coordinates
– 停靠点的位置坐标。transfer_possible
– 乘客是否可以在该站换乘电车。
-
sf_planning_districts
:此表定义了 San Francisco 规划区的边界;这些信息对于市区分析至关重要。它包含以下列:id
– 每个规划区的唯一标识符。name
– 规划区的名称。boundaries
– 规划区的边界(作为位置坐标)。
-
sf_bicycle_routes
:此表存储了有关城市自行车路线的信息;您将会需要此数据来分析 San Francisco 的自行车基础设施。它包含以下列:id
– 每条自行车路线的唯一标识符。course
– 路线的过程。condition_rating
– 路线的评级(基于其条件)。
-
sf_restaurants
:此表列出了有关 San Francisco 餐厅的信息,包括其名称、位置、评级和美食类型。它包含以下列:id
– 每个餐厅的唯一标识符。name
– 餐厅的名称。food_type
– 这家餐厅供应的美食类型。rating
– 餐厅的评级。coordinates
– 餐厅的位置坐标。
-
sf_sights
:此表记录了城市内著名地标和景点(POI)的信息。它包含以下列:id
– 每个景点的唯一标识符。name
– 景点的名称。coordinates
– 景点的位置。
-
sf_atms
:此表存储了 San Francisco 的 ATM 的详细信息,包括每个 ATM 的位置以及运营它的公司。它包含以下列:id
– 每个 ATM 的唯一标识符。company
– 运营此 ATM 的公司。coordinates
– ATM 的位置。
这些数据将是我们要探索的空间查询的基础。我们将使用这些查询来分析地标和便利设施之间的接近度,计算规划区内的面积等等。每个查询都将展示,PostGIS 如何帮助您从空间数据中提取有意义的见解。
使用 PostGIS 进行基础的空间查询
使用 PostGIS 将地理空间数据存储在 PostgreSQL 中后,您就可以开始查询它了!空间查询允许您,根据地理的位置、形状和空间关系,来选择、筛选和操作数据。那么,让我们来开始使用地理空间数据。
可视化地理空间数据
首先,让我们看看地理空间数据是什么样的。在这里,我们为乘客可以换乘的那些站点,查询其电车站 ID 和坐标:
SELECT
id,
coordinates
FROM sf_tram_stops
WHERE transfer_possible = true;
结果如下所示:
id | coordinates |
---|---|
1 | 0101000020E610000030D80DDB16995EC0742497FF90CE4240… |
4 | 0101000020E61000000DAB7823F3985EC010AFEB17ECCE4240… |
5 | 0101000020E6100000FDD98F1491995EC07AC7293A92CF4240… |
… |
如您所见,坐标列中的地理空间数据并不是真正可读的。要使它真正可用,您需要专门的软件来在地图上绘制它。使用一种内置的地图,您可以查看这些电车站的位置:
将地理空间数据转换为文本
也许您会想,在没有地图的情况下,来查看上述电车站的位置坐标。您可以使用以下查询将数据转换为人类可读的坐标:
SELECT
id,
ST_AsText(coordinates),
ST_Y(coordinates),
ST_X(coordinates)
FROM sf_tram_stops
WHERE transfer_possible = true;
此查询使用 PostGIS 函数ST_AsText
以一种可读格式获取坐标。它使用ST_Y
和ST_X
来提取纬度和经度值。下面是部分结果:
id | st_astext | st_y | st_x |
---|---|---|---|
1 | POINT(-122.39202 37.6138) | 37.6138 | -122.39202 |
2 | POINT(-122.38984 37.61658) | 37.61658 | -122.38984 |
3 | POINT(-122.39948 37.62165) | 37.62165 | -122.39948 |
… |
空间关系
PostGIS 提供了多种功能来探索地理空间对象的空间关系。让我们快速回顾一下它们。
ST_Intersection
此函数返回两个几何形状的共享部分(即交集)。以下查询显示 Downtown 市区边界内的所有自行车路线(或其部分):
SELECT
sfbr.id,
ST_Intersection(sfpd.boundaries, sfbr.course)
FROM sf_bicycle_routes sfbr
JOIN sf_planning_districts sfpd
ON ST_Intersects(sfpd.boundaries, sfbr.course)
WHERE sfpd.name = 'Downtown';
ST_Intersection
函数查找两个形状重叠的区域:在本例中,自行车路线穿过 “Downtown” 市区的边界。ST_Intersects
函数检查自行车路线和市区边界是否相互接触或交叉,确保仅包含那些相互接触或交叉的路线。
下面是文本形式的部分结果:
id | st_intersection |
---|---|
409 | 0102000020E61000000C000000438F3471DF9A5EC058F13A2… |
441 | 0102000020E6100000100000007451E9429B995EC0EF7A00F.. |
412 | 0102000020E610000009000000ED6FEAA8999A5EC06469EB2.. |
… |
地图形式的结果如下:
ST_Contains
ST_Contains
函数检查一个几何形状是否完全包含另一个几何形状。要列出包含来自 Crown Financial 公司的 ATM 的规划区,您可以运行这个查询:
SELECT DISTINCT sfn.name
FROM sf_planning_districts sfn
JOIN sf_atms sfa
ON ST_Contains(sfn.boundaries, sfa.coordinates)
WHERE sfa.company = 'Crown Financial Inc.';
结果如下:
name |
---|
Downtown |
Northeast |
ST_Within
ST_Within 函数还会检查一个几何形状是否完全位于另一个几何形状中。下面查询查找 Northeast 市区评分高于 4.0 的餐厅:
SELECT
sep.name,
sep.coordinates
FROM sf_planning_districts spd
JOIN sf_restaurants sep
ON ST_Within(sep.coordinates, spd.boundaries)
WHERE rating > 4.0
AND spd.name = 'Northeast';
此查询返回餐馆的名称和坐标,使其易于在地图上可视化。
name | coordinates |
---|---|
Fast Duck | 0101000020E6100000B9FC87F4DB995EC02E73BA2C26E64240 |
Red Curry | 0101000020E6100000569FABADD8995EC0E1455F419AE54240 |
The Saloon | 0101000020E6100000D52137C30D9A5EC0431CEBE236E64240 |
距离和面积计算
计算距离和面积是处理地理空间数据的另一个基本方面。这些计算可以帮助回答,诸如 “此 ATM 距离特定景点有多远” 或 “此规划区的面积是多少” 等问题。
距离计算
ST_Distance
函数返回两个地理空间对象之间的距离。它需要两个几何形状的参数:ST_Distance(geometryA, geometryB)
。
要可视化位于 Fisherman’s Wharf 景点 300 米范围内的所有 ATM,您可以使用以下查询:
SELECT
sa.id,
sa.coordinates,
ST_Distance(
ST_Transform(sa.coordinates, 26910),
ST_Transform(ss.coordinates, 26910)) AS distance
FROM sf_sights ss
JOIN sf_atms sa
ON ST_Distance(
ST_Transform(sa.coordinates, 26910),
ST_Transform(ss.coordinates, 26910)) < 300
WHERE ss.name = 'Fisherman''s Wharf';
在此查询中,ST_Transform
函数将给定的坐标转换为适合空间计算的特定坐标系。坐标系可确保所有空间操作(如距离计算)都准确,且与地理区域和工程的特定需求相关。
在此查询中,我们使用由 SRID(空间参考系统标识符)26910 定义的坐标系,它对应于 NAD83 / UTM zone 10N 系统。该系统通常用于 San Francisco 地区的精确距离计算。
如何找到正确的 SRID?尝试以下网站之一:
- 空间参考网站:使用 EPSG 选项卡。
- io:键入国家名称、地区代码或坐标系名称,以搜索和获取所有可能的坐标参考系统。
- EPSG-registry.org
通过转换坐标,查询可确保 ATM 和 Fisherman’s Wharf 景点之间的距离计算是精确的。结果如下:
id | coordinates | distance |
---|---|---|
132 | 0101000020E6100000FC00A436719A5EC009FEB7921DE74240 | 189.1839552624224 |
133 | 0101000020E61000000D897B2C7D9A5EC033A7CB6262E74240 | 277.9680083048927 |
135 | 0101000020E61000000E15E3FC4D9A5EC0650113B875E74240 | 216.11656973079064 |
136 | 0101000020E6100000910A630B419A5EC033FE7DC685E74240 | 283.89507791796825 |
面积计算
要计算规划区的面积,请使用ST_Area
函数。这采用几何形状的参数(ST_Area(geometry)
),并返回结果形状的面积。
这是查询。请注意,我们再次使用 SRID = 26910 作为我们的坐标系:
SELECT
ST_Area(ST_Transform(boundaries, 26910))
FROM sf_planning_districts
WHERE name = 'Buena Vista';
结果如下:
st_area |
---|
2617829.8666631826 |
当 SRID = 26910 时,默认单位是米。因此,ST_Area
的结果以平方米为单位。
高级空间分析
随着您对 PostGIS 的熟练程度越来越高,可以使用其高级功能来执行深入的空间分析。这些技术允许您探索空间关系、执行邻域分析,甚至进行网络分析,从而让您对地理空间数据的洞察更具可操作性。
缓冲和邻域分析
缓冲会在空间特征周围创建区域。这在邻域分析中特别有用,因为在邻域分析中,您需要确定某些特征彼此之间的接近程度。例如,如果您想识别 “Palace of Fine Arts” 景点半径 3000 米内的所有餐厅,您可以使用ST_DWithin
函数:
SELECT
sep.name,
sep.rating,
sep.food_type,
sep.coordinates,
ST_Distance(
ST_Transform(sep.coordinates, 26910),
ST_Transform(ss.coordinates, 26910)) AS distance
FROM sf_sights ss
JOIN sf_restaurants sep
ON ST_DWithin(
ST_Transform(sep.coordinates, 26910),
ST_Transform(ss.coordinates, 26910),
3000)
WHERE ss.name = 'Palace of Fine Arts';
以下是表格和地图形式的结果:
name | rating | food_type | coordinates | distance |
---|---|---|---|---|
Olive | 2.10 | Greek | 0101000020E6100000C9AB730CC89A5EC0527E52EDD3E54240 | 2764.17980825426 |
La fragranza | 4.86 | Italian | 0101000020E61000008811C2A38D9D5EC038F3AB3940E44240 | 2361.1920187470487 |
叠加操作
在地图绘制中,叠加操作允许我们查看不同的地理信息集匹配或交互的程度。假设您有两张地图,一张显示城市中的所有公园,另一张显示易受洪水影响的区域。通过将一张地图放在另一张地图上,您可以找出哪些公园有洪水风险。这个过程有助于我们理解和可视化不同地理特征的重合之处;它让规划、分析和决策更加高效。
以下查询使用ST_Union
函数,将所有 “recreational” 规划区的边界合并成一个统一的几何形状:
SELECT
ST_Union(boundaries)
FROM sf_planning_districts
WHERE type = 'recreational';
同样,您可以使用ST_Intersection
来完成相同的任务。
网络分析
网络分析涉及检查路线、识别最短路线以及提高交通网络内的出行效率。这对于了解和优化交通系统和连接至关重要。PostGIS 在搭配pgRouting
使用时,为此类分析提供了强大的工具。
pgRouting 扩展提供了用于路线优化的高级算法。最著名的功能之一是pgr_dijkstra
函数;它通过考虑道路类型、交通状况和其他变量等因素,来计算两点之间的最短或最快路线。此函数在导航系统、物流规划、运输管理等方面的价值不可估量。通过利用此类扩展,用户可以增强路线规划、减少出行时间,并提高整体交通网络的效率。