空间数据库-msyql空间数据大纲

发布时间 2023-05-22 15:10:08作者: 且行且思

MySql支持的类型

  • 点 POINT(15 20) 

  • 线 LINESTRING(0 0, 10 10, 20 25, 50 60) 

  • 面 POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)) 

  • 多个点 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)),简称GEOMETRY,可以放入点、线、面。

空间数据操作

使用示例

# 创建表
CREATE DATABASE geodatabase;
USE geodatabase;
DROP TABLE IF EXISTS test;

DROP TABLE IF EXISTS points;
CREATE TABLE `points` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `location` point NOT NULL,
  PRIMARY KEY (`id`),
  SPATIAL KEY `sp_index` (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

空间数据插入

用通行的GEOMFROMTEXT函数实现WKT到数据库内部几何格式的转换。而GEOMFROMWKB函数用于转换WKB。

# 插入测试数据
INSERT INTO points VALUES (1,'天安门',POINT(116.397389,39.908149));
INSERT INTO points VALUES (2,'颐和园',POINT(116.273106,39.992634));

等价对比

INSERT INTO `points` VALUES(null,'a test string',
POINTFROMTEXT('POINT(15 20)'),
LINESTRINGFROMTEXT('LINESTRING(0 0, 10 10, 20 25, 50 60)'),
POLYGONFROMTEXT('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))'));

INSERT INTO `gis` VALUES(null,'a test strin222g',
GEOMFROMTEXT('POINT(15 20)'),
GEOMFROMTEXT('LINESTRING(0 0, 10 10, 20 25, 50 60)'),
GEOMFROMTEXT('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))'))

空间数据查询

用以下SQL从数据表中获得空间数据

SELECT id,name,ASTEXT(pnt),ASTEXT(line),ASTEXT(pgn) from `test`;
STEXT函数的功能与GEOMFROMTEXT的功能恰好相反,就是将数据从内部格式转换为WKT;相应的ASBINARY可以转换为WKB。

# 定义多边形
SET @rect = CONCAT('POLYGON((116.373871 39.915786,116.417645 39.916444,116.41816 39.900841,116.374214 39.900182,116.373871 39.915786))');
# 使用变量
select name,X(location),Y(location),Astext(location) from points where INTERSECTS( location, GEOMFROMTEXT(@rect) ) ;


常用查询语句案列

st_distance两点之间地理距离: 求两点之间的直线距离

select st_distance(ST_GEOMFROMTEXT("POINT(0 0)"),p.pot),p.`name` from Points p;

AREA计算面积

select AREA(tp.pgn),tp.`name `FROM `t_polygon` tp

ST_Intersects 图形是否有交叉重叠:

SELECT ST_Intersects(tp.pgn,ST_GEOMFROMTEXT("POLYGON((0 0,2 0,2 2,0 2,0 0))")),tp.`name` FROM `Points` tp;

查找指定矩形范围内的点:

SET @bbox = 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))';
SELECT name, AsText(location) FROM Points WHERE Intersects( location, GeomFromText(@bbox) );

 

查找圆形区域内的点

这一步介绍如何查询圆形区域(通常用一个中心点和半径来表示)内的几何对象。

您首先想到的语句可能是:

SET @point = 'POINT(10 10)';

SET @radius = 20;

SELECT name, AsText(location) FROM Points WHERE Distance(location, GeomFromText(@point)) < @radius;

但是这条语句运行会出错,因为Distance函数还没有实现。MySql空间扩展文档说明中已经说明他们只实现了OpenGis标准的一部分。

一个替代的方式是使用intersect函数。

MySql空间扩展文档中已经指明各种几何对象可以使用intersect函数来判断几何对象是否和一个矩形相交。

这样在取得近似范围后我们可以再使用距离估算来过滤出正确的结果。

SET @center = GeomFromText('POINT(10 10)');

SET @radius = 30;

SET @bbox = CONCAT('POLYGON((',X(@center) - @radius, ' ', Y(@center) - @radius, ',',X(@center) + @radius, ' ', Y(@center) - @radius, ',',

X(@center) + @radius, ' ', Y(@center) + @radius, ',',X(@center) - @radius, ' ', Y(@center) + @radius, ',',X(@center) - @radius, ' ', Y(@center) - @radius, '))');

MBRWithin(g1,g2)

现在我需要的功能是查找一辆车在某一段时间内是否在一段区域内经过,用点来说明的话,就是一个空间坐标点在一个特定时间段内是否包含在一个特定的矩形区域内。下面这个函数应该能达到这个功能:

SELECT AsText(pnt) FROM `gis` WHERE MBRWithin(pnt,GeomFromText('Polygon(1 1,0 30,30 30,30 0,1 )'))