【问题标题】:Near location search on Google Maps, PHP & MySQL在 Google 地图、PHP 和 MySQL 上进行附近位置搜索
【发布时间】:2013-05-18 20:50:36
【问题描述】:

我正在构建一个网络应用程序(只是为了好玩 xD),您可以在其中告诉它您在哪里以及您想去哪里,然后您可以搜索您可能乘坐的巴士列表。

我的数据库是这样的:

buses
---------------------------------
id | bus_number | bus_description

routes
-----------------------
id | bus_id | lat | lng

您可能会注意到,路线表存储了公共汽车遵循的路线点,如果找到任何搜索结果,我将用折线显示这些点。 问题是我如何编写一些 SQL,给定这 2 个参数(用户在哪里,他想去哪里)并找到并显示正确的总线?

我从 Google Maps 文档中找到了这个 select 语句,这很好(而且效果很好!)因为它可以告诉我给定的 Lat/Lng 是否在另一个的半径(在本例中为 25 英里)内:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

但我需要它与给定 Lat/Lng 的 2 一起工作,这样我就可以知道用户必须在哪里乘坐公共汽车,以及在哪里下车。

谢谢!!

(哦,我忘了,有一个 preview,只是普通的 html,没有任何工作,但如果你想看看我打算如何设计这个应用程序,这很有用。顺便说一句,它是西班牙语,你可以进去english google translated)

更新:以下是路线表上的一些示例数据:

+----+-------+------------+------------+
| id | bus_id| lat        | lng        |
+----+-------+------------+------------+
|  1 |     1 | -31,527273 | -68,521408 |
|  2 |     1 | -32,890182 | -68,844048 |
|  3 |     1 | -31,527273 | -68,521408 |
|  4 |     1 | -32,890182 | -68,844048 |
|  5 |     1 | -31,527273 | -68,521408 |
|  6 |     2 | -32,890182 | -68,844048 |
|  7 |     2 | -31,527273 | -68,521408 |
|  8 |     2 | -32,890182 | -68,844048 |
|  9 |     2 | -31,527273 | -68,521408 |
|  10|     2 | -32,890182 | -68,844048 |
+----+-------+------------+------------+

忽略重复的 lat,lng 值,关键是一条公交路线会有很多,数百个点来描述完整的路线。

【问题讨论】:

  • 我不明白这一点。公共汽车是从 A 到 B 还是从 A..B ?您可以在此处转储一些数据。
  • 巴士从 A..B 出发,所以路线表会是这样的:id|bus_id|lat|lng ---------------------- 1, 1, -43.341,-33.2321 2, 1, -43.342,-33.2322 3, 1, -43.343,-33.2323 4, 1, -43.344,-33.2324
  • (好吧,我不知道 cmets 的“代码”格式是如何工作的)
  • 好的,你找到了相对于用户最近的公交车站,以及相对于目的地最近的公交车站,然后检查 A 站是否与 B 站在同一条路线上(尝试匹配它们),类似的。
  • 是的,这正是我所需要的。我想我可以选择第一个 lat/lng 值,然后选择第二个 lat/lng,然后比较或交叉一些表格。

标签: php mysql google-maps


【解决方案1】:

好的,让我们开始吧,使用下面的查询,您可以获得在一定半径(英里)内最近的公交车站。查询将返回定义半径内的每个点。

$lat = -31,52;
$lon = -68,52;

$multiplier = 112.12; // use 69.0467669 if you want miles
$distance = 10; // kilometers or miles if 69.0467669

$query = "SELECT *, (SQRT(POW((lat - $lat), 2) + POW((lng - $lng), 2)) * $multiplier) AS distance FROM routes WHERE POW((lat - $lat), 2) + POW((lng - $lng), 2) < POW(($distance / $multiplier), 2) ORDER BY distance ASC";

结果...最近的半径为 10 英里...

最远但在 10 英里以内...

现在对destination 重复相同的操作,然后在您的表中搜索该路线上的巴士。 另请查看此链接...http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

【讨论】:

  • 谢谢webarto!这是最终的 SQL:SELECT id, number FROM buses WHERE id IN (SELECT bus_id FROM coord WHERE POW((lat - $to_lat), 2) + POW((lng - $to_lng), 2) &lt; POW(($distance / 69.0467669), 2)) AND id IN (SELECT bus_id FROM coord WHERE POW((lat - $in_lat), 2) + POW((lng - $in_lng), 2) &lt; POW(($distance / 69.0467669), 2)) 还有一个问题,我怎样才能把它放在公里数上?
  • 在我开发类似的应用程序时,我花了几天时间才弄清楚所有事情。祝你好运。我以为你用里程。我也用公里。我会更新答案。
  • @ricardocasares 只需将 69.x 替换为 111.12 即可。
  • 如果这些坐标表示您的位置,您应该为每个轴使用不同的公里/度值:zodiacal.com/tools/lat_table.php 表示纬度 -68 附近的每个经度度数只有 23 英里
【解决方案2】:

我认为您必须执行以下操作:

1) 在路径表中搜索用户想要的destination X 距离内的所有点,并将每个点存储到一个数组中:

  • bus_id
  • 该路线行与 用户
  • 路由行 ID

2) 找到每个 bus_id 的最小距离,为每个 bus_id 留下一个由单个点组成的较小数组(不确定最好的方法,但可能使用距离进行第二次查询,升序排序,限制 1)

3) 遍历这个数组,在路由表中搜索距离用户起点AND有正在测试的bus_id的所有点.将它们放在第二个数组中

4) 对端点数组重复步骤 2

5) 现在每个数组中的每个 bus_id 都应该有一个点,因此您可以为出现在两个集合中的每个 bus_id 绘制折线(如果您有一个非常用户友好的交通系统,则可能不止一个)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2016-09-09
    相关资源
    最近更新 更多