You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
mapbox-sdk/Core/mapbox-sdk-cs/Utils/PolylineUtils.cs

119 lines
3.5 KiB

//-----------------------------------------------------------------------
// <copyright file="PolylineUtils.cs" company="Mapbox">
// Copyright (c) 2016 Mapbox. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace Mapbox.Utils
{
using System;
using System.Collections.Generic;
using System.Text;
/// <summary>
/// A set of Polyline utils.
/// </summary>
public static class PolylineUtils
{
/// <summary>Decodes an encoded path string into a sequence of Positions.</summary>
/// <remarks>
/// Adapted from <see href="https://github.com/mapbox/mapbox-java/blob/9bda93a2f84e26ad67434de1a5c73c335ecac12c/libjava/lib/src/main/java/com/mapbox/services/commons/utils/PolylineUtils.java"/>
/// </remarks>
/// <param name="encodedPath">A string representing a path.</param>
/// <param name="precision">Level of precision. OSRMv4 uses 6, OSRMv5 and Google use 5.</param>
/// <returns>List of <see cref="Vector2d"/> making up the line.</returns>
public static List<Vector2d> 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<Vector2d>();
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;
}
/// <summary>
/// Encodes a sequence of Positions into an encoded path string.
/// </summary>
/// <remarks>
/// Adapted from <see href="https://github.com/mapbox/mapbox-java/blob/9bda93a2f84e26ad67434de1a5c73c335ecac12c/libjava/lib/src/main/java/com/mapbox/services/commons/utils/PolylineUtils.java"/>
/// </remarks>
/// <param name="path">List of <see cref="Vector2d"/> making up the line.</param>
/// <param name="precision">Level of precision. OSRMv4 uses 6, OSRMv5 and Google use 5..</param>
/// <returns>A string representing a polyLine.</returns>
public static string Encode(List<Vector2d> 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();
}
/// <summary>
/// Encode the latitude or longitude.
/// </summary>
/// <param name="variable">The value to encode.</param>
/// <param name="result">String representation of latitude or longitude.</param>
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)));
}
}
}