PostGIS五分钟入门【空间数据库】

news2024/11/15 4:30:18

在本文中,我们将介绍 PostGIS 的一些基础知识及其功能,以及一些可用于简化解决方案或提高性能的提示和技巧。

在这里插入图片描述

推荐:用 NSDT设计器 快速搭建可编程3D场景。

简而言之 - PostGIS 是一个 Postgres 扩展,增加了对存储和操作空间数据类型的支持。 当我们构建在地图上存储、操作和可视化数据的软件应用程序时,我们通常需要使用空间数据存储。 我们可以使用谷歌地图或类似应用程序作为典型地理空间可视化软件功能的一个很好的例子。

在我们使用 PostGIS 功能之前,我们需要在 Postgres 中安装扩展:

CREATE EXTENSION IF NOT EXISTS postgis;

1、空间数据类型

PostGIS 支持几种不同类型的(地理)空间数据类型。 他们中的大多数人在平面设计领域都有“表亲”。 但与对象坐标相对于屏幕或一张纸的图形软件不同,地理空间坐标参考地球表面的点。 这使得在地图上呈现此类对象成为可能,而且还可以分析它们之间的交互。 当我们开始使用空间对象和操作来解决现实世界的问题时,这将派上用场。

1.1 矢量 - Vectors

与图形设计软件类似,空间矢量数据支持基本的几何形状,如点、线串和多边形。 除了基本的几何图形,PostGIS 还支持一些更高级的几何图形:

  • 多版本的基本几何图形 - 点、线串或多边形的同质集合
  • 基本几何图形的 3D 版本 - 与添加了 Z 坐标的基本几何图形相同
  • 几何集合——任意几何的集合,同质的或异质的
  • 多面体曲面 - 复杂的 3D 曲面

地图和导航应用程序严重依赖矢量对象来模拟地图的特征。 查看下面的屏幕截图,Google 地图上的大多数对象都可以表示为多边形(例如建筑物)或点(例如企业)或线(例如道路)。 在 3D 模式下查看地图时,建筑物通常表示为多面体表面。
在这里插入图片描述

要使用“geometry”数据类型创建一个表,我们可以运行下面的语句:

CREATE TABLE building (
	id UUID PRIMARY KEY,
	geom geometry
);

这将创建一个表,其中包含几何类型的“geom”列,这是所有矢量对象的通用类型。 将其视为 OOP 世界中的基类。 这意味着我们可以在同一列中组合点、线、多边形和其他矢量对象。 如果我们事先知道我们将处理哪些几何图形,我们可以将其指定为列类型定义的一部分。 在这种情况下,PostGIS 将不允许在同一列中插入其他几何类型。 这始终是存储数据的首选方式,因为某些操作希望几何图形具有相同的类型。

CREATE TABLE building (
	id UUID PRIMARY KEY,
	geom geometry(Polygon)
);

此外,我们还可以在列类型定义中包含 SRID(空间参考标识符),强制所有值都符合相同的 SRID。 稍后将更详细地介绍 SRID。

CREATE TABLE building (
	id UUID PRIMARY KEY,
	geom geometry(Polygon,4326)
);

1.2 栅格 - Rasters

空间栅格数据类型也类似于它的图形设计表亲(JPEG、PNG、TIFF 和我们日常生活中使用的其他栅格文件),但存在一些差异。

与一个像素是屏幕或纸上的一个点的常规栅格不同,空间栅格具有定义像素宽度和高度的空间分辨率。 因此,空间栅格的每个像素都覆盖了地图上大小一致的矩形。
空间栅格有一个或多个波段,每个波段都有一个所有“像素”值的矩阵。 每个波段的数据类型是单独设置的,几乎可以是任何数字类型——二进制(对屏蔽有用)、整数或浮点值。 在某种程度上,它是我们在图形设计领域中习惯使用的 24 位 RGB 光栅的概括。 24 位 RGB 栅格的空间等效项是 3 波段栅格,其中每个波段都定义为无符号 8 位整数。 然而,由于可以灵活地存储除颜色之外的任何数值,我们可以利用栅格来存储各种信息——地形高程、人口密度、植被信息或指标等。
在这里插入图片描述

