Skip to content

Instantly share code, notes, and snippets.

@pictos
Created November 23, 2017 15:10
Show Gist options
  • Save pictos/85c16796665cefee7a9d2a4a6ab009d5 to your computer and use it in GitHub Desktop.
Save pictos/85c16796665cefee7a9d2a4a6ab009d5 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms.Maps;
namespace RouteMap.Model
{
public class GooglePoints
{
public static IEnumerable<Position> Decode(string encodedPoints)
{
if (string.IsNullOrEmpty(encodedPoints))
throw new ArgumentNullException("encodedPoints");
char[] polylineChars = encodedPoints.ToCharArray();
int index = 0;
int currentLat = 0;
int currentLng = 0;
int next5bits;
int sum;
int shifter;
while (index < polylineChars.Length)
{
// calculate next latitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylineChars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylineChars.Length);
if (index >= polylineChars.Length)
break;
currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
//calculate next longitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylineChars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylineChars.Length);
if (index >= polylineChars.Length && next5bits >= 32)
break;
currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
yield return new Position(Convert.ToDouble(currentLat) / 1E5, Convert.ToDouble(currentLng) / 1E5);
}
}
public static string Encode(IEnumerable<Position> points)
{
var str = new StringBuilder();
var encodeDiff = (Action<int>)(diff =>
{
int shifted = diff << 1;
if (diff < 0)
shifted = ~shifted;
int rem = shifted;
while (rem >= 0x20)
{
str.Append((char)((0x20 | (rem & 0x1f)) + 63));
rem >>= 5;
}
str.Append((char)(rem + 63));
});
int lastLat = 0;
int lastLng = 0;
foreach (var point in points)
{
int lat = (int)Math.Round(point.Latitude * 1E5);
int lng = (int)Math.Round(point.Longitude * 1E5);
encodeDiff(lat - lastLat);
encodeDiff(lng - lastLng);
lastLat = lat;
lastLng = lng;
}
return str.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment