如何从PHP中的Google Maps Direction API解码折线

问题描述 投票:2回答:4

我从以下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乙@ V□的|??????【J @为fA XA @ XA H +乙˚F@ TA @的xD H + BNA @ |?????甲@ rB中@ ˚F@ @@ d v□的AXB d @ AZEzA BIjB @Cx @ EzAAlC F F T B˚F@ DhHBhD 5 R升5 R |???????????????CCpDAj @ E | DGnDKzCCb @ OtBa @ rFGfAAb @ FAP @ ADbJD|F@bF@@@fERhd@BrEFdDBtBAvBAx@@l@?n@@^@bANnQ?rABnM?jC?hH@fA?@BF VC的hB @BpM @Ĵ@@ p @@ |??????????KB〜Q因子@ pFBbHBvF @ Z @频率@@ jB表示nA的@ Z @ DZD @ VJ 〜CLFC \ |?????????????E B @ HnANtAVpDRpCLbB ^ dFTxC @ LZvDF ^ HrALlCHEB|H?DBpEB~V?^BhDJR @@ \〜甲nABrL @ JD @ VD @ vA型H + BLx的[X @乙\˚F@ pA的6 H @ d〜H +的Bz @ RbCLfA博士\ rBPv @@@ T〜@ T @ bCPf @ Z @ XBD @ RAF @分贝\咱〜@ PjAT〜BFrADxAHX?z@?@HfW?x@?F?@@dD@^F|Y@v@D|JBzH?rB@tAApABxB?bA@dBBxABlAJ~CJrBDfANhBNjCLlCLpBHlBFnB@C |????A v @ AlBCdA R 6 EJEC | BItEMdGEtAIfEI |?BKzDOzGEjCCl @ MnDWHSrFSlFAd@?@qA|[Ct@Cj@At@AbA?hBAdBClBQjFQnECr@EAYjFIzAWxDQpCYpEAFItACt @ S〜C] |?GSlEMnCMtCGdAKlBQxDg @ BLAT BKrCAn @广告@ X @ 2P @Ĵ|????@@ 1A中@ Z @ BbABn @ @@的Bt〜@HnAPxB@LB^LATBPAP @ Z〜ALN @ ?@@ @的Fd | BjAfGd @ DDD @ | d \ BFDF @ d〜@@ @˚FC |?@@ @ xCJP?dBBEDtE @ bADlAREJlABh@Dp@F @ @xEJdBHlCF~C@nA?@?@DfG?ADhLBbD X @频率@〜çdCNbTDrIBxDLbO @〜AVY?@DfHEvDGlC]fHGhD?lHPlP?@?B?R?@BfBNbRBpENfQDrGBvCDrEBtEBzABfABx@B~@^FHx @ H | @ @bDPxAZpCTbDNDBlC @Ĵ @@Ĵ@ BhAHhLBvC 2 p @ BLB?jAAfAAx @ C@MzDM|B_@tDq@pF]fB]zAo@fCc@~Am@jBo@dBoCxG?@?@Sd@g@vAY~@St@W|@_@bBUhA_@zBWhBKAOpAKfAEp @ GZ @ @的Cb @ GpACZAVAh广告@ AX·F @在@的CpB”

我想解码Polyline点字符串以使用PHP来转换上述URL返回的长值。

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

php json directions google-maps-direction-api
4个回答
6
投票

你可以看一下Github上的这个回购:Google Maps Polyline Encoding Tool

一个简单的PHP类,用于将折线转换为Google Maps的编码字符串。


9
投票

Python Implementation

这不是在PHP中,但是如果您要从Google地图解码折线字符串,则此线程接近搜索结果的顶部。如果其他人需要它(就像我做的那样),这里有一个用于解码折线字符串的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
投票
<?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

?>

0
投票

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

这是Github Repo的Link,包括编码/解码类。它还具有最简单的使用说明。

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

$points[] = array('x' => $lat/1000000, 'y' => $lng/1000000);
© www.soinside.com 2019 - 2024. All rights reserved.