PostGIS学习教程十二:地理

PostGIS学习教程十二:地理

坐标为"地理(geographics)“形式或者说是” 纬度(latitude)/经度(longitude)"形式的数据非常常见。

与Mercator(墨卡托)、UTM(通用横轴墨卡托)、Stateplane中的坐标不同,地理坐标不是笛卡尔平面坐标(Cartesian coordinates)。地理坐标并不表示平面上与原点的线性距离,相反,这些球坐标描述了地球上的角坐标。在球坐标中,点由该点与参考子午线(经度)的旋转角度和该点与赤道的角度(纬度)指定。
在这里插入图片描述
你可以将地理坐标看作近似的笛卡尔平面坐标,并继续进行空间计算,然而,关于距离、长度和面积的测量将会是毫无意义的。由于球坐标测量角度距离,因此单位以"度"表示。此外,索引和真/假测试(如相交和包含)可能会变得非常错误,因为越与极点或国际日期线接近的区域,点与点之间的距离变得越大。

例如,下面是洛杉矶(Los Angeles)和巴黎(Paris)的地理坐标:

Los Angeles: POINT(-118.4079 33.9434)
Paris: POINT(2.3490 48.8533)
使用标准的PostGIS笛卡尔平面坐标系空间函数ST_Distance(geometry, geometry)计算洛杉矶和巴黎之间的距离。请注意,SRID 4326声明了地理空间参考系统。

SELECT ST_Distance(
  ST_GeometryFromText('POINT(-118.4079 33.9434)', 4326), -- Los Angeles (LAX)
  ST_GeometryFromText('POINT(2.5559 49.0083)', 4326)     -- Paris (CDG)
);

在这里插入图片描述
啊哈!121!但那是什么意思?

空间参考4326的单位是度,所以我们的答案是121度。但是,这表示什么呢?

在地球球体上,1度对应的地球实际距离的大小是变化的。当远离赤道时,它会变得更小,当越接近两极时,地球上的经线相互之间越来越接近。因此,121度的距离并不意味着什么,这是一个没有意义的数字。

为了计算出真实的距离,我们不能把地理坐标近似的看成笛卡尔平面坐标,而应该把它们看成是球坐标。我们必须把两点之间的距离作为球面上的真实路径来测量——大圆(大圆被定义为过球心的平面和球面的交线)的一部分。

从1.5版开始,PostGIS通过地理(geography)数据类型提供此功能。

注意:不同的空间数据库有不同的"处理地理"的方法:

当SRID是地理坐标系统时,Oracle试图通过透明地进行地理计算来掩盖差异
SQL Server使用两种空间类型,一种是针对笛卡尔平面坐标数据的"STGeometry",另一种是针对地理坐标系统数据的"StGeography"
Informix Spatial是Infomix的纯笛卡尔扩展插件,而Informix Geodetic是纯地理扩展插件,也就是说Infomix使用两种插件来分别处理笛卡尔坐标系问题和地理坐标系问题。
与SQL Server类似,PostGIS使用两种数据类型:“geometry"和"geography”
关于上面的测量应该使用geography而不是geometry类型。也就是说使用geography这种数据类型时,PostGIS的内部计算是基于实际地球球体来计算的;而使用geometry这种数据类型时,PostGIS的内部计算是基于平面来计算的。

让我们再次尝试测量洛杉矶和巴黎之间的距离,我们将使用ST_GeographyFromText(text)函数,而不是ST_GeometryFromText(text)。

SELECT ST_Distance(
  ST_GeographyFromText('POINT(-118.4079 33.9434)'), -- Los Angeles (LAX)
  ST_GeographyFromText('POINT(2.5559 49.0083)')     -- Paris (CDG)
);

在这里插入图片描述
得到一个大数字!所有geography计算的返回值都以米为单位,所以我们的答案是9124km。

早期版本的PostGIS支持使用ST_Distance_Spheroid(point, point, measurement)函数对球体进行非常基本的计算。然而,ST_Distance_Spheroid功能是有限的,该函数仅适用于点,不支持跨极点或国际日期变更线的要素的索引。

