【问题标题】:Finding towns within a 10 mile radius of postcode. Google maps API查找邮政编码半径 10 英里范围内的城镇。谷歌地图 API
【发布时间】:2011-12-29 10:22:27
【问题描述】:

我最近开始查看 Google Maps API 以尝试在我的网站中尝试一些新的东西。我目前正在使用此代码:

<?php

$postcode = $_REQUEST['postcode'];

$url = 'http://maps.googleapis.com/maps/api/geocode/xml?address='.$postcode.'&sensor=false';
$parsedXML = simplexml_load_file($url);

if($parsedXML->status != "OK") {
echo "There has been a problem: " . $parsedXML->status;
}

$myAddress = array();
foreach($parsedXML->result->address_component as $component) {
if(is_array($component->type)) $type = (string)$component->type[0];
else $type = (string)$component->type;

$myAddress[$type] = (string)$component->long_name;
}
header('Content-Type: application/json');
echo json_encode($myAddress);


?>

它只是使用我定义的邮政编码并搜索 Google 数据库,然后返回城镇、县等。

如果可能,我不仅想显示最近的城镇,还想显示半径 5-10 英里范围内的任何城镇。有人可以告诉我该怎么做吗?

感谢您的帮助

【问题讨论】:

  • stackoverflow.com/search?q=radius+search+google+maps+php 有一些很有希望的问答 - 您检查了哪些,为什么它们没有帮助您解决问题?
  • 我会看看这些,我在输入问题时确实查看了建议的帖子,但没有看到太多有用的东西。你知道我可以在哪里获得英国邮政编码数据库而无需支付皇家邮政愚蠢的钱吗?我看到一篇文章说 wikileaks 发布了它,但这是在 2009 年,所以我猜它不是完全最新的
  • 不知道,抱歉。一个快速的谷歌提出了ordnancesurvey.co.uk/opendatadownload/products.html,但我不确定这些是否可以免费使用或有帮助。

标签: php google-maps google-maps-api-3


【解决方案1】:

更新:我在http://www.mullie.eu/geographic-searches/上写了一篇关于这个特定主题的更详细的博文

--

使用 Google Maps API 遍历所有可用城镇以获取其纬度和经度。将这些保存在某处(数据库)。 - 请注意,Google 不会接听大量电话,因此请限制您的电话。

那么,在获取城镇的时候,可以使用类似下面的代码来获取一定范围内的城市:

public static function getNearby($lat, $lng, $type = 'cities', $limit = 50, $distance = 50, $unit = 'km')
{
    // radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
    if ($unit == 'km') $radius = 6371.009; // in kilometers
    elseif ($unit == 'mi') $radius = 3958.761; // in miles

    // latitude boundaries
    $maxLat = (float) $lat + rad2deg($distance / $radius);
    $minLat = (float) $lat - rad2deg($distance / $radius);

    // longitude boundaries (longitude gets smaller when latitude increases)
    $maxLng = (float) $lng + rad2deg($distance / $radius / cos(deg2rad((float) $lat)));
    $minLng = (float) $lng - rad2deg($distance / $radius / cos(deg2rad((float) $lat)));

    // get results ordered by distance (approx)
    $nearby = (array) FrontendDB::getDB()->retrieve('SELECT *
                                                    FROM table
                                                    WHERE lat > ? AND lat < ? AND lng > ? AND lng < ?
                                                    ORDER BY ABS(lat - ?) + ABS(lng - ?) ASC
                                                    LIMIT ?;',
                                                    array($minLat, $maxLat, $minLng, $maxLng, (float) $lat, (float) $lng, (int) $limit));

    return $nearby;
}

以上代码注意事项:

  • 使用了自己的数据库包装器,因此转换为 mysql_query、PDO、...
  • 这并不准确。我们无法在 DB 中进行精确的球面计算,因此我们采用了经纬度上下限。这基本上意味着一个位置比您的距离稍远(例如,在远东北,就在实际半径之外(实际上几乎是一个圆),但仍在最大纬度和经度之内(因为我们比较它在数据库中的平方范围内)。这只会在您的半径范围内提供粗略但绝对 100% 准确的城市选择。

我将尝试说明这一点:

_________________
|      / \      |
| Y  /     \    |
|  /         \  |
|(      X      )|
|  \         /  |
|    \     /    |
|______\_/______|

上面的圆圈(有点)是你想要在其中找到位置的实际半径,基于位置 X。这很难直接从你的数据库中完成,所以我们实际上从数据库中获取的是周围的正方形.如您所见,位置(如 Y)可能位于这些最大和最小边界内,尽管它们实际上并不在请求的半径范围内。不过这些可以稍后通过 PHP 过滤掉。

要解决最后一个问题,您可以循环所有结果并计算您的根位置和找到的接近匹配项之间的确切距离,以计算它们是否真的在您的半径范围内。为此,您可以使用以下代码:

public static function getDistance($lat1, $lng1, $lat2, $lng2, $unit = 'km')
{
    // radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
    if ($unit == 'km') $radius = 6371.009; // in kilometers
    elseif ($unit == 'mi') $radius = 3958.761; // in miles

    // convert degrees to radians
    $lat1 = deg2rad((float) $lat1);
    $lng1 = deg2rad((float) $lng1);
    $lat2 = deg2rad((float) $lat2);
    $lng2 = deg2rad((float) $lng2);

    // great circle distance formula
    return $radius * acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lng1 - $lng2));
}

这将计算位置 X 和位置 Y 之间的(准)精确距离,然后您可以准确地过滤掉那些足够接近以通过粗略的 db-fetch 的城市,但不仅仅是靠近到实际在您的范围内界限。

【讨论】:

  • 我不知道你为什么只有 6 个 ups =)
猜你喜欢
  • 2012-01-21
  • 1970-01-01
  • 2011-07-28
  • 2012-01-25
  • 2019-10-17
  • 2014-09-09
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
相关资源
最近更新 更多