Google 地图缩短了街道名称和地址,导致代码不可靠
Google Maps shortened street names and addresses causing for unreliable code
PHP 版本 7.4
我目前正在开发一个小的 php 程序来接收某些货物并将它们的顺序优化到最有效的路线。到目前为止一切顺利,它可以通过以下方式与 google 地图 api 一起使用:
$url = "https://maps.googleapis.com/maps/api/directions/json?";
$url .= "origin=".urlencode($this->startPoint);
$url .= "&destination=".urlencode($this->endPoint);
$url .= "&waypoints=".urlencode("optimize:true")."|";
$x = 0;
foreach($ordersadress as $order){
if($x != 0){
$url .= urlencode("|");
}
$url .= urlencode($order["address"]);
$x++;
}
$url .= "&key=".$conf->global->GOOGLE_MAPS_API_KEY;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$json = json_decode($resp);
现在,为了知道实际上哪个货件先到,我查看 json 响应并将我的货件地址与响应中的每个航路点进行比较,以查看哪个地址先到等等。
这是我的问题,在响应中地址没有写出来,它们被缩短了。例如,对于德国地址,我添加到 api 电话的发货地址是“Kirchenplatz 4”。在 google 的回复中,他们将其缩短为“Kirchenpl.4”。
我认为英语中的等效词是将“Road”更改为“Rd”。
(我会在最后放一个示例请求,如果你不知道它是什么样子,你确实需要一个 Google API 键。)
现在,我按以下方式进行:
foreach($json->routes[0]->legs as $leg){
if($iterator != 0){
foreach($ordersadress as $order){
$addy = explode(",", $leg->start_address);
$oa = explode(",", $order["address"]);
//Here I compare if the returned address is the same as the one on the shipment, needs to be a 1:1 match, this is my issue
if(strpos($oa[0], $addy[0]) !== false){
$lat = $leg->start_location->lat;
$lon = $leg->start_location->lng;
$co = $order["object"];
$this->orders[] = ["rowid" => $co->id, "sortorder" => $sortnum, "notes" => "", "tourdate" => $tourdate->format("d.m.Y"), "address" => $leg->start_address, "drivetime" => $leg->duration->value, "object" => $co, "lat" => $lat, "lon" => $lon];
$this->kmAll += round($leg->distance->value/1000, 2);
$sortnum++;
foreach($leg->steps as $step){
$polyline .= $step->polyline->points;
}
break;
}
}
unset($order);
}
此示例仅适用于完全 1:1 匹配,这在现实世界中当然不可行,因为我客户的工作人员无法始终以完全相同的方式输入地址googlereturns另外,已经有几千个货件的数据需要修改了。
我想到了以下解决方案:
获取所有被 google 缩短的单词的列表,然后对我的地址执行此操作。但是我找不到列表。
我的第二个解决方案是对 2 个地址进行百分比匹配,匹配度最高的地址将位于 google 返回的位置。有了这个解决方案,老实说,我并没有真正理解 similar_text
函数及其工作原理,我不确定它是否对我来说是一个好的解决方案。
我乐于接受您的任何想法和建议。
示例Google API请求:
https://maps.googleapis.com/maps/api/directions/json?origin=Lange+G.+20%2C+2700+Wiener+Neustadt&destination=Ruckergasse+42%2C+1120+Wien&waypoints=optimize%3Atrue|Brauhausgasse+6%7CHauptpl.+1%2C+Graz%7CKirchenpl.+4%2C+G%C3%A4nserndorf%7CS%C3%BCdtiroler+Pl.+1%2C+Salzburg%7CUnter+dem+Rucker+14%7CVivenotgasse+3%2F6+13%2C+Wien&key=YOUR_API_KEY
在尝试了一段时间并询问了一些朋友之后,我得出了使用 fuzzy logic to match addresses 的解决方案。幸运的是,已经有这种逻辑方法的实现,称为 levenshtein($string1, $string2)
我建议在这里阅读它:https://www.php.net/manual/de/function.levenshtein.php
示例 1 基本上是我对问题的解决方案,到目前为止一直没有问题。
但是要小心!正如示例 1 下面的评论中所解释的 here 使用 UTF-8 会导致问题!
PHP 版本 7.4
我目前正在开发一个小的 php 程序来接收某些货物并将它们的顺序优化到最有效的路线。到目前为止一切顺利,它可以通过以下方式与 google 地图 api 一起使用:
$url = "https://maps.googleapis.com/maps/api/directions/json?";
$url .= "origin=".urlencode($this->startPoint);
$url .= "&destination=".urlencode($this->endPoint);
$url .= "&waypoints=".urlencode("optimize:true")."|";
$x = 0;
foreach($ordersadress as $order){
if($x != 0){
$url .= urlencode("|");
}
$url .= urlencode($order["address"]);
$x++;
}
$url .= "&key=".$conf->global->GOOGLE_MAPS_API_KEY;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$json = json_decode($resp);
现在,为了知道实际上哪个货件先到,我查看 json 响应并将我的货件地址与响应中的每个航路点进行比较,以查看哪个地址先到等等。 这是我的问题,在响应中地址没有写出来,它们被缩短了。例如,对于德国地址,我添加到 api 电话的发货地址是“Kirchenplatz 4”。在 google 的回复中,他们将其缩短为“Kirchenpl.4”。 我认为英语中的等效词是将“Road”更改为“Rd”。 (我会在最后放一个示例请求,如果你不知道它是什么样子,你确实需要一个 Google API 键。)
现在,我按以下方式进行:
foreach($json->routes[0]->legs as $leg){
if($iterator != 0){
foreach($ordersadress as $order){
$addy = explode(",", $leg->start_address);
$oa = explode(",", $order["address"]);
//Here I compare if the returned address is the same as the one on the shipment, needs to be a 1:1 match, this is my issue
if(strpos($oa[0], $addy[0]) !== false){
$lat = $leg->start_location->lat;
$lon = $leg->start_location->lng;
$co = $order["object"];
$this->orders[] = ["rowid" => $co->id, "sortorder" => $sortnum, "notes" => "", "tourdate" => $tourdate->format("d.m.Y"), "address" => $leg->start_address, "drivetime" => $leg->duration->value, "object" => $co, "lat" => $lat, "lon" => $lon];
$this->kmAll += round($leg->distance->value/1000, 2);
$sortnum++;
foreach($leg->steps as $step){
$polyline .= $step->polyline->points;
}
break;
}
}
unset($order);
}
此示例仅适用于完全 1:1 匹配,这在现实世界中当然不可行,因为我客户的工作人员无法始终以完全相同的方式输入地址googlereturns另外,已经有几千个货件的数据需要修改了。
我想到了以下解决方案:
获取所有被 google 缩短的单词的列表,然后对我的地址执行此操作。但是我找不到列表。
我的第二个解决方案是对 2 个地址进行百分比匹配,匹配度最高的地址将位于 google 返回的位置。有了这个解决方案,老实说,我并没有真正理解 similar_text
函数及其工作原理,我不确定它是否对我来说是一个好的解决方案。
我乐于接受您的任何想法和建议。
示例Google API请求:
https://maps.googleapis.com/maps/api/directions/json?origin=Lange+G.+20%2C+2700+Wiener+Neustadt&destination=Ruckergasse+42%2C+1120+Wien&waypoints=optimize%3Atrue|Brauhausgasse+6%7CHauptpl.+1%2C+Graz%7CKirchenpl.+4%2C+G%C3%A4nserndorf%7CS%C3%BCdtiroler+Pl.+1%2C+Salzburg%7CUnter+dem+Rucker+14%7CVivenotgasse+3%2F6+13%2C+Wien&key=YOUR_API_KEY
在尝试了一段时间并询问了一些朋友之后,我得出了使用 fuzzy logic to match addresses 的解决方案。幸运的是,已经有这种逻辑方法的实现,称为 levenshtein($string1, $string2)
我建议在这里阅读它:https://www.php.net/manual/de/function.levenshtein.php
示例 1 基本上是我对问题的解决方案,到目前为止一直没有问题。 但是要小心!正如示例 1 下面的评论中所解释的 here 使用 UTF-8 会导致问题!