【问题标题】:Google Maps geocoding working from browser but not from PHP server谷歌地图地理编码从浏览器工作,但不是从 PHP 服务器
【发布时间】:2017-06-01 06:55:36
【问题描述】:

当我从浏览器获取 Google Maps Geocoding API 时,它可以正常工作,但不能从我的 PHP 脚本中获取。

工作https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France

返回:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "La Pérelle",
               "short_name" : "La Pérelle",
               "types" : [ "colloquial_area", "political" ]
            },
         ],
         "formatted_address" : "La Pérelle, 38380, France",
         // other stuffs
         "partial_match" : true,
         "place_id" : "ChIJZzDRRAX4ikcRnZ-vb1tnTgY",
         "types" : [ "colloquial_area", "political" ]
      }
   ],
   "status" : "OK"
}

不工作

<?php 
$url = 'https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France';
echo file_get_contents($url);

返回:

{
   "results" : [],
   "status" : "ZERO_RESULTS"
}

有什么想法吗?

更新:有些人也没有从他们的浏览器中看到任何结果。 Google 可以利用我的职位来展示不错的结果吗?

【问题讨论】:

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


【解决方案1】:

(缺乏)语言偏好是这个问题最常见的原因。

当您从浏览器发送 API 请求时:

https://maps.google.com/maps/api/geocode/json?address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France

您的浏览器语言首选项可能会设置为首选法语作为第一语言,这会使您的浏览器包含与所有请求一起发送 Accept-Language 标头。

Google 地理编码 API 将检查 language GET 参数,如果没有,它将检查 Accept-Language 标头作为备份。如果您的浏览器设置为首选法语内容,则上述请求应等同于

https://maps.google.com/maps/api/geocode/json?address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France&language=fr

对我来说,因为我的浏览器设置为首选英语,所以第一个请求返回“La Perelle, 73130 Saint-François-Longchamp, France”,而第二个请求返回“La Pérelle, 38380 Saint-Pierre-de-Chartreuse, France ”。

自 2016 年底推出新的地理编码器以来,region 参数不再是唯一影响结果的参数,language 参数现在确实影响结果:

首选语言对结果集的影响很小 API 选择返回,以及它们返回的顺序。 地理编码器对缩写的解释不同,具体取决于 语言,例如街道类型的缩写或同义词 可能在一种语言中有效,但在另一种语言中无效。例如,utca 和 tér 在匈牙利语中是 street 的同义词。

也就是说,如果“La Perelle, 73130 Saint-François-Longchamp, France”对于上述查询(La Pérelle, Saint-Pierre-de-Chartreuse, France)来说只是一个糟糕的结果,请考虑filing a bug report

