Google API的一致结果

时间:2018-11-29 18:36:06

标签: php arrays json

使用Google API从两种选择(按纬度和经度)之一确定县时,结果不一致。一个以2的键给县。另一个键为4。如何在这种不一致的情况下获取所需的信息?

我只用过几次Json,所以也许我误解了如何获取值,所以这是我的PHP函数来解析它:

function getCounty($LatLong) {
    global $googlekey;
    $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=$LatLong&key=$googlekey";
    $json = @file_get_contents($url);
    $data = json_decode($json);
    $status = $data->status;
    if ($status === "OK") :
        //return $data->results[0]->address_components[2]->long_name;
        return $data->results[0]->address_components[4]->long_name;
    else :
        return FALSE;
    endif;
}

换句话说,要获得一个县名,它需要这样做:

返回$ data->结果[0]-> address_components [2]-> long_name;

。 。 。而需要它来获取其他县名称:

返回$ data->结果[0]-> address_components [4]-> long_name;

这违背了试图动态查找正在使用哪个县的目的!

使用Json解析它,为一个县(县的关键字为2)给出此信息(输出的一部分)

[2] => stdClass Object
    (
        [long_name] => Santa Cruz County
        [short_name] => Santa Cruz County
        [types] => Array
            (
                [0] => administrative_area_level_2
                [1] => political
            )

    )

[3] => stdClass Object
    (
        [long_name] => California
        [short_name] => CA
        [types] => Array
            (
                [0] => administrative_area_level_1
                [1] => political
            )

    )

[4] => stdClass Object
    (
        [long_name] => United States
        [short_name] => US
        [types] => Array
            (
                [0] => country
                [1] => political
            )

    )

。 。 。这将另一个县的密钥设置为4:

[2] => stdClass Object
    (
        [long_name] => West Valley
        [short_name] => West Valley
        [types] => Array
            (
                [0] => neighborhood
                [1] => political
            )

    )

[3] => stdClass Object
    (
        [long_name] => San Jose
        [short_name] => San Jose
        [types] => Array
            (
                [0] => locality
                [1] => political
            )

    )

[4] => stdClass Object
    (
        [long_name] => Santa Clara County
        [short_name] => Santa Clara County
        [types] => Array
            (
                [0] => administrative_area_level_2
                [1] => political
            )

    )

话虽如此,有没有办法直接从IP地址获取县?我看到Google不满意的地方,但是在Google API文档中,我看到了使用IP的引用,但没有示例,因此在如何实现上含糊其词。

2 个答案:

答案 0 :(得分:1)

正如@enricog所说;您想要的是根据特定类型提取值。

基于文档:https://developers.google.com/maps/documentation/geocoding/intro?hl=de#Types

以下是您可以做什么的想法:

$data = json_decode($json);
$counties = [];

foreach($data->results as $result){
    $counties = array_merge($counties, array_filter($result->address_components, function ($address) { 
        return in_array('administrative_area_level_2', $address->types);
    })); 
}


$counties = array_map(function ($county) { 
    return $county->long_name;
}, $counties); 

echo implode(', ', $counties);

https://3v4l.org/UUboK

我不使用google map API,我不知道您是否可以在响应中包含多个县。 JSON结构允许它,我想取决于请求是什么,它可能有一些。 我向json添加了虚构值来验证该原理。

我相信此代码段可以优化。但是至少它将从响应中返回每个县,并且您不会得到undefined index

  

评论

使用了API之后,我现在可以更精确地回答。但这只是我的事。 当您请求位置时,它将返回许多您所在位置附近的已知位置。第一个结果应该始终是最接近您的。

Google的注释:反向地理编码不是一门精确的科学。地理编码器将尝试在一定的公差范围内找到最接近的可寻址位置。

基于此,我们可以对代码进行优化,以使其只有一个结果应该是正确的县。

function getCounty($LatLong) {
    // do stuff
    $data = json_decode($json);
    $counties = [];

    if(!empty($data->results)){
        $counties = array_merge($counties, array_filter($data->results[0]->address_components, function ($address) { 
            return in_array('administrative_area_level_2', $address->types);
        })); 
    }

    if(!empty($counties)){
        return reset($counties)->long_name; // https://stackoverflow.com/a/3771228/8068675
    }
    return 'No county found';
}

https://3v4l.org/5RGOe
我确实读过,您在不使用PHP 7的地方。但是,自php 5.6 is no longer supported起,我将保留与PHP 7兼容的代码,并且不应再使用。

答案 1 :(得分:0)

使用cbaconnier的循环并将其限制为仅运行一次,现在可以正常工作了!注意$ counties = [];在我的本地PHP 7.2开发系统上工作,但不在实时服务器上的旧版本PHP上工作,因此我将其更改为$ counties = array();。

感谢您的所有帮助。现在,如果有一种直接从IP进行操作的方法,我想知道它是什么!

function getCounty($LatLong) {
    global $googlekey;

    $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=$LatLong&key=$googlekey";
    $json = @file_get_contents($url);
    $data = json_decode($json);
    $status = $data->status;
    if ($status === "OK") :
        //$counties = []; // for later PHP versions but does not work on live server
        $counties = array();

        $i = 0;
        foreach (range(1, 1)  as $i) :
            foreach($data->results as $result) :
                if ($i++ > 1) break;
                $counties = array_merge($counties, array_filter($result->address_components, function ($address) { 
                    return in_array('administrative_area_level_2', $address->types);
                })); 
            endforeach;
        endforeach;

        $counties = array_map(function ($county) { 
            return $county->long_name;
        }, $counties);

        return $counties[0];

    else :
        return FALSE;
    endif;
}