谷歌地图地理编码从浏览器工作,但不是从 PHP 服务器

Posted

技术标签:

【中文标题】谷歌地图地理编码从浏览器工作,但不是从 PHP 服务器【英文标题】:Google Maps geocoding working from browser but not from PHP server 【发布时间】: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 可以利用我的职位来展示不错的结果吗?

【问题讨论】:

你确定它有效吗?我的结果为零。 在您的浏览器中?它现在对我有用。 请求的结果为零。只需在浏览器或 curl 上单击您的链接。 imgur.com/a/cBDyj s27.postimg.org/74qb232yb/Capture.png :( 【参考方案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 介于​​一小部分之间,我没有重复他的回答......希望可以理解......

以上是关于谷歌地图地理编码从浏览器工作,但不是从 PHP 服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何从谷歌地图地理编码返回地址类型?

如何解析谷歌地图地理编码结果

如何使用谷歌地图 api 将邮政编码转换为地理位置(纬度和经度)?

如何将 php 数组从 mysql 返回到谷歌地理位置

如何从异步 php db 搜索向地理编码器发送地址

谷歌地理编码 API 不如使用地址的谷歌地图准确