栅格数据支持包含在一个单独的 postgis 扩展中,在我们可以使用之前需要安装它:

CREATE EXTENSION IF NOT EXISTS postgis_raster;

然后我们可以使用栅格类型创建一个表:

CREATE TABLE satellite_image (
	id UUID PRIMARY KEY,
	rast raster
);

1.3 点云

点云数据格式可以看作是栅格和矢量之间的混合。 它在某种程度上类似于栅格,表示离散数据集,由单个点而不是形状组成。 然而,与光栅不同的是,它没有分辨率或密度,因此点可以位于 3D 空间中的任何位置。 将点云与矢量类型进行比较——它类似于 3D 矢量点的集合。

点云数据通常是从 LiDAR、3D 扫描仪或测量 3D 空间中物体物理特性的类似设备获得的。 可视化时,它看起来类似于下图。 树木(或任何其他物体)看起来像连续的 3D 物体,但它们都是由空间中的离散点组成的。

在这里插入图片描述

点云支持包含在一个单独的 postgis 扩展中,在我们可以使用栅格之前需要安装它:

CREATE EXTENSION pointcloud;
CREATE EXTENSION pointcloud_postgis;

2、空间操作

在处理“常规”非空间数据时,我们通常根据包含表示对象标识符(整数、字符串或可能是 UUID)的原始值的列中的精确值来连接和过滤表。 这是由于我们通常在关系数据库中解决的问题的性质。 对非空间数据集的典型查询可能看起来像这样:

SELECT *
FROM book b
INNER JOIN publisher p ON p.id = b.publisher_id;

或者这样:

SELECT *
FROM book b
WHERE b.publisher_id = 12345;

然而,对于空间数据,我们通常没有真实世界的用例要求我们通过相等性过滤空间对象或通过使用相等性比较器匹配空间对象来连接表。 如果我们在使用 Google 地图应用程序时想一想它是如何工作的——缩放、平移、单击对象,我们可以推断出对空间数据最常用的操作是交集。 每当我们平移或缩放地图时,系统都需要确定应从存储中获取哪些对象并在屏幕上呈现。 这通常是通过将对象与代表地图可见部分的矩形相交来完成的。 下面的查询查找与地图上给定矩形相交的建筑物:

SELECT *
FROM building b
WHERE ST_Intersects(b.geom, ST_MakeEnvelope(24, 47, 25, 48, 4326));

另一个常用的操作是距离计算,它通常用于确定哪些对象位于地图上给定点的附近。

3、空间索引

在对原始值进行索引时,数据库通常使用 Hash 或 B-Tree 来构建索引。 由于通常用于空间数据的操作有所不同,因此不能在此处应用此方法。 空间索引需要以一种允许我们从与给定空间对象相交的空间对象集合中有效地找到空间对象的方式构建。

为了解决这个问题,空间索引使用 R-Tree(“Rectangle”中的“R”)结构,它构建了一个矩形树,其中每个子节点矩形都包含在父节点矩形中。 树的叶子是代表 PostGIS 列中空间对象边界框的矩形。
在这里插入图片描述

这样,我们可以快速遍历树以找到哪些对象与给定对象相交,而不是检查每个对象是否相交。 这将过滤操作的时间复杂度从 O(N) 降低到 O(logN)。

创建空间索引的 SQL 命令与“常规”索引创建非常相似:

CREATE INDEX building_geom_idx ON building USING GIST(geom);

这里唯一的区别是“GIST”部分,它向 PostGis 发出信号,表明我们需要为此索引使用“通用索引结构”。 PostGIS 支持三种空间索引(GIST、SPGIST 和 BRIN),但在大多数情况下,GIST 是一个不错的选择。

