使用空间点types在MySQL中存储Lat Lng值
技术使用:MySQL 5.1和PHP 5.3
我只是为我正在撰写的网站devise一个新的数据库。 我正在研究现在存储Lat和Lng值的最佳方法。
在过去,我一直在使用DECIMAL,并使用PHP / MySQLselectforms:
SQRT(POW(69.1 * (fld_lat - ( $lat )), 2) + POW(69.1 * (($lon) - fld_lon) * COS(fld_lat / 57.3 ), 2 )) AS distance
find最近的匹配地点。
开始阅读更多关于新技术,我想知道如果我应该使用空间扩展。 http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html
虽然信息很薄弱,但是如何存储数据还是有问题的。 而不是使用DECIMAL,我现在将使用POINT作为数据types?
另外,一旦存储为POINT,只需要从中获取Lat Lng值,以便我想将其绘制在地图上,还是应该再次将经纬度值存储为DECIMALS?
我知道我应该使用PostGIS作为这里的大多数post说我只是不想学习一个新的数据库,但!
跟进
我一直在玩新的POINTtypes。 我已经能够使用以下添加Lat Lng值:
INSERT INTO spatialTable (placeName, geoPoint) VALUES( "London School of Economics", GeomFromText( 'POINT(51.514 -0.1167)' ));
然后我可以从Db中获取Lat和Lng值:
SELECT X(geoPoint), Y(geoPoint) FROM spatialTable;
这一切看起来不错,但距离的计算是我需要解决的一点。 显然MySQL有一个距离函数的占位符,但不会被释放一段时间。 在几篇文章中,我发现我需要做下面的事情,但是我认为我的代码有点不对劲:
SELECT placeName, ROUND(GLength( LineStringFromWKB( LineString( geoPoint, GeomFromText('POINT(52.5177, -0.0968)') ) ) )) AS distance FROM spatialTable ORDER BY distance ASC;
在这个例子中,geoPoint是使用上面的INSERTinput到数据库中的一个POINT。
GeomFromText('POINT(52.5177, -0.0968)'
是我想要计算距离的Lat Lng值。
更多后续
相当愚蠢的是,我刚刚放入SQL的ROUND部分,却没有真正想到。 拿出来给我:
SELECT placeName, (GLength( LineStringFromWKB( LineString( geoPoint, GeomFromText('POINT(51.5177 -0.0968)') ) ) )) AS distance FROM spatialTable ORDER BY distance ASC
这似乎给我正确的距离,我需要。
我想现在唯一需要回答的是关于我是否现在使用Spatial或者面向未来的自己来使自己生活困难的想法…
我认为你应该总是使用容易获得的最高级抽象。 如果您的数据是地理空间数据,则使用地理空间对象。
不过要小心。 Mysql是目前最糟糕的地理空间数据库。 它可以点但它的所有多边形函数完全被破坏 – 它们将多边形更改为其边界矩形,然后做出答案。
打我的最糟糕的例子是,如果你有一个代表日本的多边形,并且你问在日本什么地方,符拉迪沃斯托克进入列表!
Oracle和PostGIS没有这个问题。 我期望MSSQL不会使用任何使用JTS作为引擎的Java数据库。 地理空间良好。 MySQL地理空间不好。
刚刚阅读这里如何使用MySQL空间查询来查找X半径中的所有logging? 它固定在5.6.1。
Hoorah!
Mysql GIS yagni:
如果你对地理信息系统没有经验,学习空间扩展实际上就像学习一个新的数据库,再加上一点math和大量的缩写。 地图,投影,Srids,格式…您是否需要学习所有计算给定经纬度的点之间的距离:可能不是,您将要整合第三方GIS数据还是使用比点更复杂的任何东西你将使用坐标系统吗?
回到yagni:做一些简单的事情,在这种情况下,用php或简单的SQL来实现你的代码。 一旦你到达一个障碍,并决定你需要空间,阅读GIS系统,协调系统,项目和公约。
届时,您可能会需要PostGIS。
这是一件好事,因为那样你就可以在查询中使用空间索引。 例如,限制到一个边界框,以限制要比较的行数。
如果您可以在后端添加一些额外的代码,请使用Geohash。
它以前缀表示更广的区域的方式将坐标编码成string。 你的string越长,精度就越高。
它对许多语言都有绑定。
http://en.wikipedia.org/wiki/Geohash https://www.elastic.co/guide/en/elasticsearch/guide/current/geohashes.html