PostGIS数据库中的几种复杂查询举例

news/2024/7/23 10:42:24 标签: 数据库, GIS, PostGIS, 空间查询

本文包含以下内容:

  1. 利用索引
  2. 空间查询SQL示例

有效地使用PostGIS需要知道哪些空间功能可用,并确保适当的索引可用以提供良好的性能。这些示例中使用的SRID 312仅用于演示。您应该使用spatial_ref_sys表中列出的REAL SRID,并使用与数据投影相匹配的REAL SRID。如果数据未指定空间参考系统,则应仔细考虑为什么没有这样做,也许应该这样做。

如果是因为要建模的对象没有定义地理空间参考系统,例如分子的内部结构或尚未建造的游乐园的平面图,那很好。但是,如果已经计划了游乐园的位置,那么,只要确保游乐部分不会侵入已经存在的结构,就应该对该位置使用合适的平面坐标系。

即使计划在发生核大屠杀的情况下进行火星探险以运送人类,并且您想要绘制火星行星以进行人类居住的情况,也可以使用非地球坐标系,例如火星2000并将其插入spatial_ref_sys表中。尽管此火星坐标系是非平面的(以球面度为单位),但您可以将其与地理类型一起使用,以长度和接近度单位以米(而非度)为单位。

1. 利用索引

构造查询时,重要的是要记住,只有基于边界框的运算符(如&&)才能利用GiST空间索引。 诸如ST_Distance()之类的函数无法使用索引来优化其操作。 例如,在大型表上,以下查询将非常慢:

SELECT the_geom
FROM geom_table
WHERE ST_Distance(the_geom, 'SRID=312;POINT(100000 200000)') < 100

该查询正在选择geom_table中所有在点(100000,200000)的100个单位内的几何。 这会很慢,因为它正在计算表中每个点与我们指定点(即)之间的距离。 表中的每一行都进行一次ST_Distance()计算。 我们可以通过使用单步索引加速函数ST_DWithin减少所需的距离计算次数来避免这种情况:

SELECT the_geom
FROM geom_table
WHERE ST_DWithin(the_geom, 'SRID=312;POINT(100000 200000)', 100)

该查询选择相同的几何形状,但是它以更有效的方式执行。 假设the_geom上有一个GiST索引,查询计划者将认识到可以在计算ST_Distance()函数的结果之前使用该索引减少行数。 注意,在&&操作中使用的ST_MakeEnvelope几何是一个以原始点为中心的200单位的方形框-这是我们的“查询框”。 &&运算符使用索引将结果集快速缩减为仅具有边界框与“查询框”重叠的那些几何。 假设我们的查询框比整个几何表的范围小得多,这将大大减少需要完成的距离计算的数量。

2. 空间查询SQL示例

本节中的示例将使用两个表,一个线性道路表和一个多边形市政边界表。 bc_roads表的表定义为:

Column      | Type              | Description
------------+-------------------+-------------------
gid         | integer           | Unique ID
name        | character varying | Road Name
the_geom    | geometry          | Location Geometry (Linestring)

边界数据bc_municipality表的表定义为:

Column     | Type              | Description
-----------+-------------------+-------------------
gid        | integer           | Unique ID
code       | integer           | Unique ID
name       | character varying | City / Town Name
the_geom   | geometry          | Location Geometry (Polygon)

所有道路的总长度是多少(以公里为单位)?

SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM bc_roads;

km_roads
------------------
70842.1243039643
(1 row)

乔治王子城有多少公顷?

SELECT
  ST_Area(the_geom)/10000 AS hectares
FROM bc_municipality
WHERE name = 'PRINCE GEORGE';

hectares
------------------
32657.9103824927
(1 row)

按地区划分,全省最大的直辖市是哪个?

SELECT
  name,
  ST_Area(the_geom)/10000 AS hectares
FROM
  bc_municipality
ORDER BY hectares DESC
LIMIT 1;

name           | hectares
---------------+-----------------
TUMBLER RIDGE  | 155020.02556131
(1 row)
--注意,为了回答这个查询,我们必须计算每个多边形的面积。
--如果我们经常这样做,则可以在表中添加一个Area列,这样我们就可以单独索引以提高性能。 
--通过将结果按降序排列,并使用PostgreSQL的“ LIMIT”命令,我们可以轻松选择最大值,而无需使用诸如max()之类的聚合函数。

每个自治市完全包含的道路长度是多少?

--这是“空间联接”的一个示例,因为我们将来自两个表的数据(进行联接)组合在一起
--但使用空间交互条件(“包含”)作为联接条件,而不是通常的关系方法来联接:
SELECT
  m.name,
  sum(ST_Length(r.the_geom))/1000 as roads_km
FROM
  bc_roads AS r,
  bc_municipality AS m
WHERE
  ST_Contains(m.the_geom, r.the_geom)
GROUP BY m.name
ORDER BY roads_km;

