PostGIS之地理坐标
1. 概述
PostGIS 是PostgreSQL数据库一个空间数据库扩展,它添加了对地理对象的支持,允许在 SQL 中运行空间查询
PostGIS官网:About PostGIS | PostGIS
PostGIS官方教程:PostGIS 简介 — Introduction to PostGIS
PostGIS相关教程:文章目录汇总 - 知乎 (zhihu.com)
本文基于官方教程描述PostGIS中的地理坐标
数据准备可参考:
数据介绍可参考:
2. 地理坐标
2.1 平面坐标与球面坐标
地图中常用投影坐标系和地理坐标系,投影坐标系是将地球表面投影到平面上,地理坐标系是球面坐标,使用地理坐标系,不适用于运算面积、长度等
2.2 地理坐标
2.2.1 点到点
当使用的坐标系是地理坐标时,进行距离运算是没意义的,比如在WGS-84坐标系下计算洛杉矶(Los Angeles)和巴黎(Paris)的距离:
- Los Angeles:
POINT(-118.4079 33.9434)
- Paris:
POINT(2.3490 48.8533)
SELECT ST_Distance(ST_GeometryFromText('POINT(-118.4079 33.9434)', 4326), ST_GeomFromText('POINT(2.3490 48.8533)', 4326));
结果为:121.67388386839635,这似乎并没有什么意义
当使用的坐标系是地理坐标系时,需要将运算的背景放在球面坐标系,PostGIS中将这类数据定义为geography类型,而通常使用的平面坐标系下的属于geometry类型
使用geography类型来计算距离:
SELECT ST_Distance(ST_GeographyFromText('SRID=4326;POINT(-118.4079 33.9434)'), ST_GeogFromText('SRID=4326;POINT(2.3490 48.8533)'));
计算结果为:9125752.37394223,单位:米
2.2.2 点到线
在地理坐标系下进行距离量算,往往会出现错误的结果,比如下图中,"从洛杉矶(LAX)到巴黎(CDG)的航班路线距离冰岛有多远?"
使用平面坐标系,得到的是紫色的直线,而实际上,应该是红色的大圆路线
因此,这种情况下,应尽可能的使用geography类型来计算距离:
SELECT ST_Distance(
ST_GeographyFromText('SRID=4326;LINESTRING(-118.4079 33.9434, 2.3490 48.8533)'), -- LAX-CDG
ST_GeogFromText('SRID=4326;POINT(-22.6056 63.9850)') -- Iceland
);
2.2.3 国际日期变更线
国际日期变更线就是180°经线,根据定义,西经与东经相接于0°和180°经线,使用平面坐标系就会存在分界线问题,比如:WGS-84坐标系下,点(-179,0)与点(179,0)的距离是多少?
SELECT ST_Distance(ST_GeomFromText('SRID=4326;POINT(-179 0)'), ST_GeomFromText('SRID=4326;POINT(179 0)'));
结果为358°,显然这是错的,它计算的是(-179,0)到(179,0)的平面距离,没有考虑地理坐标的实际意义
因此,这种情况下,使用geography类型来计算距离:
SELECT ST_Distance(
ST_GeogFromText('SRID=4326;POINT(-179 0)'),
ST_GeogFromText('SRID=4326;POINT(179 0)')
);
结果为:222638.98158655,单位:米,显然geography类型考虑了国际日期变更线的问题
2.3 Geometry转Geography
Geometry转Geography首先要将Geometry转换到地理坐标系WGS-84(SRID/EPSG:4326),再使用转换函数:
- Geography(geometry) 将基于EPSG:4326的geometry数据类型转换为geography数据类型
- (geometry)::geography 将基于EPSG:4326的geometry数据类型转换为geography数据类型
将Geometry数据表转换为Geography表:
CREATE TABLE nyc_subway_stations_geog AS
SELECT
ST_Transform(geom,4326)::geography AS geog,
name,
routes
FROM nyc_subway_stations;
Geography表构建空间索引与Geometry相同,不同之处在于PostGIS对于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
- ST_Intersection(geography, geography) returns
geography
2.4 Geography转Geometry
与Geometry转Geography类似,支持转换的函数主要有:
- Geometry(geography) 将基于EPSG:4326的geography数据类型转换为geometry数据类型
- (geography)::geometry 将基于EPSG:4326的geography数据类型转换为geometry数据类型
SELECT Geometry(ST_GeogFromText('SRID=4326;POINT(-179 0)'));
2.5 创建Geography表
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表的信息(元数据)储存在geography_columns表(视图)中
SELECT * FROM geography_columns;
2.6 不使用的原因
地理坐标是大众普遍接受的坐标,geography类型有效解决了很多问题,那么为什么不广泛使用呢?
- 因为geography类型计算复杂,支持的函数少
选择合适的投影,是个不错的解决办法
3. 参考资料
[1]18. Geography — Introduction to PostGIS
[2]PostGIS教程十二:地理 - 知乎 (zhihu.com)
PostGIS之地理坐标的更多相关文章
- postgis 中的距离计算
最近在做一个项目,有一个功能想要实现类似于查询附近的人的功能.由于项目的原因数据库只能使用 postgresql,空间查询就使用了 postgis 来实现. 具体业务像这样:业务需要返回附近距自己 1 ...
- ubuntu16.04搭建geodjango+postgresql+postgis的WebGIS框架(一)安装第三方空间库
postgis是postgresql的空间扩展对象,它需要一些第三方库的支持.包括GEOS, PROJ.4 和 GDAL.我们首先安装这几个空间库. 在ubuntu系统终端执行:(预先装一些依赖的库) ...
- PostgreSQL及PostGIS使用
基础知识 参考文档:http://www.postgis.net/docs/ PostGIS支持的GIS对象是OpenGIS Consortium(OGC)定义的“简单特征”的超集.OpenGIS规范 ...
- OpenLayers 3+Geoserver+PostGIS实现点击查询
WebGIS开发中,点击查询是最经常使用的一种查询方式,在ArcGIS api 中.这样的查询叫IdentifyTask,主要作用是前台提交參数.交ArcServer查询分析返回. 本文从开源框架的角 ...
- PostGIS(解压版)安装
1.软件下载 postgresql-9.6.1-1-windows-x64-binaries.zip https://www.postgresql.org/download/windows/ post ...
- [原]CentOS7部署PostGis
转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 本文参考了<An almost idiot's guide to install Pos ...
- PostgreSql+PostGIS和uDig的安装
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 总体来说,这两款开源软件均是很好安装的,一般按照提示一步一步 ...
- (十)WebGIS中地理坐标与屏幕坐标间的转换原理
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 地图本身是拥有坐标的,一般可以大致分为平面坐标和经纬度坐标, ...
- ae 地理坐标与投影坐标转换 [转]
转载地址:http://blog.163.com/lai_xiao_hui/blog/static/123037324201151443221942/ 代码是将WGS84地理坐标转换为WGS84UTM ...
- 与你相遇好幸运,Postgresql和postgis安装
笔者开发环境: windows 7 x86_64 一开始安装的是官网最新版 PostgreSQL 9.6 ,安装成功 之后安装PostGIS Bundle 2.2 for PostgreSQL x64 ...
随机推荐
- codeforce E - Binary Inversions题解
题目: 给你一个01串,现在你可以(或者不用)选取其中一个元素进行一次反转操作0-1,1-0:从而使得串中的逆序对个数最多. 题目链接:codeforce origin problem 思路: 1. ...
- Django项目启动 AttributeError: ‘str‘ object has no attribute ‘decode‘ 问题
Watching for file changes with StatReloader Performing system checks... System check identified no i ...
- nuxt.js安装使用
首先要学会看文档,https://www.nuxtjs.cn/guide/configuration 一.创建项目,并运行 终端运行 npx create-nuxt-app <项目名> ( ...
- VC实例和VM实例的区别!!!
1.内置关系是什么 VueComponent.prototype.__proto__ === Vue.prototype 2.为什么要有这个关系 让组件实例对象可以访问到 Vue原型上的属性.方法.
- C++可执行文件绝对路径获取与屏蔽VS安全检查
:前言 前几天写新项目需要用到程序所在绝对路径的时候,发现网上居然一点相关分享都没有. :_pgmptr 翻箱倒柜找出了几本教程,发现了一个叫_pgmptr的东西. 进去看了一下,在stdlib.h里 ...
- 学习ASP.NET Core Blazor编程系列十八——文件上传(中)
学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...
- [R语言] ggplot2入门笔记2—通用教程ggplot2简介
文章目录 通用教程简介(Introduction To ggplot2) 2 ggplot2入门笔记2-通用教程ggplot2简介 1. 了解ggplot语法(Understanding the gg ...
- [Leetcode]旋转链表
题目 代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * Li ...
- [Leetcode]完全平方数
题目 代码 class Solution { public: int numSquares(int n) { vector<int> dp(n + 1, INT_MAX); dp[0] = ...
- WPF中下拉框即可以选择项也可以作为只读文本框使用
1.需求 当前在开发的系统需要一个这样的控件. (1)可以选择已有的选择项,类似于ComboBox选择: (2)可以通过其他按钮点击,选择一个文件,选择后,把文件路径显示到控件上,并且处于只读状态,行 ...