Permalink
Browse files

Added GooglePolylineEncoder. Closes #1

  • Loading branch information...
sibartlett committed Mar 13, 2013
1 parent af24f1a commit 7134ce1e0f46f70850716edc4542660ca04c412f
@@ -76,6 +76,7 @@
<Compile Include="Geo\Gps\Serialization\PocketFmsFlightplanDeSerializerTests.cs" />
<Compile Include="Geo\Gps\Serialization\SerializerTestFixtureBase.cs" />
<Compile Include="Geo\Gps\Serialization\SkyDemonFlightplanDeSerializerTests.cs" />
+ <Compile Include="Geo\IO\Google\GooglePolylineEncoderTests.cs" />
<Compile Include="Geo\IO\Wkb\WkbTests.cs" />
<Compile Include="Geo\IO\Wkt\WktWriterTests.cs" />
<Compile Include="Geo\IO\Wkt\WktReaderTests.cs" />
@@ -0,0 +1,33 @@
+using Geo.Geometries;
+using Geo.IO.Google;
+using NUnit.Framework;
+
+namespace Geo.Tests.Geo.IO.Google
+{
+ public class GooglePolylineEncoderTests
+ {
+ [Test]
+ public void Encode()
+ {
+ var lineString = new LineString(new Coordinate(38.5, -120.2),
+ new Coordinate(40.7, -120.95),
+ new Coordinate(43.252, -126.453));
+
+ var result = new GooglePolylineEncoder().Encode(lineString);
+
+ Assert.AreEqual("_p~iF~ps|U_ulLnnqC_mqNvxq`@", result);
+ }
+
+ [Test]
+ public void Decode()
+ {
+ var lineString = new LineString(new Coordinate(38.5, -120.2),
+ new Coordinate(40.7, -120.95),
+ new Coordinate(43.252, -126.453));
+
+ var result = new GooglePolylineEncoder().Decode("_p~iF~ps|U_ulLnnqC_mqNvxq`@");
+
+ Assert.AreEqual(lineString, result);
+ }
+ }
+}
View
@@ -57,6 +57,7 @@
<Compile Include="CoordinateZ.cs" />
<Compile Include="CoordinateZM.cs" />
<Compile Include="Geodesy\GeodeticCalculations.cs" />
+ <Compile Include="IO\Google\GooglePolylineEncoder.cs" />
<Compile Include="IO\Spatial4n\Spatial4nReader.cs" />
<Compile Include="IO\Spatial4n\Spatial4nWriter.cs" />
<Compile Include="IO\Wkb\WkbBinaryReader.cs" />
@@ -0,0 +1,90 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Geo.Geometries;
+
+namespace Geo.IO.Google
+{
+ public class GooglePolylineEncoder
+ {
+ // Attributions:
+ // https://developers.google.com/maps/documentation/utilities/polylinealgorithm
+ // http://geographyservices.codeplex.com
@PureKrome

PureKrome Mar 14, 2013

I'm famous! ✌️🐲 🎉🎉🎁

@sibartlett

sibartlett Mar 15, 2013

Owner

@PureKrome I hope you approve. Your polyline encoder was a useful resource to refer to, and I really appreciate it! 😃

@PureKrome

PureKrome via email Mar 15, 2013

+ // http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
+
+ private const double CoordinateFactor = 1e5;
+ private const int BinaryChunkSize = 5;
+ private const int MinAscii = 63;
+
+ public string Encode(LineString lineString)
+ {
+ var plat = 0;
+ var plng = 0;
+
+ var builder = new StringBuilder();
+
+ foreach (var coordinate in lineString.Coordinates)
+ {
+ var late5 = (int)(coordinate.Latitude * CoordinateFactor);
+ var lnge5 = (int)(coordinate.Longitude * CoordinateFactor);
+
+ EncodeNumber(builder, late5 - plat);
+ EncodeNumber(builder, lnge5 - plng);
+
+ plat = late5;
+ plng = lnge5;
+ }
+
+ return builder.ToString();
+ }
+
+ public LineString Decode(string polyline)
+ {
+ var reader = new StringReader(polyline);
+ var coordinates = new List<Coordinate>();
+ int lat = 0, lng = 0;
+
+ while (reader.Peek() != -1)
+ {
+ lat += DecodeNumber(reader);
+ lng += DecodeNumber(reader);
+
+ var p = new Coordinate(lat / CoordinateFactor, lng / CoordinateFactor);
+ coordinates.Add(p);
+ }
+
+ return new LineString(coordinates);
+ }
+
+ private static void EncodeNumber(StringBuilder builder, int num)
+ {
+ num = num << 1;
+
+ if (num < 0)
+ num = ~num;
+
+ while (num >= 0x20)
+ {
+ builder.Append((char)((0x20 | (num & 0x1f)) + MinAscii));
+ num >>= BinaryChunkSize;
+ }
+
+ builder.Append((char)(num + MinAscii));
+ }
+
+ private static int DecodeNumber(StringReader reader)
+ {
+
+ int b, shift = 0, result = 0;
+ do
+ {
+ b = reader.Read() - MinAscii;
+ result |= (b & 0x1f) << shift;
+ shift += BinaryChunkSize;
+ }
+ while (b >= 0x20);
+
+ return (result & 1) != 0 ? ~(result >> 1) : result >> 1;
+ }
+ }
+}

0 comments on commit 7134ce1

Please sign in to comment.