当提出这样一个问题时,支持非点的几何图形的需求变得非常明显:“从洛杉矶到巴黎的航班路线距离冰岛有多远?”
在这里插入图片描述
在笛卡尔平面坐标系统(底图是投影坐标系)上使用地理坐标(紫色线)产生了一个非常错误的答案!使用大圆路线(红线)则能得出正确的答案(地球上的航班路线(直线)当投影到平面坐标系统时,应该变成曲线,即大圆路线)。如果我们将LAX-CDG航班路线转换成一条线串,并利用geography计算其到冰岛某个点的距离,我们可以得到正确的答案(以米为单位)。

SELECT ST_Distance(
  ST_GeographyFromText('LINESTRING(-118.4079 33.9434, 2.5559 49.0083)'), -- LAX-CDG
  ST_GeographyFromText('POINT(-22.6056 63.9850)')                        -- Iceland (KEF)
);

在这里插入图片描述
因此,在LAX-CDG航班路线距离冰岛的距离(从冰岛的国际机场测量)是一个相对较小的502km这样的一个长度距离。

笛卡尔平面坐标系统处理地理坐标的方法是完全分解跨越国际日期变更线的要素。从洛杉矶到东京的最短大圆路线穿越太平洋(下图红线),而最短的笛卡尔平面路线则穿越大西洋和印度洋(下图紫线)。
在这里插入图片描述

SELECT ST_Distance(
  ST_GeometryFromText('Point(-118.4079 33.9434)'),  -- LAX
  ST_GeometryFromText('Point(139.733 35.567)'))     -- NRT (Tokyo/Narita)
    AS geometry_distance,
ST_Distance(
  ST_GeographyFromText('Point(-118.4079 33.9434)'), -- LAX
  ST_GeographyFromText('Point(139.733 35.567)'))    -- NRT (Tokyo/Narita)
    AS geography_distance;

在这里插入图片描述

文章目录

  • PostGIS学习教程十二:地理
  • 一、使用Geography
  • 二、创建一个Geography表
  • 三、转换为Geometry
  • 四、为什么使用Geography


一、使用Geography

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

CREATE TABLE nyc_subway_stations_geog AS
SELECT
  Geography(ST_Transform(geom,4326)) AS geog,
  name,
  routes
FROM nyc_subway_stations;

在这里插入图片描述
在geography表上构建空间索引与在geometry表上构建空间索引完全相同:

CREATE INDEX nyc_subway_stations_geog_gix
ON nyc_subway_stations_geog 
USING GIST (geog);

在这里插入图片描述
对于geography类型,只有相关的少量空间函数:

ST_AsText(geography) returns text
ST_GeographyFromText(text) returns geography
ST_AsBinary(geography) returns bytea
ST_GeogFromWKB(bytea) returns geography
ST_AsSVG(geography) returns text
ST_AsGML(geography) returns text
ST_AsKML(geography) returns text
ST_AsGeoJson(geography) returns text
ST_Distance(geography, geography) returns double
ST_DWithin(geography, geography, float8) returns boolean
ST_Area(geography) returns double
ST_Length(geography) returns double
ST_Covers(geography, geography) returns boolean
ST_CoveredBy(geography, geography) returns boolean
ST_Intersects(geography, geography) returns boolean
ST_Buffer(geography, float8) returns geography[1]
ST_Intersection(geography, geography) returns geography[1]

二、创建一个Geography表

用于创建含有geography列的新表的SQL与用于创建geography表的SQL非常相似。但是,geography包含在表创建时直接指定表类型的功能。例如:

CREATE TABLE airports (
  code VARCHAR(3),
  geog GEOGRAPHY(Point)
);
INSERT INTO airports VALUES ('LAX', 'POINT(-118.4079 33.9434)');
INSERT INTO airports VALUES ('CDG', 'POINT(2.5559 49.0083)');
INSERT INTO airports VALUES ('KEF', 'POINT(-22.6056 63.9850)');

在表定义中,GEOGRAPHY(Point)将airport数据类型指定为点。新的geography字段不会在geometry_columns视图中注册,相反,它们是在名为geography_columns的视图中注册的。

SELECT * FROM geography_columns;

在这里插入图片描述

三、转换为Geometry

虽然geography类型的空间函数已经可以处理许多问题,但有时你可能需要访问仅由geometry类型支持的其他空间函数。幸运的是,你可以将对象从geography转换为geometry。

PostgreSQL的类型转换语法是将:: typename附加到希望转换的值的末尾。因此,2::text将数字2转换为文本字符串"2";‘POINT(0 0)’ :: geometry将点的文本表示形式转换为geometry点。

