PHP MySQL 从 GPS 获取半径用户位置的位置
例如,我的数据库中有汽车事故。这些事件有纬度和经度。在使用 GPS 的手机上,我可以获取用户的位置及其坐标。用户可以选择他想知道他周围是否有事件的半径。假设他想了解他周围 2 英里的事件。
因此,我将用户的纬度、经度和他选择的半径从手机发送到网络服务。我需要进行 SQL 查询来获取用户周围 2 英里的事件。
你知道该怎么做吗?
I have in my database car incidents for example. These incidents have a latitude and longitude. On a mobile using the GPS, I get the user's location with his coordinates. The user can select a radius that he wants to know if there are incidents around him. So let's say he want to know incidents 2 miles around him.
So I send from the phone to a web service the user's latitude, longitude and the radius he selected. I need to make a SQL query to get the incidents 2 miles around the user.
Do you have any idea how to do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如其他人所说,计算距离的计算成本相当高。返回巨大的数据集也不是一个好主意 - 特别是考虑到 PHP 的性能并不是那么好。
我会使用启发式方法,例如通过简单的加法和减法来近似距离。
只需搜索数据库中包含该范围内的事件(实际上是一个正方形,而不是一个圆形),然后您就可以使用 PHP 处理这些事件。
编辑:这是一个替代方案;计算成本较低的近似值:
以英里为单位的近似距离:
您可以通过添加余弦数学函数来提高此近似距离计算的准确性:
改进以英里为单位的近似距离:
来源: http://www.meridianworlddata.com/Distance-Calculation.asp
编辑2:我跑了一堆使用随机生成的数据集进行测试。
绝对不值得。只需进行近似即可。
代码在这里:http://pastebin.org/424186
Calculating the distance is pretty computationally expensive, as others have said. Returning huge datasets is also not a very good idea - specially considering PHP isn't that great in performance.
I would use a heuristic, like approximating the distance with simple addition and subtraction.
Just search the db with incidents within that range (effectively a square, rather than a circle), and then you can work on those with PHP.
EDIT: Here's an alternative; an approximation that's way less computationally expensive:
Approximate distance in miles:
You can improve the accuracy of this approximate distance calculation by adding the cosine math function:
Improved approximate distance in miles:
Source: http://www.meridianworlddata.com/Distance-Calculation.asp
EDIT 2: I ran a bunch of tests with randomly generated datasets.
Definitely not worth it. Just go with an approximation.
Code is here: http://pastebin.org/424186
如果您的数据库不太大,则获取所有数据并通过函数运行它比使用查询更快。
它也适用于公斤和海里。 ;)
Its faster to fetch all the data and run it through a function, rather than use a query if your database isn't too big.
It works for Kilos and Nautical miles too. ;)
另外,如果您正在寻找这方面的好读物/教程..请查看此处
http://www.phpfreaks.com/forums/index.php/主题,208965.0.html
Also, if you're looking for a good read/tutorial on this.. Check here
http://www.phpfreaks.com/forums/index.php/topic,208965.0.html
我快速搜索了一下,找到了这篇博文,它给出了很好的解释和可供选择的 SQL给定半径内的记录。
在评论中,他建议“为了提高大型数据集的速度,您可能希望首先通过在纬度/经度之间添加一英里左右作为原点,然后使用上面的内容作为子选择来工作,从而在原点周围抓取一个正方形块从中间向外”,这对我来说听起来像是要走的路。
I did a quick search and turned up this blog post which gives a good explanation and SQL to select records in a given radius.
In the comments, he suggests "For speed on large datasets you probably want to grab a square block around the origin point first by adding a mile or so to and from both lat/lon for origin and then using the above as a subselect to work from the middle out" which sounds to me like the way to go.
有一个公式可以计算两个纬度/经度坐标之间的距离。但请注意——这在计算上相当昂贵,所以如果你有很多事件,你会想要聪明地对待它。首先,了解涉及数学。
至于PHP代码,快速谷歌一下就找到了 此链接,看起来可能有效。
现在,您可能希望使用一些更有效的方法将事件点分为两组:那些可能在范围内的点(希望是一个较小的集合),以及那些您可以完全忽略的点。检查几十个事件坐标可能会出现性能问题。
我对此没有任何特别的见解,但如果没有其他人提出一些聪明的东西,我会在时间允许的情况下尝试自己想出一些东西。
There is a formula to compute the distance between two lat/lon coordinates. Beware though -- it's rather computationally expensive, so if you have lots of incidents, you'll want to be smart about it. First up, read about the maths involved.
As for PHP code, a quick google turned up this link, which looks like it probably works.
Now, you probably want to use some more efficient method to divide your incident points into two sets: those points that might be within range (hopefully a smallish set), and those that you can discount entirely. Checking more than a few dozen incident coordinates is likely to be a performance issue.
I don't have any particular insight into that, but if nobody else comes along with something clever, I'll try to come up with something myself later, time permitting.