值得注意的是,空间索引也可以用于栅格数据,因为我们经常需要快速找到相关栅格。 相同的语法可以应用于栅格列,但在这种情况下,我们在栅格图像周围索引边界框,因此该语句需要包含 ST_ConvexHull 函数。

CREATE INDEX satellite_image_rast_idx ON satellite_image USING GIST(ST_ConvexHull(rast));

与任何索引一样,在将对象插入数据库时存在性能折衷,因为 PostGIS 需要将新对象插入 R-Tree 索引。 但是每当我们计划使用空间操作时,我们应该考虑为查询中使用的列添加索引,因为它会显着提高性能。

4、坐标系标识 - SRID

SRID(spatial reference identifier)是我们需要给每个空间对象赋予属性的重要信息。 它包括有关坐标系的信息、(0, 0) 点在地球上的位置、坐标的分辨率以及地图上的坐标如何与地球上的实际点相对应。

最常用的 SRID 是 WGS84 — SRID 4326 用于 GPS 跟踪、谷歌地图和许多其他应用程序,但是还有更多的 SRID 很受欢迎,有些在全球某些地区提供比 WGS84 更高的精度。 所以我们总是需要知道进入系统的数据的 SRID。

PostGIS 在涉及 SRID 时非常灵活。 在上面的示例中,我们创建了一个表“building”,其中包含一个没有指定 SRID 的几何列。 这意味着 PostGIS 将允许插入具有任何 SRID 的多边形。 在我们无法预测或更改传入数据的 SRID 的情况下,这有时很有用,甚至是必要的,但应尽可能避免。

空间列也可以有一个预定义的 SRID,它强制该列中的所有对象使用指定的 SRID。

CREATE TABLE building (
	id UUID PRIMARY KEY,
	geom geometry(Polygon, 4326)
);

在所有对象上使用统一的 SRID 的第一个原因是空间查询需要相同 SRID 的对象,如果我们尝试与不同 SRID 的对象相交,将会失败:

SELECT ST_Intersects(
	ST_MakeEnvelope(24, 47, 25, 48, 4979), 
	ST_MakeEnvelope(24, 47, 25, 48, 4326)
);

将提示如下错误:

ERROR:  ST_Intersects: Operation on mixed SRID geometries (Polygon, 4979) != (Polygon, 4326)

这个问题有一个解决方法,但它会导致下一个缺点。 每当我们有不匹配的 SRID 时,我们可以将一个空间对象转换为另一个对象的 SRID。

SELECT ST_Intersects(
	ST_Transform(ST_MakeEnvelope(24, 47, 25, 48, 4979), 4326), 
	ST_MakeEnvelope(24, 47, 25, 48, 4326)
);

在此查询中,ST_Transform 将所有坐标从源 SRID 转换为目标 SRID,并输出一个 SRID 为 4326 的多边形,该多边形可以与另一个多边形相交而不会出现错误。

但是,这种方法会带来性能损失。 首先,这种变换需要一些时间。 更重要的是,我们将无法使用空间索引来提高 ST_Intersects 操作的性能,因为空间索引适用于原始 SRID 中的几何图形,而不适用于目标 SRID 中的转换几何图形。 查询执行计划将需要在第一个表上执行表扫描,以确定哪些对象与第二个表中的对象相交,在转换为目标 SRID 之后。

处理此问题的一种方法是在将所有对象插入数据库时对所有对象执行 ST_Transform,并始终保持 SRID 之间的一致性。 这有很多好处,但值得注意的是,对象转换并不总是精确的,从一个 SRID 转换到另一个 SRID 时我们会损失一些精度。 如果精度对软件至关重要,那么将原始对象和转换后的对象都存储在数据库中并交替使用它们可能是个好主意。

5、结束语

