mysql gis 中文:http://dev.mysql.com/doc/refman/5.1/zh/spatial-extensions-in-mysql.html#gis-class-polygon
下文为收集资料整理后,并测试后结果
当前只有MyISAM引擎的数据表支持地理空间数据的存储
建表:
CREATE DATABASE geodatabase;
USE geodatabase;
CREATE TABLE test(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(128) NOT NULL,
pnt POINT,
line LINESTRING,
pgn POLYGON
)ENGINE=MyISAM;
添加空间列,在geom表里添加可以存储point类型数据
ALTER TABLE geom ADD pt POINT;
用以下SQL插入一条空间数据
INSERT INTO `test` 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))')
);
这里也可以用通行的GEOMFROMTEXT函数实现WKT到数据库内部几何格式的转换。而GEOMFROMWKB函数用于转换WKB。
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))')
)
这个函数很有用:Envelope
Envelope(g)
返回几何值g的最小边界矩形(MBR)。结果以Polygon值的形式返回。
多边形(polygon)是由边界框的顶点定义的:
POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
mysql> SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))); +-------------------------------------------------------+ | AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))) | +-------------------------------------------------------+ | POLYGON((1 1,2 1,2 2,1 2,1 1)) | +-------------------------------------------------------+
或者多个点面集合:
SELECT AsText( Envelope( GeomFromText('GeometryCollection(Point(10 2),Point(9 9),LineString(2 2, 3 30),LineString(200 200, 3 30),Polygon((400 300,10 0,10 10,0 10,400 300)),Point(100 100))' ) ) ) ;
用以下SQL从数据表中获得空间数据
SELECT id,name,ASTEXT(pnt),ASTEXT(line),ASTEXT(pgn) from `test`;
ASTEXT函数的功能与GEOMFROMTEXT的功能恰好相反,就是将数据从内部格式转换为WKT;相应的ASBINARY可以转换为WKB。
MYISAM.
这样就创建成功了
2 在geom表里添加可以存储point类型数据
ALTER TABLE geom ADD pt POINT;
3 向point列添加标准的空间数据
4 数据已经存进去了,只要把它去出来,第三个问题也就解决啦!
这是从mysql的空间数据列中取出标准的wtk格式空间数据的函数AsText().
现在我需要的功能是查找一辆车在某一段时间内是否在一段区域内经过,用点来说明的话,就是一个空间坐标点在一个特定时间段内是否包含在一个特定的矩形区域内。下面这个函数应该能达到这个功能:
-
MBRWithin(g1,g2)
SELECT AsText(pnt) FROM `gis` WHERE MBRWithin(pnt,GeomFromText('Polygon(1 1,0 30,30 30,30 0,1 )'))
我需要解决的问题中只需要矩形这个几何体,而在OpenGIS的Geometry Model的二维矩形表示用不带孔的Polygon就行了。Polygon是二维对象Surface的子类。
上图中的Polygon含有一个孔.
如果要构造一个矩形,只要构造一个没有孔的封闭四边形的Polygon。
带一个孔的Polygon的表示
看到上面的Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))’;(Polygon第一个参数是外部边界,第二个或者[第三个,第四个]都是Polygon里面的孔)
0 0,0 3,3 0,0 0围成的图形是是一个三角形,中间有一个孔(相当于被挖空的一块),也是三角形(1 1,1 2,2 1,1 1))(在纸上画下就知道了)
通过面积也可以知道孔是被挖掉的(3*3/2-1*1/2=4);
我现在要构造一个不带孔的矩形
那现在要构造一个矩形就简单的多了
呵呵算一下面积正好是矩形的面积。那跟预想的一样。
现在矩形也有了,点也有了,我们用mysql提供的函数来实际解决下问题4吧。
(具体的函数见mysql4.1文档的空间数据库特性那节,现在mysql4.1只提供MySQL提供了一些可测试两个几何对象g1和g2最小边界矩形之间关系的函数。
OpenGIS规范定义了下述函数。目前在MySQL尚未按照规范实施它们。对于那些已实施的函数,它们返回的结果与对应的基于MBR的函数返回的相同。包括下面列出的函数,但Distance()和Related()除外。
在未来的版本中,可能会实施这些函数,为空间分析提供全部支持,而不仅仅是基于MBR的支持。)
我们用到的函数有2个:
-
MBRContains(g1,g2)
返回1或0以指明g1的最小边界矩形是否包含g2的最小边界矩形。
-
MBRWithin(g1,g2)
返回1或0以指明g1的最小边界矩形是否位于g2的最小边界矩形内。
现在表中有6个点
我们来构造一个矩形。
现在来用MBRContains(g1,g2)测试下这个矩形包含了哪些点
返回了,和预想的一样:P
再来测试下MBRWithin(g1,g2)函数
参考文献 :
http://classicning.iteye.com/blog/100323
http://blog.csdn.net/snailjava/article/details/1337433