3

我有来自以下 URL 的 json 响应:

http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los%20Angeles,CA&sensor=false

JSON路径routes[x].legs[y].steps[z].polyline.points

"azq~Fhc{uOAlB?jB?^?P?P?B@V@|J@fA?xA@xA?h@?B?F?@?tA@xD?h@BnA@|A@rB@ f@?d@@v@AxB?d@AZEzA?BIjB?@Cx@?@EzAAlC?F?F?T?B?f@DhHBhD?@?R?l@?R?|CCpDAj@E|DGnDKzCCb @OtBa@rFGfAAb@?@?FAp@? ADbJD|F@bF@@@fERhd@BrEFdDBtBAvBAx@@l@?n@@^@bANnQ?rABnM?jC?hH@fA?@BF?vC?hB?@BpM?@?j@@p@@|KB~Q@pFBbHBvF@z@?f@@jB?nA@z@DzD@VJ ~CLfC\|E?B?@HnANtAVpDRpCLbB^dFTxC@LZvDF^HrALLlCH EB|H?DBpEB~V?^BhDJR?@@\?~A?nABrL?@?jD@vD@vA?h@?BLx[?x@?B?\?F@ pA?h@D~H?@Bz@Dr@RbCLfA\rBPv@@@T~@t@bCPf@z@xBd@rAf@dB\zAN~@PjAT~BFrADxAH X?z@?@HfW?x@?F?@@dD@^F|Y@v@D|JBzH?rB@tAApABxB?bA@dBBxABlAJ~CJrBDfANhBNjCLlCLpBHlBFnB@C?|A?v@AlBCdA?r @EjEC|BItemdGEtAIfEI|BKzDOzGEjCCl@?@MnDW HSrFSlFAd@?@qA|[Ct@Cj@At@AbA?hBAdBClBQjFQnECr@EAYjFIzAWxDQpCYpEAFItACt@S~C]|GSlEMnCMtCGdAKlBQxDg@bLAT?BKrCAn@Ad@?x@?p@?J?|@@lA@z@BbABn@Bt@@ @HnAPxB@LB^LAT BPAP~@ Z~ALn@?@@Fd@|BjAfGd@dDd@|D\bFDf@D~@@f@B|@@xCJ P?dBBEDtE@bADlAR EJlABh@Dp@F@ @xEJdBHlCF~C@nA?@?@DfG?ADhLBbD@x@?F@~C?dCNbTDrIBxDLbO@~AV Y?@DfHEvDGlC]fHGhD?lHPlP?@?B?R?@BfBNbRBpENfQDrGBvCDrEBtEBzABfABx@B~@^FHx@ H|@ @bDPxAZpCTbDNDBlC@j@@j@BhAHhLBvC?p@BlB?jAAfAAx@C@MzDM|B_@tDq@pF]fB]zAo@fCc@~Am@jBo@dBoCxG?@?@Sd@g@vAY~@St@W|@_@bBUhA_@zBWhBKAOpAKfAEp@Gz@Cb@GpACZAVAh@Ad@AX?f@At@CpB"

我想使用 PHP 将折线点字符串解码为上述 URL 返回的 lat long 值。

我在 Java 和 Objective C 中找到了一些结果,但我在 PHP 中需要它。

4

4 回答 4

12

Python 实现

这不在 PHP 中,但如果您要从 Google 地图中解码折线字符串,则此线程位于搜索结果的顶部附近。如果其他人需要它(就像我一样),这里有一个用于解码折线字符串的 Python 实现。这是从 Mapbox JavaScript 版本移植过来的;在我的回购页面上找到更多信息。

def decode_polyline(polyline_str):
    index, lat, lng = 0, 0, 0
    coordinates = []
    changes = {'latitude': 0, 'longitude': 0}

    # Coordinates have variable length when encoded, so just keep
    # track of whether we've hit the end of the string. In each
    # while loop iteration, a single coordinate is decoded.
    while index < len(polyline_str):
        # Gather lat/lon changes, store them in a dictionary to apply them later
        for unit in ['latitude', 'longitude']: 
            shift, result = 0, 0

            while True:
                byte = ord(polyline_str[index]) - 63
                index+=1
                result |= (byte & 0x1f) << shift
                shift += 5
                if not byte >= 0x20:
                    break

            if (result & 1):
                changes[unit] = ~(result >> 1)
            else:
                changes[unit] = (result >> 1)

        lat += changes['latitude']
        lng += changes['longitude']

        coordinates.append((lat / 100000.0, lng / 100000.0))

    return coordinates
于 2015-11-06T00:45:35.350 回答
6

你可以在 Github 上查看这个 repo:Google Maps Polyline Encoding Tool

一个简单的 PHP 类,用于将折线转换为谷歌地图的编码字符串。

于 2013-03-13T09:38:06.640 回答
3
<?php

# Do steps 1-11 given here 
# https://developers.google.com/maps/documentation/utilities/polylinealgorithm
# in reverse order and inverted (i.e. left shift -> right shift, add -> subtract)

$string = "udgiEctkwIldeRe}|x@cfmXq|flA`nrvApihC";
# Step 11) unpack the string as unsigned char 'C'
$byte_array = array_merge(unpack('C*', $string));
$results = array();

$index = 0; # tracks which char in $byte_array
do {
  $shift = 0;
  $result = 0;
  do {
    $char = $byte_array[$index] - 63; # Step 10
    # Steps 9-5
    # get the least significat 5 bits from the byte
    # and bitwise-or it into the result
    $result |= ($char & 0x1F) << (5 * $shift);
    $shift++; $index++;
  } while ($char >= 0x20); # Step 8 most significant bit in each six bit chunk
    # is set to 1 if there is a chunk after it and zero if it's the last one
    # so if char is less than 0x20 (0b100000), then it is the last chunk in that num

  # Step 3-5) sign will be stored in least significant bit, if it's one, then 
  # the original value was negated per step 5, so negate again
  if ($result & 1)
    $result = ~$result;
  # Step 4-1) shift off the sign bit by right-shifting and multiply by 1E-5
  $result = ($result >> 1) * 0.00001;
  $results[] = $result;
} while ($index < count($byte_array));

# to save space, lat/lons are deltas from the one that preceded them, so we need to 
# adjust all the lat/lon pairs after the first pair
for ($i = 2; $i < count($results); $i++) {
  $results[$i] += $results[$i - 2];
}

# chunk the array into pairs of lat/lon values
var_dump(array_chunk($results, 2));

# Test correctness by using Google's polylineutility here:
# https://developers.google.com/maps/documentation/utilities/polylineutility

?>
于 2014-07-10T15:37:33.273 回答
0

解决这个问题的最简单的方法..

这是Github 存储库的链接,其中包括编码/解码类。它还具有最简单的使用说明。

注意:我必须稍微更改类以解码函数 decodeValue 中的折线,这是 while 循环中的最后一行。我不得不用 1000000 替换 100000

$points[] = array('x' => $lat/1000000, 'y' => $lng/1000000);
于 2018-02-16T08:44:26.743 回答