//-----------------------------------------------------------------------
//
// 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)));
}
}
}