Skip to content

Commit

Permalink
[WIP|Draft|Spike] First try using Pidgin Parser lib for WKT1Parser.
Browse files Browse the repository at this point in the history
  • Loading branch information
driekus77 committed Jul 14, 2024
1 parent 246879e commit 9157e53
Show file tree
Hide file tree
Showing 17 changed files with 1,591 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/ProjNet/ProjNET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ Proj.NET performs point-to-point coordinate conversions between geodetic coordin
<ResolvedMatchingContract Include="$(NugetPackageRoot)projnet\2.0.0\lib\netstandard2.0\ProjNET.dll" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Pidgin" Version="2.5.0" />
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions src/ProjNet/Wkt/Utils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;

namespace ProjNet.Wkt
{
/// <summary>
/// Helper functions for WKT Parser(s).
/// </summary>
public class Utils
{
internal static double CalcAsFractionOf(uint i, uint f)
{
// Convert f to string to count the digits
string fstr = f.ToString();
int fractionDigits = fstr.Length;

double d = i;

// Calculate the fractional part from f based on the number of fractional digits
double divisor = Math.Pow(10, fractionDigits);
double fractionPart = f / divisor;

// Sum i and the fractional part
return d + fractionPart;
}
}
}
573 changes: 573 additions & 0 deletions src/ProjNet/Wkt/Wkt1Parser.cs

Large diffs are not rendered by default.

Binary file not shown.
119 changes: 119 additions & 0 deletions src/ProjNet/Wkt/v1/DateTimeBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System;
using System.Globalization;
using Pidgin;

namespace ProjNet.Wkt.v1
{
internal sealed class DateTimeBuilder
{
internal int? Year { get; set; }
internal int? Month { get; set; }
internal int? Day { get; set; }

internal uint? OrdinalDay { get; set; }

internal int? Hour { get; set; }
internal int? Minutes { get; set; }
internal int? Seconds { get; set; }
internal int? Milliseconds { get; set; }

internal TimeSpan? LocalOffset { get; set; }

internal DateTimeKind Kind { get; set; } = DateTimeKind.Unspecified;


public DateTimeBuilder SetYear(int y)
{
Year = y;
return this;
}
public DateTimeBuilder SetMonth(int m)
{
Month = m;
return this;
}
public DateTimeBuilder SetDay(int d)
{
Day = d;
return this;
}

public DateTimeBuilder SetHour(int h)
{
Hour = h;
return this;
}
public DateTimeBuilder SetMinutes(int m)
{
Minutes = m;
return this;
}
public DateTimeBuilder SetSeconds(int s)
{
Seconds = s;
return this;
}
public DateTimeBuilder SetMilliseconds(int ms)
{
Milliseconds = ms;
return this;
}

public DateTimeBuilder SetOrdinalDay(Maybe<uint> od)
{
OrdinalDay = od.HasValue ? od.GetValueOrDefault() : OrdinalDay;
return this;
}


public DateTimeBuilder SetKind(DateTimeKind k)
{
Kind = k;
return this;
}

public DateTimeBuilder SetLocalOffset(TimeSpan lo)
{
if (lo == TimeSpan.Zero)
{
Kind = DateTimeKind.Utc;
}
else
{
LocalOffset = lo;
Kind = DateTimeKind.Local;
}

return this;
}

public DateTimeBuilder Merge(DateTimeBuilder other)
{
Day = Day ?? other.Day;
Month = Month ?? other.Month;
Year = Year ?? other.Year;

Hour = Hour ?? other.Hour;
Minutes = Minutes ?? other.Minutes;
Seconds = Seconds ?? other.Seconds;
Milliseconds = Milliseconds ?? other.Milliseconds;

OrdinalDay = OrdinalDay ?? other.OrdinalDay;
Kind = Kind == DateTimeKind.Unspecified ? other.Kind : Kind;
LocalOffset = LocalOffset ?? other.LocalOffset;

return this;
}

public DateTimeOffset ToDateTimeOffset()
{
var dt = new DateTime(Year.GetValueOrDefault(), Month.GetValueOrDefault(), Day.GetValueOrDefault(),
Hour.GetValueOrDefault(), Minutes.GetValueOrDefault(), Seconds.GetValueOrDefault(),
Milliseconds.GetValueOrDefault(),
new GregorianCalendar(),
Kind);

return new DateTimeOffset(dt, LocalOffset.GetValueOrDefault());
}
}
}
34 changes: 34 additions & 0 deletions src/ProjNet/Wkt/v1/tree/AreaDescription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Globalization;
using System.Text;

namespace ProjNet.Wkt.v1.tree
{
/// <summary>
/// Area description is an optional attribute which describes a geographic area over which a CRS or coordinate operation is applicable.
/// </summary>
/// <remarks>
/// See 7.3.3.2 Area description in specification document.
/// </remarks>
public class AreaDescription : Extent
{
/// <summary>
/// The Text Description.
/// </summary>
public string Description { get; set; }

/// <summary>
/// AreaDescriptionParser to WKT.
/// </summary>
/// <returns></returns>
public override string ToWKT()
{
var sb = new StringBuilder();

sb.Append("AREA[\"");
sb.Append(Description);
sb.Append("\"]");

return sb.ToString();
}
}
}
28 changes: 28 additions & 0 deletions src/ProjNet/Wkt/v1/tree/AuthorityCitation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text;