ST_X(point)函数仅支持geometry类型,那我们怎样才能从我们的geography类型数据中读取X坐标呢?

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

在这里插入图片描述
通过将::geometry附加到geography值后面,可以将对象转换为SRID为4326的geometry。现在,我们就可以使用任何的geometry函数了。但是,请记住-现在我们的对象是geometry,坐标将被解释为笛卡尔平面坐标,而不是球体坐标。

四、为什么使用Geography

地理坐标是大众普遍接受的坐标——每个人都知道经度/纬度的含义,但很少有人理解UTM坐标的含义。那么为什么不一直用geography类型呢?

首先,如前所述,可直接支持geography类型的函数要少得多。
其次,球体上的计算要比笛卡尔计算计算量大得多。例如,基于笛卡尔平面坐标的计算距离的公式(Pythagoras)涉及一次对sqrt()的调用,基于球体坐标的计算距离的公式包含两次sqrt()调用、一次arctan()调用、四次sin()调用和两次cos()调用,三角函数的计算是非常耗费资源的。
那么,结论是什么呢?

如果你的数据在地理范围上是紧凑的(包含在州、县或市内),请使用基于笛卡尔坐标的geometry类型,因为范围小,所以可以使你的数据有意义。有关可能的参考系统的选择,请参见http://spatialreference.org站点并输入您所在区域的名称。或者直接查看下图选择适合的投影坐标系统:
在这里插入图片描述
如果你需要测量在地理范围上是分散的数据集(覆盖世界大部分地区)的距离,请使用geography类型。通过基于geography类型运行而节省的应用程序级别复杂性将抵消任何硬件性能问题。同时通过将geography类型转换为geometry类型的方法可以消除大多数功能限制问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程 基于m98版本。 WebRtc Video Receiver(六)-FrameBuffer原理 大神有个详细的论述。 Finder的FID设计 H.264 没有FID,使用RtpSeqNumOnlyRefFinder ,比较复杂,要做出决定 RtpSeqNumOnlyRefFinder cla…

canvas 有趣的弹簧效果

先上效果 两个小球之间有一根弹簧,这里有一条线表示,其中左球固定,在点击开始后,右球开始做自由落体 思路 先做受力分析 经过受力分析可以发现,整个系统一共有三个力在起作用,我们分别把他们求出来并合成…

鸿蒙原生应用再添新丁!同花顺入局鸿蒙

鸿蒙原生应用再添新丁!同花顺入局鸿蒙 来自 HarmonyOS 微博12月11日消息,同花顺已完成#鸿蒙原生应用#beta版本,并正在进行全量版本开发,进一步丰富了#鸿蒙原生应用#的覆盖领域。同花顺作为股民和券商首选的一站式金融理财服务平台…

搜集怎么绘制三维曲线和曲面?

1、针对函数对象是单一变量、两个函数的情况。用plot3函数;(三维曲线) 看一下matlab官方的例子: t 0:pi/50:10*pi; st sin(t); ct cos(t); plot3(st,ct,t) 绘制出来的曲线: 几个比较关键的点: &…

Linux系统编程(一):基本概念

参考引用 Unix和Linux操作系统有什么区别?一文带你彻底搞懂posix Linux系统编程(文章链接汇总) 1. Unix 和 Linux 1.1 Unix Unix 操作系统诞生于 1969 年,贝尔实验室发布了一个用 C 语言编写的名为「Unix」的操作系统&#xff0…

nginx中的正则表达式及location和rewrite

目录 常用的Nginx 正则表达式 location和rewrite的区别 location location 大致可以分为三类 location 常用的匹配规则 location 优先级 location 示例说明 location优先级的总结 rewrite rewrite的功能 rewrite实现跳转的条件 rewrite的执行顺序 rewrite的语法格式…

C# 任务的异常和延续处理

写在前面 当Task在执行过程中出现异常或被取消等例外的情况时,为了让执行流程能够继续进行,可以使用延续方法实现这种链式处理;还可以针对前置任务不同的执行结果,选择执行不同的延续分支方法。子任务执行过程中的任何异常都会被…

【收获】成长之路

目录 一、前言二、计算机方面三、专业知识方面四、总结 一、前言 四年,对于一个人的成长来说,是一个相当重要的阶段。在这段时间里,我经历了许多挑战、收获了许多成就,也在不断地成长和改变。回首这四年的点点滴滴,我深…