本文简要介绍了 PostGIS、它是什么、它支持的一些空间数据类型和操作以及可以利用 PostGIS 解决的一些现实问题。 我们还介绍了空间索引,这是获得最佳性能的第一站。 希望它有助于攀登陡峭的学习曲线进入 GIS 世界。


原文链接:PostGIS快速入门 — BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/505556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyQt5桌面应用开发(11):摸鱼也要讲基本法之桌面精灵

本文目录 PyQt5桌面应用系列鼠标不要钱,手腕还不要钱吗?PyQt5源程序python文件资源定义界面定义文件 技术要素资源文件StyleSheetsQMainWindow设置窗体几何 结论 PyQt5桌面应用系列 PyQt5桌面应用开发(1):需求分析 PyQ…

orbslam3 编译时 Thirdparty sophus 库多种错误 redefinition, not declared in this scope

问题 在装了 ROS 的机器人系统里编译 orbslam3 时, 发现 Thirdparty sophus 库密集报错, 导致 orbslam3 无法完成编译 排查 同样的代码在装了 ROS 的笔记本 ubuntu18.04 系统里可以成功通过编译, 但是在装了同版本 ROS 的机器人 ubuntu18.04 系统里无法编译 Sophus 库本身…

探秘力扣之谜:如何轻松解决最长公共前缀问题?

本篇博客我会讲解力扣中的“14. 最长公共前缀”这道题,这是题目链接。 先来审题: 以下是几个输出示例: 提示: 这道题的思路其实并不难,也是一些字符串的常规操作的结合。大家可以先思考一下,再来听我讲…

TCP和UDP数据报文详解(区别及三次握手四次挥手详解)

总结TCP和UDP详解在后文 相同点: 1.都是传输层协议 2.都是全双工通信 区别: TCPUDP面向连接无连接一对一一对一,一对多,多对多,多对一(单播,多播,广播)可靠不保证可靠交付面向字节流面向报…

java变量与方法

