//----------------------------------------------------------------------- // // Copyright (c) 2016 Mapbox. All rights reserved. // //----------------------------------------------------------------------- namespace Mapbox.Utils { using System; using System.Collections.Generic; using System.Text; /// /// A set of Polyline utils. /// public static class PolylineUtils { /// Decodes an encoded path string into a sequence of Positions. /// /// Adapted from /// /// A string representing a path. /// Level of precision. OSRMv4 uses 6, OSRMv5 and Google use 5. /// List of making up the line. public static List Decode(string encodedPath, int precision = 5) { int len = encodedPath.Length; double factor = Math.Pow(10, precision); // For speed we preallocate to an upper bound on the final length, then // truncate the array before returning. var path = new List(); int index = 0; int lat = 0; int lng = 0; while (index < len) { int result = 1; int shift = 0; int b; do { b = encodedPath[index++] - 63 - 1; result += b << shift; shift += 5; } while (b >= 0x1f); lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1); result = 1; shift = 0; do { b = encodedPath[index++] - 63 - 1; result += b << shift; shift += 5; } while (b >= 0x1f); lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1); path.Add(new Vector2d(y: lng / factor, x: lat / factor)); } return path; } /// /// Encodes a sequence of Positions into an encoded path string. /// /// /// Adapted from /// /// List of making up the line. /// Level of precision. OSRMv4 uses 6, OSRMv5 and Google use 5.. /// A string representing a polyLine. public static string Encode(List path, int precision = 5) { long lastLat = 0; long lastLng = 0; var result = new StringBuilder(); double factor = Math.Pow(10, precision); foreach (Vector2d point in path) { var lat = (long)Math.Round(point.x * factor); var lng = (long)Math.Round(point.y * factor); Encode(lat - lastLat, result); Encode(lng - lastLng, result); lastLat = lat; lastLng = lng; } return result.ToString(); } /// /// Encode the latitude or longitude. /// /// The value to encode. /// String representation of latitude or longitude. private static void Encode(long variable, StringBuilder result) { variable = variable < 0 ? ~(variable << 1) : variable << 1; while (variable >= 0x20) { result.Append((char)((int)((0x20 | (variable & 0x1f)) + 63))); variable >>= 5; } result.Append((char)((int)(variable + 63))); } } }