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())存在一定的误差,尽量不要使用。

原文地址:http://www.manongjc.com/article/11778.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 本文转载自PostGIS中的常用函数并稍加修改 说明:这里许多函数是以ST_[X]yyy形式命名的,事实上很多函数...
    AllanHao阅读 6,931评论 0 4
  • from PostgreSQL+PostGIS 的使用 一、PostGIS中的几何类型 PostGIS支持所有O...
    山华水清阅读 6,938评论 0 5
  • 先了解几个基本概念,有助于了解本文应用场景 地理信息系统GIS-百度百科 地理信息系统(Geographic In...
    KICHUN阅读 24,773评论 8 10
  • 吾日三省: 1.不要管别人怎样,那是别人的事,要着眼于你的现状,努力做得更好。 2.不要对别人太好,因为那是一种负...
    高能磷酸阅读 100评论 0 0
  • 珍惜着生命!努力与改变中!
    王文琦阅读 111评论 0 0