Skip to content

Instantly share code, notes, and snippets.

@ismailbaskin
Created February 18, 2017 14:12
Show Gist options
  • Save ismailbaskin/0f44e318df04796e7c46e2308dd99da4 to your computer and use it in GitHub Desktop.
Save ismailbaskin/0f44e318df04796e7c46e2308dd99da4 to your computer and use it in GitHub Desktop.
<?php
class PolylineEncoder
{
public static function decode(string $value, int $precise = 5): array
{
$index = 0;
$points = [];
$lat = 0;
$lng = 0;
while ($index < strlen($value)) {
$b = null;
$shift = 0;
$result = 0;
do {
$b = ord(substr($value, $index++, 1)) - 63;
$result |= ($b & 0x1f) << $shift;
$shift += 5;
} while ($b > 31);
$dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1));
$lat += $dlat;
$shift = 0;
$result = 0;
do {
$b = ord(substr($value, $index++, 1)) - 63;
$result |= ($b & 0x1f) << $shift;
$shift += 5;
} while ($b > 31);
$dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1));
$lng += $dlng;
$points[] = ['x' => $lat / 10 ** $precise, 'y' => $lng / 10 ** $precise];
}
return $points;
}
public static function encode(array $points, int $precise = 5): string
{
$encoder = function ($value) use ($precise) {
$encoded = '';
$value = round($value * 10 ** $precise);
$r = ($value < 0) ? ~($value << 1) : ($value << 1);
while ($r >= 0x20) {
$val = (0x20 | ($r & 0x1f)) + 63;
$encoded .= chr($val);
$r >>= 5;
}
$encoded .= chr($r + 63);
return $encoded;
};
$encoded = '';
for ($i = 0; $i < count($points); $i++) {
$x = ($i === 0) ? $points[$i]['x'] : ($points[$i]['x'] - $points[$i - 1]['x']);
$y = ($i === 0) ? $points[$i]['y'] : ($points[$i]['y'] - $points[$i - 1]['y']);
$encoded .= $encoder($x).$encoder($y);
}
return $encoded;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment