阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MySQL中地理位置数据扩展geometry的使用心得

118次阅读
没有评论

共计 6220 个字符,预计需要花费 16 分钟才能阅读完成。

最近学习了些 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。

表结构:

MySQL 中地理位置数据扩展 geometry 的使用心得

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 从现成几何对象创建新的对象

MySQL 中地理位置数据扩展 geometry 的使用心得

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

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计6220字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中