diff options
-rw-r--r-- | api/src/php/mwm_api.php | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/api/src/php/mwm_api.php b/api/src/php/mwm_api.php new file mode 100644 index 0000000000..085d4e2adf --- /dev/null +++ b/api/src/php/mwm_api.php @@ -0,0 +1,106 @@ +<?php + +// @TODO add tests + +// Returns array(lat, lon, zoom) or empty array in the case of error +function DecodeGe0LatLonZoom($latLonZoom) +{ + $MAPSWITHME_MAX_POINT_BYTES = 10; + $MAPSWITHME_MAX_COORD_BITS = $MAPSWITHME_MAX_POINT_BYTES * 3; + + $FAILED = array(); + + $base64ReverseArray = GetBase64ReverseArray(); + + $zoom = $base64ReverseArray[ord($latLonZoom[0])]; + if ($zoom > 63) + return $FAILED; + $zoom = $zoom / 4. + 4.; + + $latLonStr = substr($latLonZoom, 1); + $latLonBytes = strlen($latLonStr); + $lat = 0; + $lon = 0; + for($i = 0, $shift = $MAPSWITHME_MAX_COORD_BITS - 3; $i < $latLonBytes; $i++, $shift -= 3) + { + $a = $base64ReverseArray[ord($latLonStr[$i])]; + $lat1 = ((($a >> 5) & 1) << 2 | + (($a >> 3) & 1) << 1 | + (($a >> 1) & 1)); + $lon1 = ((($a >> 4) & 1) << 2 | + (($a >> 2) & 1) << 1 | + ($a & 1)); + $lat |= $lat1 << $shift; + $lon |= $lon1 << $shift; + } + + $middleOfSquare = 1 << (3 * ($MAPSWITHME_MAX_POINT_BYTES - $latLonBytes) - 1); + $lat += $middleOfSquare; + $lon += $middleOfSquare; + + $lat = round($lat / ((1 << $MAPSWITHME_MAX_COORD_BITS) - 1) * 180.0 - 90.0, 5); + $lon = round($lon / (1 << $MAPSWITHME_MAX_COORD_BITS) * 360.0 - 180.0, 5); + + if ($lat <= -90.0 || $lat >= 90.0) + return $FAILED; + if ($lon <= -180.0 || $lon >= 180.0) + return $FAILED; + + return array($lat, $lon, $zoom); +} + +// Returns decoded name +function DecodeGe0Name($name) +{ + return str_replace('_', ' ', rawurldecode($name)); +} + +// Returns empty array in the case of error. +// In the good case, returns array(lat, lon, zoom) or array(lat, lon, zoom, name) +function DecodeGe0Url($url) +{ + $MAPSWITHME_ZOOM_POSITION = 6; + $NAME_POSITON_IN_URL = 17; + + $FAILED = array(); + if (strlen($url) < 16 || strpos($url, "ge0://") != 0) + return $FAILED; + + $base64ReverseArray = GetBase64ReverseArray(); + + $latLonZoom = DecodeGe0LatLonZoom(substr($url, 6, 10)); + if (empty($latLonZoom)) + return $FAILED; + + if (strlen($url) < $NAME_POSITON_IN_URL) + return $latLonZoom; + + $name = DecodeGe0Name(substr($url, $NAME_POSITON_IN_URL)); + array_push($latLonZoom, $name); + return $latLonZoom; +} + +// Internal helper function +function GetBase64ReverseArray() +{ + static $base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + $base64ReverseArray = array(); + // fill array with 255's + array_pad($base64ReverseArray, 256, 255); + + for ($i = 0; $i < 64; $i++) + { + $c = $base64Alphabet[$i]; + $base64ReverseArray[ord($c)] = $i; + } + return $base64ReverseArray; +} + + +////////////////////////////////////// +// Tests are below +//print_r(DecodeGe0Url("ge0://B4srhdHVVt/Some_Name")); +//print_r(DecodeGe0Url("ge0://AwAAAAAAAA/%d0%9c%d0%b8%d0%bd%d1%81%d0%ba_%d1%83%d0%bb._%d0%9b%d0%b5%d0%bd%d0%b8%d0%bd%d0%b0_9")); + +?> + |