linux docker 怎么更换镜像源

要设置Docker镜像,您可以按照以下步骤进行: 1. 打开终端并登录到Docker主机上。 运行以下命令来编辑 Docker 的配置文件 "/etc/docker/daemon.json"(如果不存在则新建): sudo nano /etc/docker/daemon.js…

Django系列之Celery异步框架+RabbitMQ使用

在Django项目中,如何集成使用Celery框架来完成一些异步任务以及定时任务呢? 1. 安装 pip install celery # celery框架 pip install django-celery-beat # celery定时任务使用 pip install django-celery-results # celery存储结果使用2. Django集成…

URIBuilder与SSRF

在使用一个静态扫描工具时,报了一个SSRF的问题,经过数据流的分析,导致此工具报SSRF的原因是在调用URIBuilder的setPath函数时,参数是从请求里获取的,导致了数据流被污染,因此认为由URIBuilder构造的URL也被…

作为一个产品经理带你了解Axure的安装和基本使用

1.Axure的简介 Axure是一种强大的原型设计工具,它允许用户创建交互式的、高保真度的原型,以及进行用户体验设计和界面设计。Axure可以帮助设计师和产品经理快速创建和共享原型,以便团队成员之间进行沟通和反馈。Axure提供了丰富的交互组件和功…

【EI会议征稿中|JPCS出版】第三届电子与集成电路技术国际学术会议(EICT 2024)

第三届电子与集成电路技术国际学术会议(EICT 2024) 2024 3rd International Conference on Electronics and Integrated Circuit Technology 第三届电子与集成电路技术国际学术会议(EICT 2024)将于2024年4月12至14日在南昌市举行…

Vue3封装一个轮播图组件

先看效果 编写组件代码 CarouselChart.vue <template><div classimg-box><el-button clickpreviousImages v-ifprops.showBtn>←</el-button><div classimg><div styledisplay: flex;gap: 20px idmove><imgclassimg-item v-for(item…

Github上火爆的个人知识管理AI大脑:Quivr

Github上火爆的个人知识管理AI大脑&#xff1a;Quivr。 演示视频&#xff1a; Github上火爆的个人知识管理AI大脑&#xff1a;Quivr 点击上面视频观看&#xff01;&#xff01;&#xff01; II. Quivr 的强大功能 与文件和应用程序聊天 把你的文件和应用看成你的对话伙伴&…

“险棋”更是“好棋”,鸿蒙生态为什么值得加入?

作者 | 曾响铃 文 | 响铃说 支付宝大张旗鼓与鸿蒙合作后&#xff0c;已经有高德地图、哔哩哔哩、阿里钉钉、美团、支付宝、小红书等十多个领域的独角兽企业集体宣布将开发鸿蒙原生应用&#xff0c;携手华为共同推动鸿蒙生态发展。 早前&#xff0c;有关华为鸿蒙系统可能将于…

Java中的IO流③——转换流、序列化流、反序列化流、打印流

目录 转换流 代码演示 总结 序列化流&反序列化流 序列化流 构造和成员方法 细节 代码演示 反序列化流 代码演示 序列化流和反序列化流细节 综合练习 打印流 字节打印流 代码演示 字符打印流 代码演示 总结 转换流 转换流可以将字节流转成字符流&#xff0…

【MySQL】:表的操作

表的操作 一.创建表二.查看表结构三.修改表四.删除表 一.创建表 field 表示列名。 datatype 表示列的类型。 character set 字符集&#xff0c;如果没有指定字符集&#xff0c;则以所在数据库的字符集为准。 collate 校验规则&#xff0c;如果没有指定校验规则&#xff0c;则以…

侯捷C++ 程序的生前死后

生前&#xff1a;CRT startup code 看完课程&#xff0c;能够回答一下问题&#xff1a; C进入点是main()嘛&#xff1f;什么代码比main更早执行&#xff1f;什么代码在main结束后执行&#xff1f;为什么上述代码可以如此行为&#xff1f;Heap的结构如何&#xff1f;I/O的结构…

redis(设置密码)配置文件详细

1.设置账号密码端口 config set requirepass 123456 设置密码为123456 config get requirepass 查看账号密码 auth 123456 登入的时候输入这个确定账号密码 1. 首先连接到Redis服务器: redis-cli 2. 然后使用CONFIG SET命令设置requirepass参数并指定密码: CONFIG SET requi…