首页 > 解决方案 > 使用 PHP 从谷歌地图获取行程纬度和经度

问题描述

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

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

例如,这里共享了一段 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 来做这件事。

我读了谷歌地图 api。我还阅读了 yandex 地图 api,但这似乎只能使用 javascript 完成。

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

标签: phpgoogle-maps

解决方案


从评论中我了解到问题是找到(使用 PHP)可以从谷歌方向查询中的折线点中提取的中间纬度、经度对。

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

点数据在 JSON 结果对象中显示为 ascii 字符串,有时很长并且总是“不可读”。在此字符串中编码了每条腿的开始和结束之间的中间 lat lng 对列表。编码方法在 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 进行了原始编码。我修改并添加了更多评论 - 与谷歌食谱更加一致,但仅此而已。

我也刚刚意识到有这个链接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 
}

推荐阅读