PostGIS是什么
Posted 自己的九又四分之三站台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostGIS是什么相关的知识,希望对你有一定的参考价值。
1. 什么是GIS(知识地图定位)
1.1. GIS概念
地理信息系统(Geographic Information System或 Geo-Information system,GIS)有时又称为“地学信息系统”。它是一种特定的十分重要的空间信息系统。它是在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气层)空间中的有关地理分布数据进行采集、储存、管理、运算、分析、显示和描述的技术系统。
位置与地理信息既是LBS的核心,也是LBS的基础。一个单纯的经纬度坐标只有置于特定的地理信息中,代表为某个地点、标志、方位后,才会被用户认识和理解。用户在通过相关技术获取到位置信息之后,还需要了解所处的地理环境,查询和分析环境信息,从而为用户活动提供信息支持与服务。
地理信息系统(GIS,Geographic Information System)是一门综合性学科,结合地理学与地图学以及遥感和计算机科学,已经广泛的应用在不同的领域,是用于输入、存储、查询、分析和显示地理数据的计算机系统,随着GIS的发展,也有称GIS为“地理信息科学”(Geographic Information Science),近年来,也有称GIS为"地理信息服务"
1.1. 传统GIS平台
1.1.1. ArcGIS和ESRI
ArcGis是“计算机制图”应用,包含了全球范围内的底图、地图数据、应用程序,以及可配置的应用模板和开发人员使用的 GIS 工具和 API,可用于创建 Web 地图、发布GIS服务、共享地图、数据和应用程序,以及管理组织的内容和多个用户。
1.1.1.1. ESRI公司
美国环境系统研究所公司(Environmental Systems Research Institute, Inc. 简称ESRI公司)成立于1969年,总部设在美国加州RedLands市,是世界最大的地理信息系统(Geographic Information System GIS)技术提供商。
- 技术人员可以关注ESRI的github:https://github.com/Esri
1.1.1.2. 评价
从某种意义上ArcGIS就是GIS
- 最全名最工业实现标准最多的商业GIS软件
- ArcGIS Desktop
- ArcGIS Server
- ArcGIS Engine
- City Engine
- …
- 最大的原罪就是他是美国的
1.1.2. SuperMap GIS和超图
SuperMap GIS 是超图软件研发的面向各行业应用开发、二三维制图与可视化、决策分析的大 型 GIS 基础软件系列,包含云 GIS 服务器、边缘 GIS 服务器、端 GIS 以及在线 GIS 平台等多种软 件产品。
1.1.2.1. 超图
北京超图软件股份有限公司是全球第三大、亚洲最大的地理信息系统(GIS)软件厂商,主要从事地理信息系统相关软件技术研发与应用服务。
1.1.2.2. 评价
- 国内最完善的GIS平台,可以平替ArcGIS
- 与ArcGIS在细节上有着差距
1.1.3. QGIS
Quantum GIS(QGIS)是相当友善的开源地理信息系统,使用GNU(General Public License)授权,属于 Open Source eospatial Foundation(OSGeo)的官方计划。在 GNU 这个授权下,开发者可以自行检阅与调整程序代码,并保障让所有使用者可以免费且自由地修改程序。
QGIS 的目标是成为一个使用简单的 GIS,提供了常见的功能与图征。借着核心图征提供基本功能与附加组件(Python 或 C++)持续地扩充,让使用者可以浏览、管理、编辑、分析数据以及制图。
QGIS 是一群自愿者所开发的项目,欢迎全球使用者或开发者将程序代码的缺陷、修复、报告以及提供文件等贡献。它是由热心的使用者和开发社群所维护的。它提供了交互式的邮件列表,以及透过网络管道传达给其他用户与开发人员帮忙与建议。另外,它也提供商业定制化开发。
- github地址:https://github.com/qgis/QGIS
1.2. 数据类型
在数据存储中,存储GIS(地理信息系统)数据的存储介质有
- Shapefile,简称
shp文件
- MDB
- GDB
- ArcSDE
- ArcSDE for Oracle
- ArcSDE for SqlServer
- ArcSDE for Postgresql
- Oracle Spatial
- Postgresql 的 PostGIS
一般而言,本地文件使用shp文件
,对于共享服务器存储时使用ArcSDE、PostGIS。在PostGIS出来之前,大家都是使用Oracle Spatial。
而在存储介质中对于空间数据类型划分为:
- 基本空间数据类型
- 点、多点
- 线、多线
- 面、多面
- 栅格数据
1.2.1. 基本空间数据类型
POINT(0 0)
LINESTRING(0 0,1 1,1 2)
POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))
MULTIPOINT((0 0),(1 2))
MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))
MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))
GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))
1.2.2. 栅格数据类型
1.2.2.1. 栅格数据类型
- .tiff
- ERDAS IMAGINE (.img)
- 卫星影像
- DEM和DOM
1.3. 空间参考
1.3.1. 空间参考使用历史转变
新中国按时间顺序使用的空间参考为:
- 北京54
- 西安80
- CGCS2000
具体可以参见北京54、西安80和CGCS2000
一言以蔽之,新中国由于政策和科学技术的原因使用了北京54;西安80是将大地原点设在中国中部陕西省泾阳县永乐镇
的空间参考,同时在这个时候确定了1985国家高程基准
;而走入新世纪,为了满足科研、航空、航天、航海以及国防建设我们采用了CGCS2000空间参考。
1.3.2. 常用空间参考
- WGS84坐标系:即地球坐标系,国际上通用的坐标系。
- GCJ02坐标系:即火星坐标系,WGS84坐标系经加密后的坐标系。高德地图
- BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系。百度独有
- Web墨卡托坐标系
1.3.3. 空间参考中名词拾遗(坐标系统、空间参考、投影、基准面、椭圆体)
具体可以参见:空间参考中名词拾遗(坐标系统、空间参考、投影、基准面、椭圆体)
1.3.3. 为什么要进行投影
在上述表达中我们基本上描述的均为经纬度的,也就是地理坐标系
,地图单位通常为度
,投影坐标系 (Projected Coordinate System)平面坐标系统地图单位通常为米
,也称非地球投影坐标系统(notearth),或者是平面坐标。
- 地球是三维的
- 地图(屏幕)是二维的
- 地理坐标系统是在三维(基准面)上的定位方法
- 投影使得三维转成二维
- 三维转成二维会产生变形
- 一般而言,使用相同椭球体的投影坐标系统和经纬度坐标系统是可以相互转换的,而对于两种椭球体的坐标系统需要建立坐标转换进行数学基础的转换,具体表现为,一4参,7参,二节点坐标的变化。
在一些特殊的城市,在使用投影坐标系统是往往有地方坐标系统,比如北京,原因是因为跨带
2. Postgresql中的PostGIS
2.1. 什么是PostGIS
PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL.
PostGIS是PostgreSQL对象关系数据库的空间数据库扩展器。它增加了对地理对象的支持,允许在SQL中运行位置查询。
-
PostGIS是在对象关系型数据库PostgreSQL上增加了存储管理空间数据的能力的开源空间数据库,空间数据库像存储和操作数据库中其他任何对象一样去存储和操作空间对象。
-
它是PostgreSQL的扩展插件,在PostgreSQL的core(存储、检索、事务等)层之上实现GIS层的功能,它不能独立于PostgreSQL运行。
2.2. Postgis解决什么问题,为什么选择PostGIS
-
Postgresql本身是最先进的开源RDBMS(没有之一),是最稳定成熟的RDBMS之一(流行度和社区成熟度比不上mysql)
-
PostGIS是最成熟,功能最丰富的免费GIS数据库(没有之一),只有收费的Oracle和SQL Server(他们都有GIS版)才能与之媲美,MySQL的GIS功能通常不能拿来和它比
-
PostGIS本质上还是数据库,使用SQL操作,可以满足你更新频繁、和其它筛选条件联合使用的要求
-
结合postgresql FTS扩展(Full Text Search),不仅可以根据性别、年龄、LBS信息搜索,更可以和模糊关键词搜索联合起来
-
Postgresql也可以做集群、复制、高可用
2.3. Postgis与ArcSDE的关系
2.3.1. Postgis与ArcSDE的关系?
要回答这个问题,先得明白ArcSDE是什么。
ArcSDE是ESRI提供的一项技术,可以访问和管理存储在关系型数据库中的空间数据。
2.3.1.1. 两者的相同点
- 都可以作为空间数据库的实现;
- 都遵循OGC SFSQL以及ISO SQL/MM两个规范;
2.3.1.2. 两者的不同点
- ArcSDE可作为不同关系型数据库的空间数据引擎(SDE即spatial data engine),Postgis不可以;
- ArcSDE可在不同关系型数据库中实现空间数据库,Postgis只能在PostgreSQL上实现空间数据库。
2.4. Postgis包含了哪些内容?遵循什么规范?
Postgis在PostgreSQL基础上,实现了空间数据类型、空间索引和空间函数。它所实现的这些内容,遵循了两个规范:OGC SFSQL以及ISO SQL/MM。
2.4.1. OGC SFSQL规范
OGC:它是一个国际标准组织,成立于1994年,是一个由GIS厂商、计算机厂商、数据库厂商、美国联邦机构、标准组织以及学术界等部门代表组成的公益性行业协会。致力于实现地理空间数据与地理信息处理资源的全面集成,通过信息基础设施,广泛使用商业化的、可互操作的地理信息处理软件。
2.4.2. SQL/MM标准
SQL/MM是ISO(International Standard Organization,国际标准化组织)提出的标准,SQL/MM第三部分空间定义了矢量数据存储与检索的相关标准,解释了基于这些数据类型如何使用存储、获取和处理空间数据。
SQL-MM Part3定义大量插值曲线类型来扩展SQL规范定义的简单要素类型。
2.4.3. PostGIS的扩展
- 扩展EWKT、EWKB
从本质上来说,方便数据的统一管理,为每一个存储在数据表中的图形加了一个srid(为每一个图形增加了空间参考),而在同一个数据表(表模式)下空间参考是一致的,为后续的数据存储、数据分析特别是空间参考定义一致的数学基础。
- 扩展GIS函数
方便postgis的一些新特性的展现,以及新算法和技术的实现。
3. PostGIS的基本使用
3.1. 使用扩展
CREATE EXTENSION postgis;
创建扩展之后在数据库函数中将会出现postgis类型,也就是可以在Postgresql中使用几何类型,并可以使用postgis的函数操作、分析几何图形。
3.2. 数据读取
根据前面的OGC标准我们可以使用WKT、WKB、GeoJson来进行数据的存储通信,即不同平台、数据库的交换标准,在PostGIS的体现为以下函数。
一般而言使用最多的无非
---------------读取wkt字符串为geometry---------------:
ST_GeomFromText(ST_GeometryFromText)
---------------将geometry转化为不同数据标准格式---------------:
---转换为wkt
ST_AsText
---转换为geojson
ST_AsGeoJSON
3.3. 操作符
- &&
A && B: 当二维A范围覆盖二维B范围时,返回真。
- &&&
A &&& B: 当三维A范围覆盖三维B范围时,返回真。
- &<
A&<B : A范围覆盖B范围或A范围在B范围左侧时,返回真。
- &<|
A&<|B : 当A范围覆盖B范围或A范围在B范围下方,返回真。
- =
A=B : A范围=B范围时,返回真。
- ~
A~B :A范围包含B范围时,返回真。
- <->
A<->B : 返回两点之间的距离。为了点或点检查它使用浮点精度(相对于双精度的基础几何点)。对于其他几何类型之间的距离返回浮点边界框。用于做距离排序和最近邻法。
- <#>
A<#>B :返回2个几何图形边界框之间的距离。对于点/点检查它的几乎一样的距离(虽然可能不一样,因为这个边界框是浮点精度和几何图形是双精度)。用于做最短距离和查找邻接边距离等。
3.4. 基于9交(DE-9IM)模型的空间关系
空间关系 | 中文名称 | OGC标准 | 解释 |
---|---|---|---|
Contains | 包含 | 是 | 一个几何图形的内部完全包含了另一个几何图形的内部和边界。 |
CoveredBy | 覆盖 | 否 | 一个几何图形被另一个几何图形所包含,并且它们的边界相交。Point和MultiPoint不支持此空间关系,因为它们没有边界。 |
Crosses | 交叉 | 是 | 一个几何图形的内部和另一个几何图形的边界和内部相交,但是它们的边界不相交。 |
Disjoint | 分离 | 是 | 两个几何图形的边界和内部不相交。 |
EnvelopeIntersects | 外包矩形相交 | 否 | 两个几何图形的外接矩形相交。 |
Equal | 相等 | 是 | 两个几何图形具有相同的边界和内部。 |
Inside | 内部 | 否 | 一个几何图形在另一个几何图形的内部,但是和它的边界不接触。 |
Intersects | 相交 | 是 | 两个几何图形没有分离(Non-DisJoint)。 |
Overlaps | 重叠 | 是 | 两个几何图形的边界和内部相交(Intersect)。 |
Touch | 接触 | 是 | 两个几何图形的边界相交,但是内部不相交。 |
Within | 包含于 | 是 | 一个几何图形的内部和边界完全在另一个几何图形的内部。 |
https://qlygmwcx.blog.csdn.net/article/details/122762041?spm=1001.2014.3001.5502
3.4.1. 翻译资源
- PostGIS的Spatial Relationships and Measurements-空间关系与测量
- PostGIS的Spatial Relationships and Measurements 空间关系与测量:2
- PostGIS的Spatial Relationships and Measurements 空间关系与测量:3
- PostGIS的Spatial Relationships and Measurements 空间关系与测量:4
- PostGIS的Spatial Relationships and Measurements 空间关系与测量:5
- PostGIS的Geometry Processing 几何处理_1 ST_Buffer&&ST_BuildArea
- [PostGIS的Geometry Processing 几何处理2(ST_ClipByBox2D、ST_Collect、ST_ConcaveHull、ST_ConvexHull)](PostGIS的Geometry Processing 几何处理2(ST_ClipByBox2D、ST_Collect、ST_ConcaveHull、ST_ConvexHull))
- Geometry Processing 几何处理 3 ST_CurveToLine、ST_DelaunayTriangles
- Geometry Processing 几何处理 4 ST_Difference、ST_Dump、ST_DumpPoints、ST_DumpRings
3.5. 空间关系索引
GiST 的意思是通用的搜索树(Generalized Search Tree)。 它是一种平衡的,树状结构的访问方法,在系统中起一个基础模版的作用,可以使用它实现任意索引模式。B+/-trees,R-trees 和许多其它的索引模式都可以用 GiST实现。
CREATE INDEX idx_my_table_geom ON my_table USING gist(geom gist_geometry_ops);
- 从数据库库索引说到空间数据索引
- 为什么要使用空间索引
- 空间数据:格网索引
- 空间数据结构(四叉树、八叉树、BVH树、BSP树、k-d树)
- 高效的多维空间点索引算法 — Geohash 和 Google S2
- 矢量数据空间索引之R树索引
- GIST索引
3.6. 样例说明
超融合时序数据库YMatrixDB与PostGIS案例
目录
YMatrix适用于各种规模设备的数据融合与物联网时序应用场景,本案例以具体的案例来说明YMatrix在PostGIS中的数据加载、处理和分析的能力以及时空数据的具体使用方法,首先我们先了解下PostGIS,然后再分享几个PostGIS在YMatrixDB的案例。
什么是PostGIS
PostGIS是一个空间数据库,空间数据库像存储和操作数据库中其他任何对象一样去存储和操作空间对象。空间数据库将空间数据和对象关系数据库(Object Relational database)完全集成在一起。实现从以GIS为中心向以数据库为中心的转变。PostGIS 实现了点、线、面、多点、多线、多面等的SQL实现参考。
PostGIS的特点
- PostGIS 具有强大的功能,具有以下的特点
- PostGIS支持空间数据类型,包括点(POINT)、线(LINESTRING)、面(POLYGON)、多点 (MULTIPOINT)、多线(MULTILINESTRING)、多面(MULTIPOLYGON)和几何集合 (GEOMETRYCOLLECTION)等。
- 支持对象表达方法,比如WKT和WKB。
- 提供简单的空间分析函数,同时也提供其他一些具有复杂分析功能的函数。
- 支持所有的数据存取和构造方法,如GeomFromText()、AsBinary(),以及GeometryN()等。
- 对于元数据的支持,如GEOMETRY_COLUMNS和SPATIAL_REF_SYS。同时也支持AddGeometryColumn和DropGeometryColumn函数等。
- 能对矢量数据和栅格数据做处理,能通过 SQL 调用栅格、矢量数据的投影函数。
- 能通过多种工具导入多种标准的栅格数据,同时能通过 SQL 语句将栅格渲染至各种格式GeoTiff、PNG、JPG、NetCDF 等。
- 能通过 SQL 调用 KML、GML、GeoJSON、GeoHash、WKT 等标准文本类型的矢量数据的函数。
- 矢量或栅格操作函数,包括按区域伸缩栅格像元值、局域统计、按矢量图形裁剪栅格、矢量化栅格等。
PostGIS 基础知识
OGC的WKB和WKT格式
OGC定义了两种描述几何对象的格式,分别是WKB(Well-Known Binary)和WKT(Well-Known Text)格式。
几何要素 | WKT格式 |
---|---|
点 | POINT(0 0) |
线 | LINESTRING(0 0,1 1,1 2) |
面 | POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)) |
多点 | MULTIPOINT(0 0,1 2) |
多线 | MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4)) |
多面 | MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))) |
几何集合 | GEOMETRYCOLLECTION(POINT(2 3),LINESTRING((2 3,3 4))) |
插入数据实例
EWKT、EWKB和Canonical格式
EWKT和EWKB相比OGC WKT和WKB格式主要的扩展有3DZ、3DM、4D坐标和内嵌空间参考支持。
几何类型 | 格式 |
---|---|
3D点 | POINT(0 0 0) |
内嵌空间参考的点 | SRID=32632;POINT(0 0) |
带M值的点 | POINTM(0 0 0) |
带M值的3D点 | POINT(0 0 0 0) |
内嵌空间参考的带M值的多点 | SRID=4326;MULTIPOINTM(0 0 0,1 2 1) |
插入数据实例
INSERT INTO table (SHAPE,NAME) VALUES (GeomFromText('POINT(116.39 39.9)', 4326), '北京');
SQL-MM格式
SQL-MM格式定义了一些插值曲线,这些插值曲线和EWKT有点类似,也支持3DZ、3DM、4D坐标,但是不支持嵌入空间参考。
几何类型 | 格式 |
---|---|
插值圆弧 | CIRCULARSTRING(0 0, 1 1, 1 0) |
插值复合曲线 | COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 1 0),(1 0, 0 1)) |
曲线多边形 | CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)) |
多曲线 | MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4)) |
多曲面 | MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)),((10 10, 14 12, 11 10, 10 10),(11 11, 11.5 11, 11 11.5, 11 11))) |
常几何类型和函数
名字 | 存储空间 | 描述 | 表现形式 |
---|---|---|---|
point | 16字节 | 平面上的点 | (x,y) |
line | 32字节 | 直线 | A,B,C |
lseg | 32字节 | 线段 | ((x1,y1),(x2,y2)) |
box | 32字节 | 矩形 | ((x1,y1),(x2,y2)) |
path | 16+16n字节 | 闭合路径 | ((x1,y1),…) |
path | 16+16n字节 | 开放路径 | [(x1,y1),…] |
polygon | 40+16n字节 | 多边形 | ((x1,y1),…) |
circle | 24字节 | 圆 | <(x,y),r> |
操作实例
-- 点
point(0 0)
-- 线
linestring(0 0,1 1,1 2)
-- 面
polygon((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))
-- 多点
multipoint((0 0),(1 2))
-- 多线
multilinestring((0 0,1 1,1 2),(2 3,3 2,5 4))
-- 多面
multipolygon(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))
-- 几何集合
geometrycollection(point(2 3),linestring(2 3,3 4))
常用操作符
操作符 | 描述 | 示例 | 结果 |
---|---|---|---|
+ | 平移 | select box '((0,0),(1,1))' + point '(2.0,0)'; | (3,1),(2,0) |
– | 平移 | select box '((0,0),(1,1))' – point '(2.0,0)'; | (-1,1),(-2,0) |
* | 伸缩/旋转 | select box '((0,0),(1,1))' * point '(2.0,0)'; | (2,2),(0,0) |
/ | 伸缩/旋转 | select box '((0,0),(2,2))' / point '(2.0,0)'; | (1,1),(0,0) |
# | 交点或者交面 | select box'((1,-1),(-1,1))' # box'((1,1),(-1,-1))'; | (1,1),(-1,-1) |
# | path或polygon的顶点数 | select #path'((1,1),(2,2),(2,1))'; | 3 |
@-@ | 长度或周长 | select @-@ path'((1,1),(2,2),(2,1))'; | 3.414213562 |
@@ | 中心 | select @@ circle'<(0,0),1>'; | (0,0) |
## | 第一个操作数和第二个操作数的最近点 | select point '(0,0)' ## lseg '((2,0),(0,2))'; | (1,1) |
<-> | 间距 | select circle '<(0,0),1>' <-> circle '<(5,0),1>'; | 3 |
&& | 是否有重叠 | select box '((0,0),(1,1))' && box '((0,0),(2,2))'; | t |
<< | 是否严格在左 | select circle '((0,0),1)' << circle '((5,0),1)'; | t |
>> | 是否严格在右 | select circle '((0,0),1)' >> circle '((5,0),1)'; | f |
&< | 是否没有延伸到右边 | select box '((0,0),(1,1))' &< box '((0,0),(2,2))'; | t |
&> | 是否没有延伸到左边 | select box '((0,0),(3,3))' &> box '((0,0),(2,2))'; | t |
<<| | 是否严格在下 | select box '((0,0),(3,3))' <<| box '((3,4),(5,5))'; | t |
|>> | 是否严格在上 | select box '((3,4),(5,5))' |>> box '((0,0),(3,3))'; | t |
&<| | 是否没有延伸到上面 | select box '((0,0),(1,1))' &<| box '((0,0),(2,2))'; | t |
|&> | 是否没有延伸到下面 | select box '((0,0),(3,3))' |&> box '((0,0),(2,2))'; | t |
<^ | 是否低于(允许接触) | select box '((0,0),(3,3))' <^ box '((3,3),(4,4))'; | t |
>^ | 是否高于(允许接触) | select box '((0,0),(3,3))' >^ box '((3,3),(4,4))'; | f |
?# | 是否相交 | select lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))'; | t |
?- | 是否水平对齐 | select ?- lseg '((-1,1),(1,1))'; | t |
?- | 两边图形是否水平对齐 | select point '(1,0)' ?- point '(0,0)'; | t |
?| | 是否竖直对齐 | select ?| lseg '((-1,0),(1,0))'; | f |
?| | 两边图形是否竖直对齐 | select point '(0,1)' ?| point '(0,0)'; | t |
?-| | 是否垂直 | select lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))'; | t |
?|| | 是否平行 | select lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))'; | t |
@> | 是否包含 | select circle '((0,0),2)' @> point '(1,1)'; | t |
<@ | 是否包含于或在图形上 | select point '(1,1)' <@ circle '((0,0),2)'; | t |
~= | 是否相同 | select polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'; | t |
常用操作函数
函数 | 返回值 | 描述 | 示例 | 结果 |
---|---|---|---|---|
area(object) | double precision | 面积 | select area(circle'((0,0),1)'); | 3.141592654 |
center(object) | point | 中心 | select center(box'(0,0),(1,1)'); | (0.5,0.5) |
diameter(circle) | double precision | 圆周长 | select diameter(circle '((0,0),2.0)'); | 4 |
height(box) | double precision | 矩形竖直高度 | select height(box '((0,0),(1,1))'); | 1 |
isclosed(path) | boolean | 是否为闭合路径 | select isclosed(path '((0,0),(1,1),(2,0))'); | t |
isopen(path) | boolean | 是否为开放路径 | select isopen(path '[(0,0),(1,1),(2,0)]'); | t |
length(object) | double precision | 长度 | select length(path '((-1,0),(1,0))'); | 4 |
npoints(path) | int | path中的顶点数 | select npoints(path '[(0,0),(1,1),(2,0)]'); | 3 |
npoints(polygon) | int | 多边形的顶点数 | select npoints(polygon '((1,1),(0,0))'); | 2 |
pclose(path) | path | 将开放path转换为闭合path | select pclose(path '[(0,0),(1,1),(2,0)]'); | ((0,0),(1,1),(2,0)) |
popen(path) | path | 将闭合path转换为开放path | select popen(path '((0,0),(1,1),(2,0))'); | [(0,0),(1,1),(2,0)] |
radius(circle) | double precision | 圆半径 | select radius(circle '((0,0),2.0)'); | 2 |
width(box) | double precision | 矩形的水平长度 | select width(box '((0,0),(1,1))'); | 1 |
OGC标准函数
管理函数
函数 | 说明 |
---|---|
AddGeometryColumn(, , , , , ) | 添加几何字段 |
DropGeometryColumn(, , ) | 删除几何字段 |
Probe_Geometry_Columns() | 检查数据库几何字段并在geometry_columns中归档 |
ST_SetSRID(geometry, integer) | 给几何对象设置空间参考(在通过一个范围做空间查询时常用) |
几何对象关系函数
函数 | 说明 |
---|---|
ST_Distance(geometry, geometry) | 获取两个几何对象间的距离 |
ST_DWithin(geometry, geometry, float) | 如果两个几何对象间距离在给定值范围内,则返回TRUE |
ST_Equals(geometry, geometry) | 判断两个几何对象是否相等(比如LINESTRING(0 0, 2 2)和LINESTRING(0 0, 1 1, 2 2)是相同的几何对象) |
ST_Disjoint(geometry, geometry) | 判断两个几何对象是否分离 |
ST_Intersects(geometry, geometry) | 判断两个几何对象是否相交 |
ST_Touches(geometry, geometry) | 判断两个几何对象的边缘是否接触 |
ST_Crosses(geometry, geometry) | 判断两个几何对象是否互相穿过 |
ST_Within(geometry A, geometry B) | 判断A是否被B包含 |
ST_Overlaps(geometry, geometry) | 判断两个几何对象是否是重叠 |
ST_Contains(geometry A, geometry B) | 判断A是否包含B |
ST_Covers(geometry A, geometry B) | 判断A是否覆盖 B |
ST_CoveredBy(geometry A, geometry B) | 判断A是否被B所覆盖 |
ST_Relate(geometry, geometry, intersectionPatternMatrix) | 通过DE-9IM 矩阵判断两个几何对象的关系是否成立 |
ST_Relate(geometry, geometry) | 获得两个几何对象的关系(DE-9IM矩阵) |
几何对象处理函数
函数 | 说明 |
---|---|
ST_Centroid(geometry) | 获取几何对象的中心 |
ST_Area(geometry) | 面积量测 |
ST_Length(geometry) | 长度量测 |
ST_PointOnSurface(geometry) | 返回曲面上的一个点 |
ST_Boundary(geometry) | 获取边界 |
ST_Buffer(geometry, double, [integer]) | 获取缓冲后的几何对象 |
ST_ConvexHull(geometry) | 获取多几何对象的外接对象 |
ST_Intersection(geometry, geometry) | 获取两个几何对象相交的部分 |
ST_Shift_Longitude(geometry) | 将经度小于0的值加360使所有经度值在0-360间 |
ST_SymDifference(geometry A, geometry B) | 获取两个几何对象不相交的部分(A、B可互换) |
ST_Difference(geometry A, geometry B) | 从A去除和B相交的部分后返回 |
ST_Union(geometry, geometry) | 返回两个几何对象的合并结果 |
ST_Union(geometry set) | 返回一系列几何对象的合并结果 |
ST_MemUnion(geometry set) | 用较少的内存和较长的时间完成合并操作,结果和ST_Union |
几何对象存取函数
函数 | 说明 |
---|---|
ST_AsText(geometry) | 获取几何对象的WKT描述 |
ST_AsBinary(geometry) | 获取几何对象的WKB描述 |
ST_SRID(geometry) | 获取几何对象的空间参考ID |
ST_Dimension(geometry) | 获取几何对象的维数 |
ST_Envelope(geometry) | 获取几何对象的边界范围 |
ST_IsEmpty(geometry) | 判断几何对象是否为空 |
ST_IsSimple(geometry) | 判断几何对象是否不包含特殊点(比如自相交) |
ST_IsClosed(geometry) | 判断几何对象是否闭合 |
ST_IsRing(geometry) | 判断曲线是否闭合并且不包含特殊点 |
ST_NumGeometries(geometry) | 获取多几何对象中的对象个数 |
ST_GeometryN(geometry,int) | 获取多几何对象中第N个对象 |
ST_NumPoints(geometry) | 获取几何对象中的点个数 |
ST_PointN(geometry,integer) | 获取几何对象的第N个点 |
ST_ExteriorRing(geometry) | 获取多边形的外边缘 |
ST_NumInteriorRings(geometry) | 获取多边形内边界个数 |
ST_NumInteriorRing(geometry) | (同上) |
ST_InteriorRingN(geometry,integer) | 获取多边形的第N个内边界 |
ST_EndPoint(geometry) | 获取线的终点 |
ST_StartPoint(geometry) | 获取线的起始点 |
ST_GeometryType(geometry) | 获取几何对象的类型 |
ST_GeometryType(geometry) | 类似上,但是不检查M值,即POINTM对象会被判断为point |
ST_X(geometry) | 获取点的X坐标 |
ST_Y(geometry) | 获取点的Y坐标 |
ST_Z(geometry) | 获取点的Z坐标 |
ST_M(geometry) | 获取点的M值 |
类型转换函数
函数 | 返回类型 | 描述 | 示例 | 结果 |
---|---|---|---|---|
box(circle) | box | 圆形转矩形 | select box(circle ‘((0,0),2.0)’); | (1.41421356237309,1.41421356237309),(-1.41421356237309,-1.41421356237309) |
box(point) | box | 点转空矩形 | select box(point ‘(0,0)’); | (0,0),(0,0) |
box(point, point) | box | 点转矩形 | select box(point ‘(0,0)’, point ‘(1,1)’); | (1,1),(0,0) |
box(polygon) | box | 多边形转矩形 | select box(polygon ‘((0,0),(1,1),(2,0))’); | (2,1),(0,0) |
bound_box(box, box) | box | 将两个矩形转换成一个边界矩形 | select bound_box(box ‘((0,0),(1,1))’, box ‘((3,3),(4,4))’); | (4,4),(0,0) |
circle(box) | circle | 矩形转圆形 | select circle(box ‘((0,0),(1,1))’); | <(0.5,0.5),0.707106781186548> |
circle(point, double precision) | circle | 圆心与半径转圆形 | select circle(point ‘(0,0)’, 2.0); | <(0,0),2> |
circle(polygon) | circle | 多边形转圆形 | select circle(polygon ‘((0,0),(1,1),(2,0))’); | <(1,0.333333333333333),0.924950591148529> |
line(point, point) | line | 点转直线 | select line(point ‘(-1,0)’, point ‘(1,0)’); | 0,-1,0 |
lseg(box) | lseg | 矩形转线段 | select lseg(box ‘((-1,0),(1,0))’); | [(1,0),(-1,0)] |
lseg(point, point) | lseg | 点转线段 | select lseg(point ‘(-1,0)’, point ‘(1,0)’); | [(-1,0),(1,0)] |
path(polygon) | path | 多边形转path | select path(polygon ‘((0,0),(1,1),(2,0))’); | ((0,0),(1,1),(2,0)) |
point(double precision, double precision) | point | 点 | select point(23.4, -44.5); | (23.4,-44.5) |
point(box) | point | 矩形转点 | select point(box ‘((-1,0),(1,0))’); | (0,0) |
point(circle) | point | 圆心 | select point(circle ‘((0,0),2.0)’); | (0,0) |
point(lseg) | point | 线段中心 | select point(lseg ‘((-1,0),(1,0))’); | (0,0) |
point(polygon) | point | 多边形的中心 | select point(polygon ‘((0,0),(1,1),(2,0))’); | (1,0.333333333333333) |
polygon(box) | polygon | 矩形转4点多边形 | select polygon(box ‘((0,0),(1,1))’); | ((0,0),(0,1),(1,1),(1,0)) |
polygon(circle) | polygon | 圆形转12点多边形 | select polygon(circle ‘((0,0),2.0)’); | ((-2,0),(-1.73205080756888,1),(-1,1.73205080756888),(-1.22460635382238e-16,2),(1,1.73205080756888),(1.73205080756888,1),(2,2.4492127 |
0764475e-16),(1.73205080756888,-0.999999999999999),(1,-1.73205080756888),(3.67381906146713e-16,-2),(-0.999999999999999,-1.73205080756 | ||||
888),(-1.73205080756888,-1)) | ||||
polygon(npts, circle) | polygon | 圆形转npts点多边形 | select polygon(12, circle ‘((0,0),2.0)’); | ((-2,0),(-1.73205080756888,1),(-1,1.73205080756888),(-1.22460635382238e-16,2),(1,1.73205080756888),(1.73205080756888,1),(2,2.4492127 |
0764475e-16),(1.73205080756888,-0.999999999999999),(1,-1.73205080756888),(3.67381906146713e-16,-2),(-0.999999999999999,-1.73205080756 | ||||
888),(-1.73205080756888,-1)) | ||||
polygon(path) | polygon | 将path转多边形 | select polygon(path ‘((0,0),(1,1),(2,0))’); | ((0,0),(1,1),(2,0)) |
PostGIS 系统表查看
spatial_ref_sys表
在基于PostGIS模板创建的数据库的public模式下,有一个spatial_ref_sys表,它存放的是OGC规范的空间参考。
geometry_columns表
1、geometry_columns表存放了当前数据库中所有几何字段的信息,比如我当前的库里面有两个空间表,在geometry_columns表中就可以找到这两个空间表中几何字段的定义 2、其中f_table_schema字段表示的是空间表所在的模式,f_table_name字段表示的是空间表的表名,f_geometry_column字段表示的是该空间表中几何字段的名称,srid字段表示的是该空间表的空间参考。
taix=# select * from geometry_columns;
f_table_catalog | f_table_schema | f_table_name | f_geometry_column | coord_dimension | srid | type
-----------------+----------------+---------------+-------------------+-----------------+------+-------
taix | public | trip | pickup_geom | 2 | 2163 | POINT
taix | public | trip | dropoff_geom | 2 | 2163 | POINT
taix | public | trip_1_prt_1 | pickup_geom | 2 | 2163 | POINT
taix | public | trip_1_prt_1 | dropoff_geom | 2 | 2163 | POINT
PostGIS 两个重要的坐标体系
- 4326 \\ GCS_WGS_1984 \\ Geographic Coordinate System(GCSS)地理坐标系, World Geodetic System(WGS)世界大地测量系统
- 26986 \\ 美国马萨诸塞州地方坐标系(区域坐标系)\\ 投影坐标, 平面坐标
YMatrixDB 安装PostGIS
YMatrixDB的安装可以参考
https://ymatrix.cn/doc/5.0/install/mx5_cluster/mx5_cluster
PostGIS 安装
使用以下连接下载postgis安装包及相关的依赖。
链接: https://pan.baidu.com/s/1D_awBTLzOqZV5--cxE8_oA 提取码: gjj7
如果是集群安装的数据库需要在每台节点安装postgis。
---- 以下操作需要使用root用户执行
-- 解压postgis安装包
# unzip postgis-install.zip
-- 创建postgis的repo
# cd postgis-install
# ls
county.tgz create_repo.sh mxdb-postgis-2.5-1.el7.x86_64.rpm pkg-postgis
# sh create_repo.sh
Create postgis repo successfully!
-- 查看postgis的repo
# yum repolist
repo id repo name status 0
postgis postgis
-- 安装postgis
# yum install --disablerepo="*" --enablerepo=postgis -y mxdb-postgis-2.5-1.el7.x86_64.rpm
在YMatrixDB上安装postgis扩展
使用mxadmin用户登录到数据库并创建postgis扩展,postgis适用于当前session数据库,如果其他的数据库使用,请切换到其他数据库中再次创建即可。
postgres=# create extension postgis;
CREATE EXTENSION
postgres=# \\dx
List of installed extensions
Name | Version | Schema | Description
-----------------+---------+------------+---------------------------------------------------------------------
gp_exttable_fdw | 1.0 | pg_catalog | External Table Foreign Data Wrapper for Greenplum
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
postgis | 2.5.5 | public | PostGIS geometry, geography, and raster spatial types and functions
(3 rows)
YMatrixDB的PostGIS使用案例
首先我们先熟悉一下PostGIS的常用的案例,然后再使用真实的北京市内所有的酒店信息和宾馆信息做统计。
计算两点之间的距离
-- 两个点之间的距离,距离单位是m
select ST_Distance(ST_GeographyFromText('SRID=4326;POINT(114.017299 22.537126)'),
ST_GeographyFromText('SRID=4326;POINT(114.025919 22.534866)'));
-- 两点之间的斜度数
SELECT ST_Distance(ST_GeomFromText('POINT(114.017299 22.537126)',4326),
ST_GeomFromText('POINT(114.025919 22.534866)', 4326));
范围内的点查找
-- 查看两点的距离是否有1000m,单位米m,返回t是在范围内,否则不在
SELECT ST_DWithin(
ST_GeographyFromText('SRID=4326;POINT(114.017299 22.537126)'),
ST_GeographyFromText('SRID=4326;POINT(114.025919 22.534866)'),1000);
-- 查看两点直接的斜度,是否在制定的斜度内,返回t是在范围内,f不在斜度内
SELECT ST_DWithin(ST_GeomFromText('POINT(114.017299 22.537126)',4326),
ST_GeomFromText('POINT(114.025919 22.534866)', 4326),0.00811134108875483);
-- 查找给定经纬度5km以内的点
-- geom_point::geography,单位变成米, 否则默认距离单位是度。
SELECT
uuid,
longitude,
latitude,
ST_DistanceSphere (
geom_point,
ST_GeomFromText('POINT(121.248642 31.380415)', 4326 )) distance
FROM
s_poi_gaode
WHERE
ST_DWithin ( geom_point :: geography, ST_GeomFromText ( 'POINT(121.248642 31.380415)', 4326 ) :: geography, 5000 ) IS TRUE
order by distance desc
LIMIT 30;
-- 查看给定坐标的最近的10个点
SELECT * FROM s_poi_gaode_gps ORDER BY geom_point <-> ST_GeomFromText ( 'POINT(121.248642 31.380415)', 4326 ) LIMIT 10;
弯曲的几何实体案例
-- 创建表
create table global_points (
id int,
name varchar(64),
location geography(point,4326)
) Distributed by(id);
-- 插入数据
insert into global_points (id,name, location) values (1,'town', 'srid=4326;point(-110 30)');
insert into global_points (id,name, location) values (2,'forest', 'srid=4326;point(-109 29)');
insert into global_points (id,name, location) values (3,'london', 'srid=4326;point(0 49)');
-- 创建索引
create index global_points_gix on global_points using gist ( location );
-- 查看数据
postgis=# select * from global_points;
id | name | location
----+--------+----------------------------------------------------
2 | forest | 0101000020E61000000000000000405BC00000000000003D40
3 | london | 0101000020E610000000000000000000000000000000804840
1 | town | 0101000020E61000000000000000805BC00000000000003E40
(3 rows)
-- 查询给位置1000公里之内的城镇
select name from global_points where st_dwithin(location, 'srid=4326;point(-110 29)'::
geography, 1000000);
-- 计算从西雅图(-122.33 47.606)飞往伦敦(0.0 51.5)的距离
select st_distance('linestring(-122.33 47.606, 0.0 51.5)'::geography, 'point(-21.96
64.15)'::geography);
-- 计算点线之间的距离
select st_distance('linestring(-122.33 47.606, 0.0 51.5)'::geometry, 'point(-21.96 64.15)
'::geometry);
我们可以使用地图查看西雅图(-122.33 47.606)和伦敦(0.0 51.5)的坐标点
https://lbsyun.baidu.com/jsdemo/demo/yLngLatLocation.htm
YMatrixDB的PostGIS车联网数据案例
车联网数据下载
某城市拥有超过800万人口和20万辆出租车的行程信息,该行程信息乘客的上下车时间、上下车地点、乘车人数、车费和支付的方式等。接下来使用该数据分析出租车的出车情况和交通的拥堵情况,根据道路的拥堵情况合理的分配出车调度,便于乘客方便打车提高乘客的生活体验。
数据下载:
https://pan.baidu.com/share/init?surl=JJv6ADN5vHOlem7smTrEDw (提取码1x4u)
表创建
接下来创建付费方式、费率和行程时序表。
---- 付费方式表
create table if not exists payment_types (
payment_type int,
description text
) DISTRIBUTED BY(payment_type);
insert into payment_types values
(1, '信用卡'),
(2, '现金'),
(3, '免付费'),
(4, '有争议'),
(5, '未知'),
(6, '无效行程');
---- 费率表
create table if not exists rate_codes (
rate_code int,
description text
) DISTRIBUTED BY(rate_code);
insert into rate_codes values
(1, '标准费率'),
(2, '1号机场'),
(3, '2号机场'),
(4, '特殊区域'),
(5, '协商价'),
(6, '团体');
---- 行程时序表
create extension matrixts ;
create table if not exists trip (
vendor_id text,
pickup_datetime timestamp without time zone,
dropoff_datetime timestamp without time zone,
passenger_count int,
trip_distance numeric,
pickup_longitude numeric,
pickup_latitude numeric,
rate_code_id int,
store_and_fwd_flag text,
dropoff_longitude numeric,
dropoff_latitude numeric,
payment_type int,
fare_amount numeric,
extra numeric,
mta_tax numeric,
tip_amount numeric,
tolls_amount numeric,
improvement_surcharge numeric,
total_amount numeric,
trip_duration numeric generated always as (EXTRACT(EPOCH FROM (dropoff_datetime - pickup_datetime)::INTERVAL)/60) STORED,
is_valid boolean,
pickup_geom geometry(POINT,2163),
dropoff_geom geometry(POINT,2163)
)
USING mars2 with (compresstype=zstd, compresslevel=5)
DISTRIBUTED BY (vendor_id)
PARTITION BY RANGE (pickup_datetime)
( START (date '2016-01-01') INCLUSIVE
END (date '2016-02-01') EXCLUSIVE
EVERY (INTERVAL '1 day')
);
CREATE INDEX trip_index ON trip USING mars2_btree(c1, daq_time) WITH (uniquemode=true);
pickup_datetime : 上车时间点
dropoff_datetime : 下车时间点
pickup_longitude : 上车地点的经度值
pickup_latitude : 上车地点的纬度值
dropoff_longitude : 下车地点的经度值
dropoff_longitude : 下车地点的纬度值
passenger_count : 表示乘客数量
trip_distance : 旅程的距离(单位为英里)
total_amount : 乘车费用
trip_duration : 乘车的时长(单位为分钟)
pickup_geom/dropoff_geom : 位置区域信息
数据加载
mxgate的详细使用可以参考: https://ymatrix.cn/doc/latest/tools/mxgate.md
-- 使用以下命令把数据加载到表中
tail -n +2 yellow_tripdata_2016-01.csv | mxgate --source stdin --db-database mxdb --db-master-host master --db-master-port 5432 --db-user mxadmin --time-format raw --target trip --parallel 256 --delimiter ',' --exclude-columns trip_duration,is_valid,pickup_geom,dropoff_geom
数据处理
在时序的场景中,因为各种复杂的原因,数据有时会包含一些明显错误或者无效的数据。借助YMatrix提供的丰富SQL能力,可以快速检测并清除这些无效错误数据。 一种错误情况是下车时间早于或者等于上车时间,我们把is_valid字段设置成false表示该数据无效。
insert into trip(vendor_id,pickup_datetime,is_valid)
select vendor_id,pickup_datetime,'false' as is_valid
from trip
where dropoff_datetime <= pickup_datetime
order by 1,2;
vacuum trip;
还有一种情况是汽车的平均速度大于每小时300英里,尤其在旅程或者时间较长时,这种情况明显不合理,我们也把is_valid设置成false表示该数据无效。
insert into trip(vendor_id,pickup_datetime,is_valid)
select vendor_id,pickup_datetime,'false' as is_valid
from trip
where trip_distance > trip_duration* (300/60) and trip_distance > 100
order by 1,2;
vacuum trip;
出租车数据分析
出租车行程统计
YMatrix提供了time_bucket函数,支持按照任意时间区间的分段计算。需要在数据库上安装Matrixts Extension来初始化时序组件:
CREATE EXTENSION matrixts;
接下来我们就可以通过下面的SQL语句统计出每天有多少行程:
select time_bucket('24 hours', pickup_datetime) as day, count(*)
from trip
where is_valid is null
group by day
order by day;
如果想要了解2016年1月2号一天中每个小时,分别有多少人乘车,可以用下面的SQL:
SELECT time_bucket('1 hour', pickup_datetime) as hour, sum(passenger_count)
FROM trip
where is_valid is null
and pickup_datetime >= '2016-01-02 00:00:00' and pickup_datetime < '2016-01-03 00:00:00'
GROUP BY hour
ORDER BY hour;
接下来我们统计0-10、10-50、50-100、100-200、200英里以上不同行程距离区段的总行程信息
select distance_range, count(*) as num_of_trips
from
(
select
case
when trip_distance <= 10 then 10
when trip_distance > 10 AND trip_distance <= 50 then 50
when trip_distance > 50 AND trip_distance <= 100 then 100
when trip_distance > 100 AND trip_distance <= 200 then 200
when trip_distance > 200 then 500
end as distance_range
from trip where is_valid is null
) as temp
group by distance_range;
执行后可以看到这样的输出:
distance_range | num_of_trips
----------------+--------------
10 | 3883839
50 | 239067
100 | 168
200 | 24
500 | 1
费率分布
YMatrix 时序数据库支持多表关联和高级窗口函数,例如RANK(),ROW_NUMBER(),DENSE_RANK() 。以下使用高级窗口函数统计出费率每个类型的个数。
SELECT rates.description,
COUNT(vendor_id) AS num_trips,
RANK () OVER (ORDER BY COUNT(vendor_id) DESC) AS trip_rank
FROM trip
JOIN rate_codes rates ON trip.rate_code_id = rates.rate_code
WHERE is_valid is null AND pickup_datetime < '2016-02-01'
GROUP BY rates.description
ORDER BY LOWER(rates.description);
执行后可以看到这样的输出。
description | num_trips | trip_rank
-------------+-----------+-----------
1号机场 | 92551 | 2
2号机场 | 7304 | 4
协商价 | 14010 | 3
团体 | 37 | 6
标准费率 | 4007265 | 1
特殊区域 | 1886 | 5
我们可以统计出去1号机场和2号机场机场的次数,平均行程时间(下车时间点 - 上车时间点),平均票价,最小和最大和平均路程(单位为英里)以及平均乘客人数。根据这些信息可以合理的安排出租车的运行情况,减少车的拥堵情况。
select rates.description,
count(vendor_id) as num_trips,
avg(dropoff_datetime - pickup_datetime) as avg_trip_duration,
min(trip_distance) as min_distance,
max(trip_distance) as max_distance,
avg(passenger_count) as avg_passengers
from trip
join rate_codes rates on trip.rate_code_id = rates.rate_code
where is_valid is null and trip.rate_code_id in (2,3) and pickup_datetime < '2016-02-01'
group by rates.description
order by rates.description;
执行后可以看到这样的输出:
description | num_trips | avg_trip_duration | min_distance | max_distance | avg_passengers
-------------+-----------+-------------------+--------------+--------------+--------------------
1号机场 | 92274 | 00:44:30.722349 | 0.00 | 213.60 | 1.7191408197325357
2号机场 | 7335 | 00:34:10.621541 | 0.00 | 77.40 | 1.7346966598500341
机场行程分析
我们使用YMatrix的time_bucket函数分析最近一段内出租车去1号机场和2号机场的情况。实时观测出租车的运行情况,使用软件实时的同步给出租车司机,并协助出租车规划最优路线。
select time_bucket('5 minute', pickup_datetime) as datetime,rates.description,count(*)
from trip
join rate_codes rates on trip.rate_code_id = rates.rate_code
where is_valid is null and trip.rate_code_id in (2,3) and pickup_datetime > '2016-01-02 08:00' and pickup_datetime < '2016-01-02 10:00'
group by datetime,rates.description
order by datetime desc;
执行后可以看到这样的输出:
datetime | description | count
---------------------+-------------+-------
2016-01-02 09:55:00 | 1号机场 | 16
2016-01-02 09:55:00 | 2号机场 | 1
2016-01-02 09:50:00 | 1号机场 | 8
2016-01-02 09:50:00 | 2号机场 | 3
2016-01-02 09:45:00 | 1号机场 | 8
2016-01-02 09:40:00 | 1号机场 | 10
2016-01-02 09:40:00 | 2号机场 | 3
2016-01-02 09:35:00 | 1号机场 | 10
2016-01-02 09:35:00 | 2号机场 | 2
2016-01-02 09:30:00 | 1号机场 | 15
2016-01-02 09:30:00 | 2号机场 | 2
2016-01-02 09:25:00 | 1号机场 | 15
附近出租车
YMatrix支持空间范围数据查询,需要将纬度和经度点转换为几何坐标,来根据该经纬度的位置统计出租车的数量。根据(lat,long) (40.7589,-73.9851)位置信息获取400米范围内每隔30分钟的出租车的数量。
insert into trip(vendor_id,pickup_datetime,pickup_geom)
select vendor_id,pickup_datetime,st_transform(st_setsrid(st_makepoint(pickup_longitude,pickup_latitude),4326),2163) as pickup_geom
from trip order by 1,2;
insert into trip(vendor_id,pickup_datetime,dropoff_geom)
select vendor_id,pickup_datetime,st_transform(st_setsrid(st_makepoint(dropoff_longitude,dropoff_latitude),4326),2163) as dropoff_geom
from trip order by 1,2;
vacuum trip;
select time_bucket('30 minutes', pickup_datetime) as thirty_min, count(*) as near_times_sq
from trip where is_valid is null and
st_distance(pickup_geom, st_transform(st_setsrid(st_makepoint(-73.9851,40.7589),4326),2163)) < 400
and pickup_datetime < '2016-01-01 14:00'
group by thirty_min
order by thirty_min;
执行后可以看到这样的输出。
thirty_min | near_times_sq
---------------------+---------------
2016-01-01 00:00:00 | 21
2016-01-01 00:30:00 | 34
2016-01-01 01:00:00 | 24
2016-01-01 01:30:00 | 23
2016-01-01 02:00:00 | 20
2016-01-01 02:30:00 | 33
2016-01-01 03:00:00 | 51
2016-01-01 03:30:00 | 57
2016-01-01 04:00:00 | 88
以上是关于PostGIS是什么的主要内容,如果未能解决你的问题,请参考以下文章
有啥方法可以从作为 LAT/LONG 作为 PostGIS 中的地理数据类型插入的 GPS 坐标中恢复数据?