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 から返された緯度経度値にデコードしたいと考えています。

Java と Objective C でいくつかの結果を見つけましたが、PHP で必要です。

4

4 に答える 4

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 に答える