namespace ProjNet.Wkt.v1.tree
{
/// <summary>
/// AuthorityCitation a simple wkt helper class containing a (sub) Attribute.
/// </summary>
public class AuthorityCitation: IWktAttribute
{
private string Citation { get; set; }

public AuthorityCitation(string citation)
{
Citation = citation;
}

public string ToWKT()
{
var sb = new StringBuilder();

sb.Append($@"CITATION[""");
sb.Append(Citation);
sb.Append($@"""]");

return sb.ToString();
}
}
}
56 changes: 56 additions & 0 deletions src/ProjNet/Wkt/v1/tree/BBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Globalization;
using System.Text;

namespace ProjNet.Wkt.v1.tree
{
/// <summary>
/// BoundingBox is an optional WKT attribute.
/// </summary>
/// <remarks>
/// See 7.3.3.3 Geographic bounding box in specification document.
/// </remarks>
public class BBox : Extent
{
/// <summary>
/// The lower left latitude (Ymin)
/// </summary>
public double LowerLeftLatitude { get; set; }

/// <summary>
/// The lower left longitude (Xmin)
/// </summary>
public double LowerLeftLongitude { get; set; }

/// <summary>
/// The upper right latitude (Ymax)
/// </summary>
public double UpperRightLatitude { get; set; }

/// <summary>
/// The upper right longitude (Xmax)
/// </summary>
public double UpperRightLongitude { get; set; }


/// <summary>
/// BBox to WKT.
/// </summary>
/// <returns></returns>
public override string ToWKT()
{
var sb = new StringBuilder();

sb.Append("BBOX[");
sb.Append(LowerLeftLatitude.ToString(CultureInfo.InvariantCulture));
sb.Append(",");
sb.Append(LowerLeftLongitude.ToString(CultureInfo.InvariantCulture));
sb.Append(",");
sb.Append(UpperRightLatitude.ToString(CultureInfo.InvariantCulture));
sb.Append(",");
sb.Append(UpperRightLongitude.ToString(CultureInfo.InvariantCulture));
sb.Append("]");

return sb.ToString();
}
}
}
8 changes: 8 additions & 0 deletions src/ProjNet/Wkt/v1/tree/Extent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ProjNet.Wkt.v1.tree
{
public abstract class Extent : IWktAttribute
{
public abstract string ToWKT();

}
}
10 changes: 10 additions & 0 deletions src/ProjNet/Wkt/v1/tree/IWktAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ProjNet.Wkt.v1.tree
{
/// <summary>
/// Interface for specifying WKT Attributes.
/// </summary>
public interface IWktAttribute
{
string ToWKT();
}
}
89 changes: 89 additions & 0 deletions src/ProjNet/Wkt/v1/tree/Identifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

using System;
using System.Globalization;
using System.Text;

namespace ProjNet.Wkt.v1.tree
{
/// <summary>
/// Identifier is an optional attribute which references an external
/// description of the object and which may be applied to a coordinate reference system, a coordinate
/// operation or a boundCRS. It may also be utilised for components of these objects although this
/// is not recommended except for coordinate operation methods (including map projections)
/// and parameters. Multiple identifiers may be given for any object.
///
/// When an identifier is given for a coordinate reference system, coordinate operation or boundCRS,
/// it applies to the whole object including all of its components.
///
/// Should any attributes or values given in the cited identifier be in conflict with attributes
/// or values given explicitly in the WKT description, the WKT values shall prevail.
/// </summary>
/// <remarks>
/// See 7.3.4 Identifier in specification document.
/// </remarks>
public class Identifier : IWktAttribute
{
/// <summary>
/// AuthorityName
/// </summary>
public string AuthorityName { get; set; }

/// <summary>
/// AuthorityUniqueIdentifier
/// </summary>
public object AuthorityUniqueIdentifier { get; set; }

/// <summary>
/// Version (Optional)
/// </summary>
public object Version { get; set; }

/// <summary>
/// AuthorityCitation (Optional)
/// </summary>
public AuthorityCitation AuthorityCitation { get; set; }

/// <summary>
/// Id Uri (Optional)
/// </summary>
/// <returns></returns>
public Uri IdUri { get; set; }


public string ToWKT()
{
var sb = new StringBuilder();

sb.Append("ID[");

sb.Append($@"""{AuthorityName}""");
sb.Append($@"""{AuthorityUniqueIdentifier}""");

if (Version != null)
{
if (Version is double d)
{
sb.Append(d.ToString(CultureInfo.InvariantCulture));
}
else if (Version is string vs)
{
sb.Append($@"""{vs}""");
}
}

if (AuthorityCitation != null)
{
sb.Append(AuthorityCitation.ToWKT());
}

if (IdUri != null)
{
sb.Append(IdUri.ToWKT());
}

sb.Append("]");

return sb.ToString();
}
}
}
Loading

0 comments on commit 9157e53

Please sign in to comment.