谷歌地图地理编码从浏览器工作,但不是从 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®ion=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 服务器的主要内容,如果未能解决你的问题,请参考以下文章