【讨论】:

    【解决方案2】:

    我认为与region biasing地区有关。

    尝试添加region 参数(尽管如果您有许多不同区域的请求,您可能需要在构建请求时预先计算它)。

    例如,对于来自西班牙马德里的我来说,这个请求带来的结果为零:

    https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France
    

    但是,如果我添加 region=fr 参数

    https://maps.google.com/maps/api/geocode/json?sensor=false&region=fr&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address=La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France
    

    我明白了:

    {
       "results" : [
          {
             "address_components" : [
                {
                   "long_name" : "Chartreuse Mountains",
                   "short_name" : "Chartreuse Mountains",
                   "types" : [ "establishment", "natural_feature" ]
                },
                {
                   "long_name" : "Saint-Pierre-d'Entremont",
                   "short_name" : "Saint-Pierre-d'Entremont",
                   "types" : [ "locality", "political" ]
                },
                {
                   "long_name" : "Isere",
                   "short_name" : "Isere",
                   "types" : [ "administrative_area_level_2", "political" ]
                },
                {
                   "long_name" : "Auvergne-Rhône-Alpes",
                   "short_name" : "Auvergne-Rhône-Alpes",
                   "types" : [ "administrative_area_level_1", "political" ]
                },
                {
                   "long_name" : "France",
                   "short_name" : "FR",
                   "types" : [ "country", "political" ]
                },
                {
                   "long_name" : "73670",
                   "short_name" : "73670",
                   "types" : [ "postal_code" ]
                }
             ],
             "formatted_address" : "Chartreuse Mountains, 73670 Saint-Pierre-d'Entremont, France",
             "geometry" : {
                "location" : {
                   "lat" : 45.3773525,
                   "lng" : 5.827970700000001
                },
                "location_type" : "APPROXIMATE",
                "viewport" : {
                   "northeast" : {
                      "lat" : 45.3787014802915,
                      "lng" : 5.829319680291503
                   },
                   "southwest" : {
                      "lat" : 45.3760035197085,
                      "lng" : 5.826621719708499
                   }
                }
             },
             "place_id" : "ChIJSXJWFav4ikcREQZmf4QdYMc",
             "types" : [ "establishment", "natural_feature" ]
          }
       ],
       "status" : "OK"
    }
    

    【讨论】:

    • 感谢您的完整回答。不幸的是,这不是我预期的结果......(不是同一个地方)。我要找place_id
    • 不过,我认为这与区域偏差 + 不完整的搜索输入有关。你得到了你期望的结果,因为你的位置帮助谷歌“猜测”正确的位置。是不是也可以通过邮政编码?这是对地址进行地理编码时对我最有用的提示。
    • @HugoH,另外,我看到“Saint-Pierre-de-Chartreuse”是您请求的一部分,但不是您的回复的一部分。同样,由于您的位置,Google 大部分时间都猜对了。
    • 为了清楚起见,在我删除其中一些之前,它就在结果中。 ;)
    【解决方案3】:

    我觉得我需要发表评论,因为我已经花了一些时间来解决这个问题 - 我遇到了同样的问题,解决的方法是添加“位置”和“半径”参数 - 我猜 Google 会从浏览器中猜测这些标头,但不能通过裸请求这样做。太糟糕了,他们的 API 没有在他们的文档中指定这些参数是强制性的,它们似乎是针对直接请求的。

    【讨论】:

      【解决方案4】:

      它正在工作

      $url = 'https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address='.urlencode('La Pérelle, 38380, France');
      

      【讨论】:

        【解决方案5】:

        yivi answer 之后,基于区域偏差,我必须找到另一种方法来链接前端和后端位置,我使用place_id 做到了。

        这在以前是不可能的,因为谷歌没有从它的自动完成中返回 place_id,但现在 it works,所以我这样做了:

        echo file_get_contents('https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyA3U9jkQcF-Vplh6bpJNcVOWMSNImCPn04&place_id=ChIJZzDRRAX4ikcRnZ-vb1tnTgY');
        

        【讨论】:

          【解决方案6】:

          这将正常工作。

          $address = "La Pérelle, 38380, France";
          $prepAddr = str_replace(' ','+',$address);
          $url = 'https://maps.google.com/maps/api/geocode/json?key=YOUR_KEY&address='.$prepAddr.'&sensor=false';
          $ch = curl_init();
          curl_setopt ($ch, CURLOPT_URL, $url);
          curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 5);
          curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
          $contents = curl_exec($ch);
          curl_close($ch);
          $output = json_decode($contents);
          

          【讨论】:

            【解决方案7】:
            <?php 
            $address="La Pérelle, 38380, France";
            $url = 'https://maps.google.com/maps/api/geocode/json?sensor=false&key=AIzaSyDqIj_SXTf5Z5DgE_cvn5VF9h5NbuaiCbs&address='.urlencode($address);
            echo file_get_contents($url);
            

            希望这对你有用。您的地址未格式化为请求格式。

            感谢和问候

            【讨论】:

            • 是的,但不是。地址已经格式化:La%20P%C3%A9relle,%20Saint-Pierre-de-Chartreuse,%20France
            • 我刚刚测试了这段代码,它在这里工作。看来问题出在其他地方。
            • 我认为您的回答重复了问题的代码。没有办法解决这个问题,imo。
            • Yivi,谢谢你告诉我,但你可以看到我的评论和其他 cmets 介于​​一小部分之间,我没有重复他的回答......希望可以理解......
            猜你喜欢
            • 1970-01-01
            • 2016-12-02
            • 1970-01-01
            • 1970-01-01
            • 2023-04-09
            • 2013-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多