使用PHP从Google地图获取路线纬度和经度

时间:2018-09-03 11:32:35

标签: php google-maps

我想列出行程的纬度和经度。可能是所有点,也可能是1-2公里内的所有点。

我想做的是:用户选择A作为起点,选择B作为终点。我想在地图上显示A和B之间的道路附近的一些地方。但是我需要一个职位。

例如,here共享一个JavaScript代码,据说可以使用DirectionsResult Object来完成。

var request = {
  origin: start_point,
  destination: end_point,
  travelMode: google.maps.TravelMode.DRIVING
};

var directionsService = new google.maps.DirectionsService();
  directionsService.route(request, function(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    var path = (response.routes[0].overview_path);
  }
});

但是我正在尝试使用php来做到这一点,而我必须使用php来做到这一点。

我阅读了Google Map API。我还阅读了yandex map api,但这似乎只能通过javascript完成。

有人知道用php做到这一点的方法吗?

1 个答案:

答案 0 :(得分:1)

从注释中我理解问题是要找到(使用PHP),可以从 google中的折线点提取的中间经纬度对方向查询。

这有点不寻常,因为人们通常在浏览器中使用折线点进行地图绘制,因此JavaScript库已经很好地完成了此任务。但是,在PHP中并非如此。

点数据以ASCII字符字符串的形式显示在JSON结果对象中,有时很长,并且始终“不可读”。在该字符串中编码了每条腿的起点和终点之间的中间经度对列表。编码方法已在Google网站https://developers.google.com/maps/documentation/utilities/polylinealgorithm上提供,下面的算法只是该方法的逆转,并对此进行了评论。

该示例显示了在澳大利亚珀斯的月牙形街道上2个点之间找到的路线。选择起点到终点是为了鼓励绘制路线时需要多个中间点。根据需要替换您自己的搜索。

请注意,JSON还在每个结果对象的末尾提供了这些字段。

     "overview_polyline" : {
        "points" : "~n{aEmbwaU_B@cCBk@Lo@d@UVOb@Mh@Ab@@@@BBF@DGNABD`@Fh@Pb@VZn@b@d@J"
     },

这要少得多,也不太准确(如果您绘制的地图可能会偏离地图上的实际道路线),但是也可以用相同的方式进行解码。

但是,最好的中间点是通过使用以下步骤来迭代步骤:

    "polyline" : {
        "points" : "~n{aEmbwaUg@@w@?{A?g@BUBUHSJ[XUVOb@Mh@Ab@"
     }, 

最后,可以在http://unitstep.net/blog/2008/08/02/decoding-google-maps-encoded-polylines-using-php/处找到该算法的原始源。因此,感谢Peter Chng在2008年所做的这项工作! Peter还感谢Mark MClure,他是用JavaScript进行原始编码的。我与hack在一起并添加了更多评论-与Google食谱更加一致,但仅此而已。

我还刚刚意识到,有一个链接https://github.com/emcconville/google-map-polyline-encoding-tool(我认为但尚未测试)提供了一个类和CLI工具来完成两种转换。

$json = file_get_contents("https://maps.googleapis.com/maps/api/directions/json?origin=20%20%20Kintyre%20Crescent,%20Churchlands&destination=%2018Kinross%20Crescent,%20Churchlands&key="); 
$details = json_decode($json,true);
print_r($details);    // show the full result

$points = $details['routes'][0]['legs'][0]['steps'][0]['polyline']['points'];
echo($points);        // show the points string for one leg

// show the start and end locations for that leg
print_r($details['routes'][0]['legs'][0]['steps'][0]['start_location']);
print_r($details['routes'][0]['legs'][0]['steps'][0]['end_location']);

// work out the intermdiate points (normally used for drawing)
$decodedPoints= decodePolylinePoints($points);
print_r($decodedPoints);   // print out the intermediate points

// This function decodes the polylone points in PHP
function decodePolylinePoints($pointsString)
{
    $len = strlen($pointsString);
    $latLons = array();   // the output array
    $lat = 0;             // temp storage for lat and lng
    $lng = 0;

    $index = 0;           // index to curent character
    while ($index < $len)   // process each lat,lng pair
      {
        // first build the lat
        // NOTE: first lat is an absolute value
        // NOTE: subsequent lats are offsets from previous values for coding efficiency
        $char = 0;   // char as read from points string
        $shift = 0;  // cumulative shift amount
        $value = 0;  // temp value during computation

        do // Read, convert and shift 5 bit chunks until terminator is reached to get lat
        {
          $char = ord(substr($pointsString, $index++)) - 63; // return ascii value less 63
          $value |= ($char & 0x1f) << $shift;                // convert to 5 bit and shift left
          $shift += 5;                                       // next shift is 5 extra
        }
        while ($char >= 0x20);                               // value of 20 indicates end of lat

        $lat += (($value & 1) ? ~($value >> 1) : ($value >> 1));  // convert negative values and save

        // now build the lng
        // NOTE: first lng is an absolute value
        // NOTE: subsequent lngs are offsets from previous values for coding efficiency
        $shift = 0;
        $value = 0;

        do  // build up lng from 5 bit chunks
        {
          $char= ord(substr($pointsString, $index++)) - 63;  // return ascii value less 63
          $value |= ($char & 0x1f) << $shift;               // convert to 5 bit and shift left
          $shift += 5;                                       // next shift is 5 extra
        }
        while ($char >= 0x20);                               // value of 20 indicates end of lng

        $lng += (($value & 1) ? ~($value >> 1) : ($value >> 1)); // convert negative values and save

        $latLons[] = array($lat * 1e-5, $lng * 1e-5);        // original values were * 1e5
      }

      return $latLons;    // points array converted to lat,lngs 
}