方法 构造方法 定义:构造方法是一个特殊的成员方法,名字必须与类相同,在创建对象时由编译器自动调用,并且在生命周期内只调用一次 演示: 特性: 1.构造方法名字必须与类名相同(如果不同&#…

Ajax XML

文章目录 AJAX XML 实例AJAX XML 实例实例解析 loadXMLDoc() 函数AJAX 服务器页面 AJAX XML 实例 AJAX 可用来与 XML 文件进行交互式通信。 AJAX XML 实例 下面的例子将演示网页如何使用 AJAX 来读取来自 XML 文件的信息&#xff1a; 代码部分 <!DOCTYPE html> <h…

Oracle—数据恢复

文档结构 1、恢复原理1.1、recyclebin&#xff08;回收站&#xff09;相关操作 2、恢复场景2.1、定义删除2.2、记录删除2.2.1、undo恢复2.2.2、redo恢复2.2.3、dbms_logmnr 场景&#xff1a;在 Oracle数据库使用过程中&#xff0c;误删对象或误删记录的情况时有发生&#xff1b…

07- 算法解读 Faster_R-CNN (目标检测)

要点&#xff1a; Faster_R-CNN RPN Fast R-CNN GitHub地址&#xff1a;vision/torchvision/models/detection at main pytorch/vision GitHub 三 Faster_R-CNN Faster R-CNN 是作者 Ross Girshick 继 Fast R-CNN 后的又一力作。同样使用 VGG16 作为网络的 backbone &am…

Windows 10 安装安卓子系统 WSA(Magisk/KernelSU)使用 WSA 工具箱安装 APK

from https://blog.zhjh.top/archives/XokySA7Rc1pkVvnxAEP5E 前提是系统为 Windows 10 22H2 10.0.19045.2311 或更高版本&#xff0c;尽量新。 步骤 使用 WSAPatch 和 MagiskOnWSALocal 安装 WSA 在 Microsoft Store 中安装 Ubuntu LTS&#xff08;或你喜欢的发行版&#xf…

Linux的进程

目录 一、进程占用的内存资源 二、进程的系统环境 三、进程一直在切换 四、父进程和子进程 五、进程状态 六、查看进程 1.ps -ef 列出所有进程 2.ps -lax 列出所有进程 3.ps aux列出所有进程 4.树形列出所有进程 七、作业&#xff08;用来查看管理进程&#xff09; …

windows环境安装运行kafka

一、配置java环境变量 1、下载安装包 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2、添加系统变量&#xff1a;JAVA_HOMED:\Program Files (x86)\Java\jdk1.8.0_144 二、安装zooKeeper 1、 下载安装包 http://zookeeper.apache.…

【Java笔试强训 34】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;收件人列…

eks实践案例

Eks&#xff1a; ami-0c23197c88296c1b5 eks集群&#xff1a; 拉面 - 知乎 https://blog.csdn.net/saynaihe/category_12204222.html 什么是 Amazon EKS&#xff1f; - Amazon EKS kubectl 使用指南 https://zhuanlan.zhihu.com/p/364994610 k8s HPA自动伸缩 手把手教你 K8…

centOS7忘记登录密码该如何重新修改登录密码

文章目录 前言一、重新修改登录密码1.1、第一步1.2、第二步1.3、第三步1.4、第四步1.5、第五步1.6、第六步1.7、第七步1.8、第八步 前言 忘记密码并不可怕&#xff0c;只要学会方法&#xff0c;密码随时都可以找回。 一、重新修改登录密码 1.1、第一步 当打开centOS7之后忘记…

flutter系列之:做一个修改组件属性的动画

文章目录 简介flutter中的动画widgetAnimatedContainers使用举例总结 简介 什么是动画呢&#xff1f;动画实际上就是不同的图片连续起来形成的。flutter为我们提供了一个AnimationController来对动画进行详尽的控制&#xff0c;不过直接是用AnimationController是比较复杂的&a…

Colab使用教程(自己胡乱弄了半天,发现不行,还是得学一下)

文章目录 在google云盘中创建笔记本&#xff0c;并红设置笔记本的运行环境常见设置挂载云硬盘更改工作目录移动训练数据防止断链设置方法一、控制台设置方法二、安装Colab Alive 训练结果保存到硬盘中相关链接 在google云盘中创建笔记本&#xff0c;并红 云盘链接&#xff0c;…

K公司项目文件管理系统的分析与设计_kaic

摘 要 2020年的新冠疫情促进了线上办公市场的发展&#xff0c;加快了企业进入全面数字化时代的脚步。办公自动化是当今的大趋势&#xff0c;越来越多的企业采用电子文档的形式存储内外部资料。K公司是一家致力于为政府和企业提供数据安全服务的小型B2B企业&#xff0c;公司承…

Nessus 10.5 Auto Install for macOS Ventura(自动化安装 Nessus 试用版)

发布 Nessus 试用版自动化安装程序&#xff0c;支持 macOS Ventura、RHEL 9 和 Ubuntu 22.04 请访问原文链接&#xff1a;https://sysin.org/blog/nessus-auto-install-for-macos/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.o…

STM32输入捕获之快速构建频率计

简介&#xff1a;配置好STM32 CUBE IDE后只需要额外7行代码就可以构建一个频率计&#xff0c;目前只计算测频&#xff0c;占空比测量需要加入下降沿捕获标记&#xff08;暂时没做&#xff09;。 一、原理 频率&#xff1a;单位时间内完成周期性变化的次数&#xff0c;f 1/T。…

如何裁剪图片大小尺寸?

如何裁剪图片大小尺寸&#xff1f;平时我们在工作或者学习的时候&#xff0c;会经常需要将图片上传到不同的网站或者平台上&#xff0c;然而上传的时候经常会受到尺寸的限制&#xff0c;有时候尺寸太大就需要变小&#xff0c;为了确保上传成功&#xff0c;我们需要将图片进行裁…