name                        | roads_km
----------------------------+------------------
SURREY                      | 1539.47553551242
VANCOUVER                   | 1450.33093486576
LANGLEY DISTRICT            | 833.793392535662
BURNABY                     | 773.769091404338
PRINCE GEORGE               | 694.37554369147
...
--该查询需要一些时间,因为表中的每条道路都汇总为最终结果
--(对于我们的特定示例表,大约为25万条道路)。 
--对于较小的覆盖图(几百个记录中的数千个记录),响应速度可能非常快。

创建一张包含乔治王子市内所有道路的新表格。

--这是“叠加”的一个示例,它包含两个表并输出一个新表,该表由空间裁剪或剪切的结果组成。
---与上面展示的“空间连接”不同,此查询实际上创建了新的几何。 
---覆盖层就像涡轮增压的空间连接,对于更精确的分析工作很有用:
CREATE TABLE pg_roads as
SELECT
  ST_Intersection(r.the_geom, m.the_geom) AS intersection_geom,
  ST_Length(r.the_geom) AS rd_orig_length,
  r.*
FROM
  bc_roads AS r,
  bc_municipality AS m
WHERE
  m.name = 'PRINCE GEORGE'
	AND ST_Intersects(r.the_geom, m.the_geom);

维多利亚州“道格拉斯街”的公里长度是多少?

SELECT
  sum(ST_Length(r.the_geom))/1000 AS kilometers
FROM
  bc_roads r,
  bc_municipality m
WHERE
	r.name = 'Douglas St'
	AND m.name = 'VICTORIA'
	AND ST_Intersects(m.the_geom, r.the_geom);

kilometers
------------------
4.89151904172838
(1 row)

有洞的最大的自治市多边形是多少?

SELECT gid, name, ST_Area(the_geom) AS area
FROM bc_municipality
WHERE ST_NRings(the_geom) > 1
ORDER BY area DESC LIMIT 1;

gid  | name         | area
-----+--------------+------------------
12   | SPALLUMCHEEN | 257374619.430216
(1 row)

http://www.niftyadmin.cn/n/1372094.html

相关文章

PostGIS中的空间索引(一)

本文介绍如下索引&#xff1a; GISTBRIN 索引使使用空间数据库处理大型数据集成为可能。 如果不建立索引&#xff0c;则对功能的任何搜索都需要对数据库中的每个记录进行“顺序扫描”。 索引通过将数据组织到可以快速遍历以查找特定记录的搜索树中来加快搜索速度。 PostgreSQL…

PostGIS中的空间索引(二)

本文介绍SP-GiST索引及PostGIS中索引的使用&#xff1a; SP-GiST以及如何使用索引 前面的文章介绍了两种索引&#xff0c;本文介绍SP-GiST索引及全部PostGIS中的索引使用方法。 1. SP-GiST 索引 SP-GiST代表“空间分区的通用搜索树”&#xff0c;它是索引的一种通用形式&…

PostGIS系列课程之PostGIS Geometries

介绍 在开始处理数据之前&#xff0c;让我们看一些简单的例子。 继续并在控制台中执行以下SQL语句。 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, …

PostGIS系列课程之Geography

坐标为“地理”或“纬度/经度”的数据非常常见。 与墨卡托&#xff08;Mercator&#xff09;&#xff0c;UTM或Stateplane中的坐标不同&#xff0c;地理坐标不是笛卡尔坐标。 地理坐标不代表在平面上绘制的距原点的线性距离。 而是&#xff0c;这些球坐标描述了地球仪上的角坐标…

PostGIS系列课程之投影Projection

地球不是平坦的&#xff0c;没有简单的方法可以将其放在平面的纸质地图&#xff08;或计算机屏幕&#xff09;上&#xff0c;因此人们想出了各种巧妙的解决方案&#xff0c;每种解决方案各有利弊。有些投影会保留区域&#xff0c;因此所有对象之间的大小都相对。其他投影像墨卡…

PostGIS系列课程之空间关系

本文将逐一介绍空间关系的定义及使用。 空间关系 PostGIS的强大功能是能够计算Geometry之间的空间关系。 通过比较代表自行车位置&#xff0c;街道和地铁线的Geometry 形状&#xff0c;可以回答诸如“距公园最近的自行车架在哪里&#xff1f;”或“地铁线与街道的交叉点在哪里…

鸿蒙开发之DevEco Studio开发Hello World

下载地址 https://developer.harmonyos.com/cn/develop/deveco-studio#download 下载之前需要登录华为账号 目前DevEco Studio只有Windows x64版本。 界面 安装包 安装步骤 第一步 第二步 第三步 第四步 第五步 第六步&#xff1a;安装完成后需要重启 和VsCode的图标很像 等…

5G和GIS将共同驱动未来城市

随着世界变得更加智能&#xff0c;互联程度更高&#xff0c;5G和GIS将共同为未来的城市提供动力。 世界人口的一半生活在城市中&#xff0c;到2050年&#xff0c;这一比例预计将增加到68&#xff05;。随着我们城市生态系统的不断壮大&#xff0c;技术有潜力极大地改善城市居民…