代码之家  ›  专栏  ›  技术社区  ›  Shehzad Bilal

如何在PHP中从谷歌地图方向API解码多段线

  •  4
  • Shehzad Bilal  · 技术社区  · 12 年前

    我有来自以下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@?BF?@?tA@xD?h@BnA@|A@rB@f@?天@@v@AxB?d@AZEzA?BIjB@Cx@@EzAAlC?FFTBf@DhHBhD?@?R我@?R|CCpDAj@E|DGnDKzCCb@OtBa@rFGfAAb@?@?传真@? ADbJD|F@bF@@@fERhd@BrEFdDBtBAvBAx@@l@?n@@^@bANnQ?rABnM?jC?hH@fA?@B FvC?hB@BpM?@?j@@p@@|KB~Q@pFBbHBvF@z@?f@@jB?nA@z@DzD@VJ~CLfC\|E?B@HnANtAVpDRpCLbB型^dFTxC@LZvDF^小时ALlCH EB|H?DBpEB~V?^BhDJ R?@@\~A.北极熊?@?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@@最小干重 HSrFSlFAd@?@qA|[Ct@Cj@At@AbA?hBAdBClBQjFQnECr@E AYjFIzAWxDQpCYpEAFItACt@S~C]|GSlEMnCMtCGdAKlBQxDg@bLAT?BKrCAn@Ad@?x@?p@?J|@@lA@z@BbABn@Bt@@ @HnAPxB@LB^L BP AP~@Z~ALn@@@Fd公司@|BjAfGd@dDd@|天\bFDf@D~@@f@B|@@xCJ公司 P?dBB EDtE@bADlAR EJlABh@Dp@F @ @xEJdBHlCF~C@nA?@?@DfG? ADhLBbD@x@?F@~C?dCNbTDrIBxDLbO@~AV Y?@DfHEvDGlC]fHGhD?lHPlP?@?B?R?@BfBNbRBpENfQDrGBvCDrEBtEBzABfABx@B~@^ FHx@H|@ @bDPxAZpCTbDN DBlC@j@@j@BhAHhLBvC?p@BlB?jAAfAAx@C @MzDM|B_@tDq@pF]fB]zAo@fCc@~Am@jBo@dBoCxG?@?@Sd@g@vAY~@St@W|@_@bBUhA_@zBWhBK AOpAKfAEp@Gz@Cb@GpACZAVAh@Ad@AX?f@At@CpB“

    我想使用PHP将Polyline点字符串解码为以上URL返回的lat-long值。

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

    4 回复  |  直到 7 年前
        1
  •  13
  •   Mike Davlantes    9 年前

    Python实现

    这不在PHP中,但如果你想解码谷歌地图中的折线字符串,这个线程就在搜索结果的顶部附近。如果其他人需要它(和我一样),这里有一个用于解码多段线字符串的Python实现。这是从Mapbox JavaScript版本移植过来的;在我的上找到更多信息 repo page.

    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
    
        2
  •  7
  •   j0k gauthamp    12 年前

    您可以在Github上查看此回购: Google Maps Polyline Encoding Tool

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

        3
  •  3
  •   joshbodily    10 年前
    <?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
    
    ?>
    
        4
  •  0
  •   d_bhatnagar    7 年前

    这个问题最简单的解决办法。。

    这是一个 Link 到Github Repo,其中包括用于编码/解码的类。它也有尽可能简单的用法描述。

    注意: 为了解码while循环中的最后一行,函数decodeValue中的多段线,我不得不稍微更改类。我曾经 将100000替换为1000000

    $points[] = array('x' => $lat/1000000, 'y' => $lng/1000000);