Skip to content

Commit 268ae2e

Browse files
committed
interim commit
1 parent 635ee54 commit 268ae2e

31 files changed

+268
-285
lines changed

benchmarks/PolylineAlgorithm.Benchmarks/PolylineBuilderBenchmark.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
namespace PolylineAlgorithm.Benchmarks;
77

88
using BenchmarkDotNet.Attributes;
9-
using PolylineAlgorithm;
109
using PolylineAlgorithm.Abstraction.Internal;
11-
using PolylineAlgorithm.Internal;
1210
using PolylineAlgorithm.Utility;
1311
using System.Buffers;
1412

benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks;
77

88
using BenchmarkDotNet.Attributes;
99
using PolylineAlgorithm;
10-
using PolylineAlgorithm.Abstraction;
1110
using PolylineAlgorithm.Utility;
1211
using System.Collections.Generic;
1312

samples/PolylineAlgorithm.NetTopologySuite.Sample/NetTopologyPolylineDecoder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
using System.Buffers;
77

88
internal class NetTopologyPolylineDecoder : PolylineDecoder<Point, string> {
9+
public override PolylineEncodingOptions<Point> Options { get; } = PolylineEncodingOptions<Point>.Default;
10+
911
protected override Point CreateCoordinate(double latitude, double longitude) {
1012
return new Point(latitude, longitude);
1113
}
1214

1315
protected override ReadOnlySequence<char> GetReadOnlySequence(string? polyline) {
14-
if(string.IsNullOrWhiteSpace(polyline)) {
16+
if (string.IsNullOrWhiteSpace(polyline)) {
1517
throw new ArgumentException("Value cannot be null, empty or whitespace.", nameof(polyline));
1618
}
1719

samples/PolylineAlgorithm.NetTopologySuite.Sample/NetTopologyPolylineEncoder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22

33
using global::NetTopologySuite.Geometries;
44
using PolylineAlgorithm.Abstraction;
5-
using System;
65
using System.Buffers;
76
using System.Text;
87

98
internal class NetTopologyPolylineEncoder : PolylineEncoder<Point, string> {
9+
public override PolylineEncodingOptions<Point> Options { get; } = PolylineEncodingOptions<Point>.Default;
10+
1011
protected override string CreatePolyline(ReadOnlySequence<char> sequence) {
11-
if(sequence.IsEmpty) {
12+
if (sequence.IsEmpty) {
1213
return string.Empty;
1314
}
1415

15-
if(sequence.IsSingleSegment) {
16+
if (sequence.IsSingleSegment) {
1617
return sequence.FirstSpan.ToString();
1718
}
1819

src/PolylineAlgorithm.Abstraction/IPolylineDecoder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ public interface IPolylineDecoder<TCoordinate, TPolyline> {
1515
/// Decodes the specified encoded polyline into a sequence of geographic coordinates.
1616
/// </summary>
1717
/// <param name="polyline">
18-
/// The <see cref="Polyline"/> instance containing the encoded polyline string to decode.
18+
/// The <typeparamref name="TPolyline"/> instance containing the encoded polyline string to decode.
1919
/// </param>
2020
/// <returns>
21-
/// An <see cref="IEnumerable{T}"/> of <see cref="Coordinate"/> representing the decoded latitude and longitude pairs.
21+
/// An <see cref="IEnumerable{T}"/> of <typeparamref name="TCoordinate"/> representing the decoded latitude and longitude pairs.
2222
/// </returns>
23-
IEnumerable<TCoordinate> Decode(TPolyline coordinates);
23+
IEnumerable<TCoordinate> Decode(TPolyline polyline);
2424
}

src/PolylineAlgorithm.Abstraction/IPolylineEncoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ public interface IPolylineEncoder<TCoordinate, TPolyline> {
1515
/// Encodes a sequence of geographic coordinates into an encoded polyline representation.
1616
/// </summary>
1717
/// <param name="coordinates">
18-
/// The collection of <see cref="Coordinate"/> instances to encode into a polyline.
18+
/// The collection of <typeparamref name="TCoordinate"/> instances to encode into a polyline.
1919
/// </param>
2020
/// <returns>
21-
/// A <see cref="Polyline"/> containing the encoded polyline string that represents the input coordinates.
21+
/// A <typeparamref name="TPolyline"/> containing the encoded polyline string that represents the input coordinates.
2222
/// </returns>
2323
TPolyline Encode(IEnumerable<TCoordinate> coordinates);
2424
}

src/PolylineAlgorithm.Abstraction/Internal/PolylineBuilder.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace PolylineAlgorithm.Abstraction.Internal;
1010
using System.Runtime.InteropServices;
1111

1212
/// <summary>
13-
/// Provides an efficient mechanism for constructing a <see cref="Polyline"/> from multiple character segments.
13+
/// Provides an efficient mechanism for constructing a <see cref="ReadOnlySequence{T}"/> from multiple character segments.
1414
/// This struct enables incremental building of a polyline by appending segments and producing a single concatenated result.
1515
/// </summary>
1616
[StructLayout(LayoutKind.Auto)]
@@ -37,13 +37,13 @@ public void Append(ReadOnlyMemory<char> value) {
3737
}
3838

3939
/// <summary>
40-
/// Constructs the final <see cref="Polyline"/> instance by concatenating all appended segments.
40+
/// Constructs a <see cref="ReadOnlySequence{T}"/> representing the concatenation of all appended character segments.
4141
/// </summary>
4242
/// <returns>
43-
/// A <see cref="Polyline"/> representing the combined character segments.
44-
/// If no segments have been appended, returns an empty <see cref="Polyline"/>.
43+
/// A <see cref="ReadOnlySequence{T}"/> containing all segments appended to this builder, or an empty sequence if no segments were added.
4544
/// </returns>
46-
public readonly ReadOnlySequence<char> Build() {
45+
public readonly ReadOnlySequence<char> Build()
46+
{
4747
if (_initial is null) {
4848
return new();
4949
}

src/PolylineAlgorithm.Abstraction/Internal/PolylineSegment.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ namespace PolylineAlgorithm.Abstraction.Internal;
99

1010
/// <summary>
1111
/// Represents a segment of a polyline as part of a linked list of character memory segments.
12-
/// Inherits from <see cref="ReadOnlySequenceSegment{char}"/> to enable efficient manipulation and traversal of polyline data.
12+
/// Inherits from <see cref="ReadOnlySequenceSegment{T}"/> to enable efficient manipulation and traversal of polyline data.
1313
/// </summary>
1414
internal class PolylineSegment : ReadOnlySequenceSegment<char> {
1515
/// <summary>
1616
/// Initializes a new instance of the <see cref="PolylineSegment"/> class with the specified memory segment and optional running index.
1717
/// </summary>
1818
/// <param name="memory">
19-
/// The <see cref="ReadOnlyMemory{char}"/> segment to associate with this polyline segment.
19+
/// The <see cref="ReadOnlyMemory{T}"/> segment to associate with this polyline segment.
2020
/// </param>
2121
/// <param name="runningIndex">
2222
/// The cumulative index of this segment within the polyline sequence. Defaults to 0.
@@ -30,7 +30,7 @@ public PolylineSegment(ReadOnlyMemory<char> memory, long runningIndex = 0) {
3030
/// Appends a new memory segment to the end of the current polyline segment chain.
3131
/// </summary>
3232
/// <param name="memory">
33-
/// The <see cref="ReadOnlyMemory{char}"/> segment to append as a new <see cref="PolylineSegment"/>.
33+
/// The <see cref="ReadOnlyMemory{T}"/> segment to append as a new <see cref="PolylineSegment"/>.
3434
/// </param>
3535
public void Append(ReadOnlyMemory<char> memory) {
3636
Append(new PolylineSegment(memory));

src/PolylineAlgorithm.Abstraction/PolylineAlgorithm.Abstraction.csproj

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,22 @@
3939
<Copyright>© 2025, Pete Sramek.</Copyright>
4040
</PropertyGroup>
4141

42+
<ItemGroup>
43+
<AdditionalFiles Include="PublicAPI.Shipped.txt" />
44+
<AdditionalFiles Include="PublicAPI.Unshipped.txt" />
45+
</ItemGroup>
46+
4247
<ItemGroup>
4348
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.*">
4449
<PrivateAssets>all</PrivateAssets>
4550
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
4651
</PackageReference>
4752
</ItemGroup>
4853

49-
<ItemGroup>
50-
<Compile Update="Properties\ExceptionMessageResource.Designer.cs">
51-
<DependentUpon>ExceptionMessageResource.resx</DependentUpon>
52-
<DesignTime>True</DesignTime>
53-
<AutoGen>True</AutoGen>
54-
</Compile>
55-
</ItemGroup>
56-
5754
<ItemGroup>
5855
<EmbeddedResource Update="Properties\ExceptionMessageResource.resx">
59-
<LastGenOutput>ExceptionMessageResource.Designer.cs</LastGenOutput>
6056
<Generator>ResXFileCodeGenerator</Generator>
57+
<LastGenOutput>ExceptionMessageResource.Designer.cs</LastGenOutput>
6158
</EmbeddedResource>
6259
</ItemGroup>
6360

@@ -70,4 +67,19 @@
7067
</AssemblyAttribute>
7168
</ItemGroup>
7269

70+
<ItemGroup>
71+
<None Include="..\..\README.md" Link="README.md">
72+
<PackagePath>\</PackagePath>
73+
<Pack>True</Pack>
74+
</None>
75+
</ItemGroup>
76+
77+
<ItemGroup>
78+
<Compile Update="Properties\ExceptionMessageResource.Designer.cs">
79+
<DesignTime>True</DesignTime>
80+
<AutoGen>True</AutoGen>
81+
<DependentUpon>ExceptionMessageResource.resx</DependentUpon>
82+
</Compile>
83+
</ItemGroup>
84+
7385
</Project>

src/PolylineAlgorithm.Abstraction/PolylineDecoder.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,22 @@ namespace PolylineAlgorithm.Abstraction;
1212

1313
/// <summary>
1414
/// Decodes encoded polyline strings into sequences of geographic coordinates.
15-
/// Implements the <see cref="IPolylineDecoder"/> interface.
15+
/// Implements the <see cref="IPolylineDecoder{TCoordinate, TPolyline}"/> interface.
1616
/// </summary>
1717
public abstract class PolylineDecoder<TCoordinate, TPolyline> : IPolylineDecoder<TCoordinate, TPolyline> {
1818
/// <summary>
19-
/// Decodes an encoded <see cref="Polyline"/> into a sequence of <see cref="Coordinate"/> instances.
19+
/// Gets the encoding options used by this polyline encoder.
20+
/// </summary>
21+
public abstract PolylineEncodingOptions<TCoordinate> Options { get; }
22+
23+
/// <summary>
24+
/// Decodes an encoded <typeparamref name="TPolyline"/> into a sequence of <typeparamref name="TCoordinate"/> instances.
2025
/// </summary>
2126
/// <param name="polyline">
22-
/// The <see cref="Polyline"/> instance containing the encoded polyline string to decode.
27+
/// The <typeparamref name="TPolyline"/> instance containing the encoded polyline string to decode.
2328
/// </param>
2429
/// <returns>
25-
/// An <see cref="IEnumerable{T}"/> of <see cref="Coordinate"/> representing the decoded latitude and longitude pairs.
30+
/// An <see cref="IEnumerable{T}"/> of <typeparamref name="TCoordinate"/> representing the decoded latitude and longitude pairs.
2631
/// </returns>
2732
/// <exception cref="ArgumentException">
2833
/// Thrown when <paramref name="polyline"/> is empty.
@@ -38,14 +43,15 @@ public IEnumerable<TCoordinate> Decode(TPolyline polyline) {
3843
ReadOnlySequence<char> source = GetReadOnlySequence(polyline);
3944

4045
if (source.Length < Defaults.Polyline.MinEncodedCoordinateLength) {
41-
throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullEmptyOrWhitespaceMessage, nameof(polyline));
46+
throw new ArgumentException(string.Format(ExceptionMessageResource.PolylineCannotBeShorterThanExceptionMessage, source.Length), nameof(polyline));
4247
}
4348

4449
ReadOnlySequence<char>.Enumerator enumerator = source.GetEnumerator();
4550

4651
int consumed = 0;
4752
int latitude = 0;
4853
int longitude = 0;
54+
(double Latitude, double Longitude) coordinate;
4955

5056
int position;
5157
ReadOnlyMemory<char> sequence;
@@ -57,6 +63,12 @@ public IEnumerable<TCoordinate> Decode(TPolyline polyline) {
5763
while (PolylineEncoding.Default.TryReadValue(ref latitude, ref sequence, ref position)
5864
&& PolylineEncoding.Default.TryReadValue(ref longitude, ref sequence, ref position)
5965
) {
66+
coordinate = (PolylineEncoding.Default.Denormalize(latitude), PolylineEncoding.Default.Denormalize(longitude));
67+
68+
if(!Options.Validator.IsValidLatitude(coordinate.Latitude) && !Options.Validator.IsValidLongitude(coordinate.Longitude)) {
69+
throw new Exception();
70+
}
71+
6072
yield return CreateCoordinate(PolylineEncoding.Default.Denormalize(latitude), PolylineEncoding.Default.Denormalize(longitude));
6173
}
6274

@@ -68,7 +80,22 @@ public IEnumerable<TCoordinate> Decode(TPolyline polyline) {
6880
}
6981
}
7082

83+
/// <summary>
84+
/// Converts the provided polyline instance into a <see cref="ReadOnlySequence{Char}"/> for decoding.
85+
/// </summary>
86+
/// <param name="polyline">
87+
/// The polyline instance to convert. May be <c>null</c>.
88+
/// </param>
89+
/// <returns>
90+
/// A <see cref="ReadOnlySequence{T}"/> representing the encoded polyline data.
91+
/// </returns>
7192
protected abstract ReadOnlySequence<char> GetReadOnlySequence(TPolyline? polyline);
7293

94+
/// <summary>
95+
/// Creates a coordinate instance from the given latitude and longitude values.
96+
/// </summary>
97+
/// <param name="latitude">The latitude value.</param>
98+
/// <param name="longitude">The longitude value.</param>
99+
/// <returns>A coordinate instance of type <typeparamref name="TCoordinate"/>.</returns>
73100
protected abstract TCoordinate CreateCoordinate(double latitude, double longitude);
74101
}

0 commit comments

Comments
 (0)