Skip to content

Commit 2f7cd3b

Browse files
author
Petr Sramek
committed
Merge branch 'develop/1.0' of https://github.com/dropoutcoder/polyline-algorithm-csharp into develop/1.0
2 parents b9f9810 + 061714c commit 2f7cd3b

34 files changed

+374
-192
lines changed

benchmarks/PolylineAlgorithm.Benchmarks/GlobalSuppressions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//
2-
// Copyright (c) Pete Sramek. All rights reserved.
3-
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
1+
//
2+
// Copyright © Pete Sramek. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

66
using System.Diagnostics.CodeAnalysis;

benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//
2-
// Copyright (c) Pete Sramek. All rights reserved.
3-
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
1+
//
2+
// Copyright © Pete Sramek. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

66
namespace PolylineAlgorithm.Benchmarks;
@@ -10,7 +10,8 @@ namespace PolylineAlgorithm.Benchmarks;
1010
using PolylineAlgorithm;
1111

1212
[RankColumn]
13-
public class PolylineDecoderBenchmark {
13+
public class PolylineDecoderBenchmark
14+
{
1415
private readonly Consumer _consumer = new();
1516

1617
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
@@ -24,14 +25,16 @@ public class PolylineDecoderBenchmark {
2425
public PolylineDecoder Decoder = new();
2526

2627
[GlobalSetup]
27-
public void SetupData() {
28+
public void SetupData()
29+
{
2830
StringValue = @"sq_|Fptm{UrbxoHinoiEuhmbHctjfc@`rocCt|nfJgiauLvc_uIh`pg_@h_fkVgctZoyqfW{rxgQhhymFpuvvDwqcfTlqbcBiegdTwf{uNngc|z@{vhlDnsi_B~nz`O}d_hNp{n`E}kcoKm`bCiul~\jhg|Hv{qoWshzh\{lf_G`pzMqm|bLzswoQbhcm`@b`}cIgignPgxntR|}vo^f~|}L}|_jBa|ujWuxkjQfj|w[wsz`Pmdb{XohnwA`srxWjitms@c_~`Tava_l@jxxcF`d|zHcpnaMnd{kYzccwPxzpiHfsxlL}jjjQqvdbIikyvj@cjdqTh`zoDzqleHnfmik@tbnoB_t}gFkzx_Ct_eiP`wxrBcd_|w@zlhfPtlxgBkwyyZn|~tFlpj|HxqiwUnddkFoo|nTee}dSfkcg`@py`uQiguom@zkkpEfcgkAntuuDzl~il@ir_gCrd~nI_ryeC_qmmMl_kgCz`qgFzkejBmlchYyp`hZ`_cuYzuc}Onqz}Ew~Gcsmj@lp{Hqj_gz@ne{pJnny~]g{tuNxbno[lfq_Lqhwjt@qn|cCuxnMyivuIh{|tR`ylsQlqbfO}rf`LxghfBg~{nAv`gdNbjh_Fglt|NfxwyBowwhW{bdtNdbkqe@rxtwSy{_fX{btm@va`_LkhwuUyqgzK`xdnKgbwsFigt_Mofdn\h|x[ccoPtbpvNz}skb@pl~xEqascV_wsx[`f_z]zewFs`zjAhturWxayhJqmfaAjmhhHxwuwF_aru@ojemVq|beu@kkucBdmryTevflDcbmdAnp|dHfpbd^io}z@e~}dFzcybQ}`hxOyt|bNl}blLnuspKk|t|k@itjfHt}}aVyzmcF_rgmLct}x@bazdq@loajBxygb@f}krVgnuqOcrx_Daqvp_@ew}yUn}kpU|uwnItashEpe_aHusi{Fsu}_Ewfhv[dzhzKxh_qXucxfXmynkGxuqbW|ppgi@vrsq@clryZk`bt^spkyP";
2931
CharArray = StringValue.ToCharArray();
3032
Memory = StringValue.AsMemory();
3133
}
3234

3335
[Benchmark]
34-
public void PolylineDecoder_Decode_FromString() {
36+
public void PolylineDecoder_Decode_FromString()
37+
{
3538
Polyline polyline = Polyline.FromString(StringValue);
3639

3740
Decoder
@@ -40,7 +43,8 @@ public void PolylineDecoder_Decode_FromString() {
4043
}
4144

4245
[Benchmark]
43-
public void PolylineDecoder_Decode_FromCharArray() {
46+
public void PolylineDecoder_Decode_FromCharArray()
47+
{
4448
Polyline polyline = Polyline.FromCharArray(CharArray);
4549

4650
Decoder
@@ -49,7 +53,8 @@ public void PolylineDecoder_Decode_FromCharArray() {
4953
}
5054

5155
[Benchmark]
52-
public void PolylineDecoder_Decode_FromMemory() {
56+
public void PolylineDecoder_Decode_FromMemory()
57+
{
5358
Polyline polyline = Polyline.FromMemory(Memory);
5459

5560
Decoder

benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//
2-
// Copyright (c) Pete Sramek. All rights reserved.
3-
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
1+
//
2+
// Copyright © Pete Sramek. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

66
namespace PolylineAlgorithm.Benchmarks;
@@ -10,7 +10,8 @@ namespace PolylineAlgorithm.Benchmarks;
1010
using System.Collections.Generic;
1111

1212
[RankColumn]
13-
public class PolylineEncoderBenchmark {
13+
public class PolylineEncoderBenchmark
14+
{
1415
private static readonly Random R = new();
1516

1617
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
@@ -23,19 +24,22 @@ public class PolylineEncoderBenchmark {
2324
public PolylineEncoder Encoder = new();
2425

2526
[GlobalSetup]
26-
public void SetupData() {
27+
public void SetupData()
28+
{
2729
Enumeration = Enumerable.Range(0, 100).Select(i => new Coordinate(R.Next(-90, 90) + R.NextDouble(), R.Next(-180, 180) + R.NextDouble()));
2830
List = [.. Enumeration];
2931
}
3032

3133
[Benchmark]
32-
public Polyline PolylineEncoder_Encode_List() {
34+
public Polyline PolylineEncoder_Encode_List()
35+
{
3336
return Encoder
3437
.Encode(List!);
3538
}
3639

3740
[Benchmark]
38-
public Polyline PolylineEncoder_Encode_Enumerator() {
41+
public Polyline PolylineEncoder_Encode_Enumerator()
42+
{
3943
return Encoder
4044
.Encode(Enumeration!);
4145
}

benchmarks/PolylineAlgorithm.Benchmarks/Program.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
//
2-
// Copyright (c) Pete Sramek. All rights reserved.
3-
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
1+
//
2+
// Copyright © Pete Sramek. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

66
namespace PolylineAlgorithm.Benchmarks;
77

88
using BenchmarkDotNet.Configs;
99
using BenchmarkDotNet.Running;
1010

11-
internal class Program {
12-
static void Main(string[] args) {
11+
internal class Program
12+
{
13+
static void Main(string[] args)
14+
{
1315
BenchmarkSwitcher
1416
.FromAssembly(typeof(Program).Assembly)
1517
.Run(args, DefaultConfig.Instance);

src/PolylineAlgorithm/Coordinate.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ namespace PolylineAlgorithm;
1717
/// </summary>
1818
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 16)]
1919
[DebuggerDisplay("{ToString()}")]
20-
public readonly struct Coordinate : IEquatable<Coordinate> {
20+
public readonly struct Coordinate : IEquatable<Coordinate>
21+
{
2122
/// <summary>
2223
/// Initializes default instance of <see cref="Coordinate"/> with <see cref="Latitude" /> and <see cref="Longitude" /> equal to 0.
2324
/// </summary>
24-
public Coordinate() {
25+
public Coordinate()
26+
{
2527
Latitude = 0d;
2628
Longitude = 0d;
2729
}
@@ -31,7 +33,8 @@ public Coordinate() {
3133
/// </summary>
3234
/// <param name="latitude">A latitude value.</param>
3335
/// <param name="longitude">A latitude value.</param>
34-
public Coordinate(double latitude, double longitude) {
36+
public Coordinate(double latitude, double longitude)
37+
{
3538
Latitude = latitude;
3639
Longitude = longitude;
3740
}
@@ -64,13 +67,15 @@ public bool IsValid
6467

6568
/// <inheritdoc />
6669
[ExcludeFromCodeCoverage]
67-
public override bool Equals(object? obj) {
70+
public override bool Equals(object? obj)
71+
{
6872
return obj is Coordinate coordinate && Equals(coordinate);
6973
}
7074

7175
/// <inheritdoc />
7276
[ExcludeFromCodeCoverage]
73-
public override int GetHashCode() {
77+
public override int GetHashCode()
78+
{
7479
return HashCode.Combine(Latitude, Longitude);
7580
}
7681

@@ -80,7 +85,8 @@ public override int GetHashCode() {
8085
/// <returns>The formatted string respresentation of this instance.</returns>
8186
/// <remarks>{ Latitude: [double], Longitude: [double] }</remarks>
8287
[ExcludeFromCodeCoverage]
83-
public override string ToString() {
88+
public override string ToString()
89+
{
8490
return $"{{ {nameof(Latitude)}: {Latitude.ToString("G", CultureInfo.InvariantCulture)}, {nameof(Longitude)}: {Longitude.ToString("G", CultureInfo.InvariantCulture)} }}";
8591
}
8692

@@ -89,7 +95,8 @@ public override string ToString() {
8995
#region IEquatable<Coordinate> implementation
9096

9197
/// <inheritdoc />
92-
public bool Equals(Coordinate other) {
98+
public bool Equals(Coordinate other)
99+
{
93100
return Latitude == other.Latitude &&
94101
Longitude == other.Longitude;
95102
}
@@ -100,13 +107,15 @@ public bool Equals(Coordinate other) {
100107

101108
/// <inheritdoc />
102109
[ExcludeFromCodeCoverage]
103-
public static bool operator ==(Coordinate left, Coordinate right) {
110+
public static bool operator ==(Coordinate left, Coordinate right)
111+
{
104112
return left.Equals(right);
105113
}
106114

107115
/// <inheritdoc />
108116
[ExcludeFromCodeCoverage]
109-
public static bool operator !=(Coordinate left, Coordinate right) {
117+
public static bool operator !=(Coordinate left, Coordinate right)
118+
{
110119
return !(left == right);
111120
}
112121

src/PolylineAlgorithm/IPolylineDecoder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace PolylineAlgorithm;
1010
/// <summary>
1111
/// Defines method to decode a polyline.
1212
/// </summary>
13-
public interface IPolylineDecoder {
13+
public interface IPolylineDecoder
14+
{
1415
/// <summary>
1516
/// Converts an encoded polyline to a set of coordinates.
1617
/// </summary>

src/PolylineAlgorithm/IPolylineEncoder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace PolylineAlgorithm;
1010
/// <summary>
1111
/// Defines method to encode a set of coordinates.
1212
/// </summary>
13-
public interface IPolylineEncoder {
13+
public interface IPolylineEncoder
14+
{
1415
/// <summary>
1516
/// Converts a set of coordinates to an encoded polyline.
1617
/// </summary>

src/PolylineAlgorithm/Internal/Defaults.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ namespace PolylineAlgorithm.Internal;
1212
/// Defines default values
1313
/// </summary>
1414
[ExcludeFromCodeCoverage]
15-
internal static class Defaults {
16-
public static class Algorithm {
15+
internal static class Defaults
16+
{
17+
public static class Algorithm
18+
{
1719
/// <summary>
1820
/// Defines the coordinate precision
1921
/// </summary>
@@ -43,11 +45,13 @@ public static class Algorithm {
4345
/// <summary>
4446
/// Defines coordinates default values
4547
/// </summary>
46-
public static class Coordinate {
48+
public static class Coordinate
49+
{
4750
/// <summary>
4851
/// Defines latitude default values
4952
/// </summary>
50-
public static class Latitude {
53+
public static class Latitude
54+
{
5155
/// <summary>
5256
/// Defines the maximum value for latitude
5357
/// </summary>
@@ -62,7 +66,8 @@ public static class Latitude {
6266
/// <summary>
6367
/// Defines longitude default values
6468
/// </summary>
65-
public static class Longitude {
69+
public static class Longitude
70+
{
6671
/// <summary>
6772
/// Defines the maximum value for longitude
6873
/// </summary>
@@ -77,7 +82,8 @@ public static class Longitude {
7782
/// <summary>
7883
/// Defines default ranges for latitude and longitude
7984
/// </summary>
80-
public static class Range {
85+
public static class Range
86+
{
8187
/// <summary>
8288
/// Defines latitude validation range
8389
/// </summary>

src/PolylineAlgorithm/Internal/PolylineReader.cs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ namespace PolylineAlgorithm.Internal;
99
using System.Runtime.InteropServices;
1010

1111
[StructLayout(LayoutKind.Auto)]
12-
internal ref struct PolylineReader {
12+
internal ref struct PolylineReader
13+
{
1314
private ReaderState _state = new();
1415
private readonly ReadOnlySpan<char> _polyline;
1516

16-
public PolylineReader() {
17+
public PolylineReader()
18+
{
1719
_polyline = [];
1820
}
1921

20-
public PolylineReader(ref readonly Polyline polyline) {
22+
public PolylineReader(ref readonly Polyline polyline)
23+
{
2124
_polyline = polyline.Span;
2225
}
2326

@@ -26,7 +29,8 @@ public PolylineReader(ref readonly Polyline polyline) {
2629
public readonly int Position => _state.Position;
2730

2831
[MethodImpl(MethodImplOptions.AggressiveInlining)]
29-
public Coordinate Read() {
32+
public Coordinate Read()
33+
{
3034
InvalidReaderStateException.ThrowIfCannotRead(CanRead, Position, _polyline.Length);
3135

3236
GetCurrent(out int currentLatitude, out int currentLongitude);
@@ -39,52 +43,61 @@ public Coordinate Read() {
3943
return new(Precise(ref latitude), Precise(ref longitude));
4044

4145
[MethodImpl(MethodImplOptions.AggressiveInlining)]
42-
static double Precise(ref int value) {
46+
static double Precise(ref int value)
47+
{
4348
return value / Defaults.Algorithm.Precision;
4449
}
4550
}
4651

4752
[MethodImpl(MethodImplOptions.AggressiveInlining)]
48-
void Advance() {
53+
void Advance()
54+
{
4955
_state.Position += 1;
5056
}
5157

5258
[MethodImpl(MethodImplOptions.AggressiveInlining)]
53-
void SetCurrent(ref readonly int latitude, ref readonly int longitude) {
59+
void SetCurrent(ref readonly int latitude, ref readonly int longitude)
60+
{
5461
_state.Latitude = latitude;
5562
_state.Longitude = longitude;
5663
}
5764

5865
[MethodImpl(MethodImplOptions.AggressiveInlining)]
59-
readonly void GetCurrent(out int latitude, out int longitude) {
66+
readonly void GetCurrent(out int latitude, out int longitude)
67+
{
6068
latitude = _state.Latitude;
6169
longitude = _state.Longitude;
6270
}
6371

6472
[MethodImpl(MethodImplOptions.AggressiveInlining)]
65-
int ReadNext(ref readonly int value) {
73+
int ReadNext(ref readonly int value)
74+
{
6675
int chunk;
6776
int sum = 0;
6877
int shifter = 0;
6978

70-
do {
79+
do
80+
{
7181
InvalidReaderStateException.ThrowIfCannotRead(CanRead, Position, _polyline.Length);
7282
chunk = _polyline[Position] - Defaults.Algorithm.QuestionMark;
7383
sum |= (chunk & Defaults.Algorithm.UnitSeparator) << shifter;
7484
shifter += Defaults.Algorithm.ShiftLength;
7585
Advance();
7686
} while (chunk >= Defaults.Algorithm.Space && CanRead);
7787

78-
if (!CanRead && chunk >= Defaults.Algorithm.Space) {
88+
if (!CanRead && chunk >= Defaults.Algorithm.Space)
89+
{
7990
InvalidPolylineException.Throw(Position);
8091
}
8192

8293
return value + ((sum & 1) == 1 ? ~(sum >> 1) : sum >> 1);
8394
}
8495

8596
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 12)]
86-
private ref struct ReaderState {
87-
public ReaderState() {
97+
private ref struct ReaderState
98+
{
99+
public ReaderState()
100+
{
88101
Position = Latitude = Longitude = 0;
89102
}
90103

0 commit comments

Comments
 (0)