首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在邮政编码方圆10英里范围内寻找城镇。Google地图API

在邮政编码方圆10英里范围内寻找城镇。Google地图API
EN

Stack Overflow用户
提问于 2011-11-15 18:57:25
回答 1查看 24.3K关注 0票数 13

我最近开始查看Google Maps API,以便在我的网站上尝试一些新的东西。我目前使用的是以下代码:

代码语言:javascript
复制
<?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英里的任何城镇。有人能告诉我我该怎么做吗?

谢谢你的帮助

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-15 20:35:38

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

--

使用Google Maps API遍历所有可用城镇以获取它们的纬度和经度。将这些保存在某个地方(数据库)。-当心,谷歌不会接受大量的电话,所以限制你的电话。

然后,当获取一个城镇时,您可以使用类似于以下代码的代码来获取某个范围内的城市:

代码语言:javascript
复制
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%精确选择半径范围内的城市。

我将尝试说明这一点:

代码语言:javascript
复制
_________________
|      / \      |
| Y  /     \    |
|  /         \  |
|(      X      )|
|  \         /  |
|    \     /    |
|______\_/______|

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

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

代码语言:javascript
复制
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,但又不足以实际在您的范围内的城市。

票数 58
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8135243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档