MySQL中地理位置数据扩展geometry的使用心得
最近学习了些MySQL geometry数据存储和计算,在这里记录下。
1. 环境
geometry推荐在5.6版本以上使用,尽管大部分功能在5.5已经可用,除了距离计算函数st_distance等新增函数。
2. Geometry主要相关类
2.1 Geometry
Geometry是所有此扩展中类型得基类,其他类型如Point,LineString,Polygon都是Geometry的子类。Geometry有一些属性,这些属性是所有其他几何类的共有属性:
type: 类型(Point, LineString,...)
SRID: 该值确定了用于描述定义几何对象的坐标空间的空间坐标系统,参考链接:https://www.cnblogs.com/Joetao/articles/2086846.html
coordinates: 坐标值
interior, boundary, exterior: interior是几何对象所展空间的部分,boundary是几何对象的边界,exterior是几何对象未占有的空间。
MBR: 能够覆盖几何对象的最小矩形,可以想象成信封,它由几何对象中最大最小的坐标值组合而成:
((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
simple/nonsimple: 几何对象是否简单
closed/not closed: 几何对象是否封闭
dimension: 维度数(Point: 0, LineString: 1, Polygon: 2)
2.2 Point
顾名思义就是点,有一个坐标值,没有长度、面积、边界。
2.3 LineString
顾名思义就是线,由一系列点连接而成。
如果线从头至尾没有交叉,那就是简单的(simple)
如果起点和终点重叠,那就是封闭的(closed)
2.4 Polygon
多边形。可以是一个实心平面形,即没有内部边界,也可以有空洞,类似纽扣。
2.5 MultiPoint, MultiLineString, MultiPolygon, GeometryCollection
这4种类型都是集合类,是多个Point、LineString或Polygon组合在一起而成。
3. 几何对象在MySQL中的数据格式
在MySQL中有3种表达几何对象的格式:
-->WKT(文本格式)
-->WKB(二进制格式)
-->MySQL内部存储格式
其中WKT格式简单易读,在这里着重介绍:
3.1 WKT
3.1.1 Point
POINT(121.213342 31.234532)
经度(longitude)在前,维度(latitude)在后,用空格分隔
3.1.2 LineString
LINESTRING(121.342423 31.542423,121.345664 31.246790,121.453178 31.456862)
点与点之间用逗号分隔;一个点中的经纬度用空格分隔,与POINT格式一致
3.1.3 Polygon
POLYGON((121.342423 31.542423,121.345664 31.246790,121.453178 31.456862),(121.563633 31.566652,121.233565 31.234565,121.568756 31.454367))
由一个表示外部边界的LineString和0个或多个表示内部边界的LineString组成,最简单的就是只有一个外边界的情况:POLYGON((0 0,10,0 10 10, 0 10))
3.1.4 集合类格式
MULTIPOINT(0 0, 20 20, 60 60)
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
4. 几何对象创建函数
MySQL表中的几何对象有它自己的内部格式,我们需要将几何对象从方便输入的WKT格式转换为其内部格式,才能进行进一步的存储,计算等。
这里主要讲解使用WKT格式的函数,对于集合类对象的创建函数由于较少使用也不再列举
GeomFromText(wkt): 创建一个任何类型的几何对象Geometry
PointFromText(wkt): 创建一个Point对象
LineStringFromText(wkt): 创建一个LineString对象
PolygonFromText(wkt): 创建一个Polygon对象
5. 创建支持空间几何对象的表
5.1 创建表
以下是我创建的一个样例:
CREATE TABLE `t_geo_test` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(64) NOT NULL,
`SHAPE` geometry NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
这里的字段SHAPE就是存储几何对象的,类型为geometry,可以支持point,linestring,polygon等任意几何对象。
引擎需要使用MyISAM。
表结构:

5.2 插入数据
5.2.1 插入点数据
INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (1, 'P1', geomFromText('POINT(121.474103 31.232862)'));
5.2.2 插入线数据
INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (2, 'L1', geomFromText('LINESTRING(121.474103 31.232862,121.472462 31.231339,121.471984 31.232821)'));
5.2.3 插入多边形数据
INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (5, 'POLYGON_1', geomfromtext('POLYGON((121.474243 31.234504, 121.471775 31.233348, 121.470724 31.23155, 121.471603 31.230229, 121.472655 31.230357, 121.475777 31.232045, 121.474243 31.234504))'));
5.3 获取数据
AsText(): 此函数能将几何对象的内部存储格式转换为WKT格式
6. 常用函数
6.1 获取几何对象属性的函数
6.1.1 Geometry
-->Dimension(g)
返回对象g的维数
-->Envelope(g)
返回对象g的最小边界矩形(MBR)。结类型为Polygon值。
-->GeometryType(g)
以字符串形式返回几何类型的名称,如POINT,LINESTRING
-->IsClosed(g)
返回对象g是否封闭
-->IsSimple(g)
返回对象g是否简单
6.1.2 Point
-->X(p)
以双精度数值返回点p的X坐标值(经度)。
-->Y(p)
以双精度数值返回点p的Y坐标值(纬度)。
6.1.3 LineString
-->EndPoint(line)
返回对象line的最后一个点Point
-->StartPoint(line)
返回对象line的第一个点Point
-->PointN(line, N)
返回对象line中第N个点,N从1开始
6.1.4 Polygon
-->ExteriorRing(poly)
返回对象poly的外环,类型为LineString
-->InteriorRingN(poly, N)
返回对象poly的第N个内环,N从1开始
-->NumInteriorRings(poly)
返回对象poly的neihuan个数
6.2 从现成几何对象创建新的对象

6.2.1 st_union(g1, g2)
将g1和g2合并为一个集合类对象
SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');
SELECT st_union(@g1, @g2);
结果:
POLYGON((121.472655 31.230157, 121.471903 31.230229, 121.471898134093 31.2302649098516, 121.471603 31.230229, 121.470724 31.23155, 121.471761757556 31.2333253454665, 121.471775 31.233948, 121.474243 31.234804, 121.474597 31.2339365384615, 121.475777 31.232045, 121.475442678789 31.2318642395248, 121.475777 31.231045, 121.472655 31.230157))
6.2.2 st_difference(g1, g2)
返回几何对象,该对象表示了几何值g1与g2的点集合差异
SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');
SELECT st_difference(@g1,@g2);
结果:
MULTIPOLYGON(((121.471603 31.230229, 121.470724 31.23155, 121.471761757556 31.2333253454665, 121.471724 31.23155, 121.471898134093 31.2302649098516, 121.471603 31.230229)), ((121.475442678789 31.2318642395248, 121.474597 31.2339365384615, 121.475777 31.232045, 121.475442678789 31.2318642395248)))
6.2.3 st_intersection(g1,g2)
返回几何对象,该对象表示了几何值g1与g2的点集合交集
SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');
SELECT st_intersection(@g1,@g2);
结果:
POLYGON((121.471898134093 31.2302649098516, 121.471724 31.23155, 121.471761757556 31.2333253454665, 121.471775 31.233348, 121.474243 31.234504, 121.474597 31.2339365384615, 121.475442678789 31.2318642395248, 121.472655 31.230357, 121.471898134093 31.2302649098516))
6.3 几何对象之间空间关系的函数
6.3.1 st_contains(g1, g2)
返回1: g1完全包含g2;返回0: g1未包含g2
6.3.2 st_crosses(g1, g2), st_intersects(g1, g2)
返回1: g1与g2相交;返回0:g1与g2未相交
6.3.3 st_disjoint(g1, g2)
是st_crosses的反函数
6.3.4 st_within(g1, g2)
g1在g2内则返回1,否则返回0
7. 空间索引
对表中的geometry类型的字段进行索引可以优化搜索,MySQL中通过对Geometry对象的MBR创建索引
创建:
CREATE SPATIAL INDEX i_shape ON `t_geo_test`(SHAPE);
删除:
DROP INDEX i_shape ON `t_geo_test`;
8.一些注意事项
8.1 目前MySQL中支持的空间坐标系统没有gcj02,bd09等国内坐标系,默认使用WGS84地球坐标系,所以在创建几何对象时输入的坐标值尽量使用WGS84坐标,以避免误差。
8.2 MySQL中的计算距离,长度,面积等绝对数值的空间计算函数(area(), GLength(), st_distance())存在一定的误差,尽量不要使用。
MySQL中地理位置数据扩展geometry的使用心得的更多相关文章
- Vusual C++连接Mysql和从MySql中取出数据的API介绍
.1 mysql_real_connect() 2.1.1 函数原型: MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const ...
- 用python批量向数据库(MySQL)中导入数据
用python批量向数据库(MySQL)中导入数据 现有数十万条数据,如下的经过打乱处理过的数据进行导入 数据库内部的表格的数据格式如下与下面的表格结构相同 Current database: pyt ...
- PHP如何批量更新MYSQL中的数据
最近项目需要用到批量更新数据库里的数据,在网上找了一下这方面的例子,觉得这个还不错,分享给大家. 在这个业务里里面涉及到了更新两张数据表,那么大家是不是会想到非常简单,马上上代码 $sql ,type ...
- hadoop项目实战--ETL--(二)实现自动向mysql中添加数据
四 项目开发 1 创建数据库db_etl,新建两张表user 和oder.表结构如第一部分图所示. 2 编写python脚本,实现自动向mysql中插入数据. 新建python 项目,目录结构如下图 ...
- PHP读取mysql中的数据
<!DOCTYPE HTML> <html> <head> <title> PHP动态读取mysql中的数据 </title> <me ...
- 辛星浅谈mysql中的数据碎片以及引擎为MyISAM下的操作
对于mysql中的数据碎片,事实上和我们删除数据是息息相关的,删除数据的时候必定会在数据文件里造成不连续的空白空间,对于少量的数据的删除,并不会产生多少的空白空间.假设在一段时间内的大量的删除操作,会 ...
- PHP批量更新MYSQL中的数据
原文链接:https://blog.csdn.net/wuming19900801/article/details/62893429 $sql = "update newhouse_clic ...
- MySQL_(Java)分页查询MySQL中的数据
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL_(Java)使用preparestatement ...
- 利用Ajax实现数据的同步传输,从mysql中提取数据,通过echarts可视化
如何将mysql数据库中的方式通过echarts可视化呢,以下面这个简单的例子向大家进行演示: 步骤一:mysql的创表和插入数据,当然这些数据也可以是你通过爬虫抓取的. 步骤二: 创 ...
随机推荐
- 利用python3.x实现小爬虫下载贴吧内图片
Hi, I'm back. 寒假在家只有一台笔记本,也懒得把台式机上的键盘拆下来用,因此编程被我暂时搁置,转而在网易云课堂上学了一下Python.可惜的是云课堂的Python教程是基于Python ...
- [MyEclipse]转:设置注释格式
Window --> Java --> Code Style --> Code Templates --> Comments --> types --> Edit ...
- Python之匿名函数(filter,map,reduce)
参考博客:Python匿名函数详解--http://blog.csdn.net/csdnstudent/article/details/40112803 Python内建函数之——filter,map ...
- 二十四 Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图
1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scrapy架构源码分析图
- 用Qt写了一个qq客户端,采用webqq协议,发出来和大家分享一下---大神请无视
首先做以下声明: 本程序基于腾讯公司的webqq协议开发,所有相关版权归腾讯公司所有.此程序只用于技术交流和学习,不得用于其他方面. ---开发者:雨后星辰,转载请注明出处:http://www.cn ...
- Dir命令
注: 此系列为自己之前所搭建网站内容. 其实python的os模块能够很好的完成此任务.改天总结下. 之前在处理气象数据时,十几个文件,文件名比较长,需要自己处理变动的年份找出地址的规律再进行文件的读 ...
- T4模板的基本结构
(转自:http://www.cnblogs.com/yank/archive/2012/02/14/2342287.html) T4模板的基本结构 代码块的总体分类,就是两种:文本.程序脚本. 我感 ...
- jquery基础 笔记三
一. 操作"DOM属性" 在jQuery中没有包装操作"DOM属性"的函数, 因为使用javascript获取和设置"DOM属性"都很简单. ...
- 转载:【Oracle 集群】RAC知识图文详细教程(六)--RAC在LINUX上使用NFS安装前准备
文章导航 集群概念介绍(一) ORACLE集群概念和原理(二) RAC 工作原理和相关组件(三) 缓存融合技术(四) RAC 特殊问题和实战经验(五) ORACLE 11 G版本2 RAC在LINUX ...
- 经典问题:查询有多少段区间和等于k值
题目连接 题意:在大小为1e5以内的数组求存在多少个区间和的值等于k的次方 这种题很经常见,总是想着用两个for循环解决,但是一定会超时. 题解:算出前缀和,使用map去查找mp[sum[i+1]-t ...