Skip to content

Commit

Permalink
Adding deserialization of coordinates for points, linestrings and mul…
Browse files Browse the repository at this point in the history
…tipoint
  • Loading branch information
arnaudleclerc committed Apr 9, 2021
1 parent 5edb696 commit 40bbc77
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 29 deletions.
152 changes: 143 additions & 9 deletions src/AzureMapsControl.Components/Atlas/Geometry.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
namespace AzureMapsControl.Components.Atlas
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

[ExcludeFromCodeCoverage]
[JsonConverter(typeof(GeometryJsonConverter))]
public abstract class Geometry
{
internal string Id { get; set; }

internal string Type { get; set; }
internal string GeometryType { get; set; }

public string Type => GeometryType;

public Geometry() { }
}
Expand All @@ -22,11 +27,138 @@ public abstract class Geometry<TPosition> : Geometry

public Geometry() : base() { }

internal Geometry(string type) : this() => Type = type;
internal Geometry(string type) : this() => GeometryType = type;

internal Geometry(TPosition coordinates, string type) : this(type) => Coordinates = coordinates;
}

internal class GeometryJsonConverter : JsonConverter<Geometry>
{
public override Geometry Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var originalDepth = reader.CurrentDepth;

string type = null;
dynamic coordinates = null;

while (reader.TokenType != JsonTokenType.EndObject || originalDepth != reader.CurrentDepth)
{
reader.Read();

if (reader.TokenType == JsonTokenType.PropertyName && reader.GetString() == "type")
{
reader.Read();
type = reader.GetString();
Console.WriteLine(type);
}

if (reader.TokenType == JsonTokenType.PropertyName && reader.GetString() == "coordinates")
{
coordinates = ReadCoordinates(ref reader);
}

}

return type switch {
Point.InnerGeometryType => new Point(coordinates),
LineString.InnerGeometryType => new LineString(coordinates),
MultiLineString.InnerGeometryType => new MultiLineString(coordinates),
MultiPoint.InnerGeometryType => new MultiPoint(coordinates),
MultiPolygon.InnerGeometryType => new MultiPolygon(coordinates),
Polygon.InnerGeometryType => new Polygon(coordinates),
_ => default
};
}

public override void Write(Utf8JsonWriter writer, Geometry value, JsonSerializerOptions options) => throw new NotImplementedException();

internal dynamic ReadCoordinates(ref Utf8JsonReader reader)
{
var startDepth = reader.CurrentDepth;
Console.WriteLine($"1 - Reading coordinates at depth {startDepth}");
dynamic result = null;
do
{
Console.WriteLine($"2 - Reading depth {reader.CurrentDepth}");
reader.Read();
Console.WriteLine(reader.TokenType);
Console.WriteLine(reader.CurrentDepth);

if (reader.TokenType == JsonTokenType.StartArray)
{
result = ReadCoordinatesArray(ref reader, startDepth);
}
}
while (reader.TokenType != JsonTokenType.EndArray && startDepth != reader.CurrentDepth);
return result;
}

private dynamic ReadCoordinatesArray(ref Utf8JsonReader reader, int startDepth)
{
dynamic result = null;
Console.WriteLine($"3 - Found array at depth {reader.CurrentDepth}");
reader.Read();
Console.WriteLine(reader.TokenType);
Console.WriteLine(reader.CurrentDepth);

if (reader.TokenType == JsonTokenType.StartArray)
{
result = ReadCoordinatesArray(ref reader, startDepth);
}
else if (reader.TokenType == JsonTokenType.Number)
{
Console.WriteLine($"4 - Found number at depth {reader.CurrentDepth}");
if (reader.CurrentDepth == startDepth + 1)
{
Console.WriteLine("Point case");
result = ReadPosition(ref reader);
}
else if (reader.CurrentDepth == startDepth + 2)
{
Console.WriteLine("LineString and multipoint case");
result = new List<Position>();

do
{
Console.WriteLine("Adding position to line string or multi point");

if (reader.TokenType == JsonTokenType.StartArray)
{
Console.WriteLine("5");
reader.Read();
Console.WriteLine(reader.TokenType);
Console.WriteLine(reader.CurrentDepth);
}

result.Add(ReadPosition(ref reader));

Console.WriteLine("6");
reader.Read();
Console.WriteLine(reader.TokenType);
Console.WriteLine(reader.CurrentDepth);
} while (reader.TokenType == JsonTokenType.StartArray && reader.CurrentDepth == startDepth + 1);
}
}

return result;
}

private Position ReadPosition(ref Utf8JsonReader reader)
{
var result = new Position();
result.Longitude = reader.GetDouble();
reader.Read();
result.Latitude = reader.GetDouble();
reader.Read();
if (reader.TokenType == JsonTokenType.Number)
{
result.Elevation = reader.GetInt32();
reader.Read();
}
return result;
}
}

internal class GeometryJsonConverter<TGeometry> : JsonConverter<TGeometry> where TGeometry : Geometry, new()
{
public GeometryJsonConverter() { }
Expand All @@ -39,15 +171,17 @@ public override TGeometry Read(ref Utf8JsonReader reader, Type typeToConvert, Js

while (reader.TokenType != JsonTokenType.EndObject || originalDepth != reader.CurrentDepth)
{
reader.Read();
if (reader.TokenType == JsonTokenType.PropertyName && reader.GetString() == "type")
{
reader.Read();
type = reader.GetString();
Console.WriteLine(type);
}
}

var geometry = new TGeometry {
Type = type
GeometryType = type
};
return geometry;
}
Expand All @@ -58,22 +192,22 @@ public override void Write(Utf8JsonWriter writer, TGeometry value, JsonSerialize
writer.WriteString("type", value.Type);
switch (value.Type)
{
case Point.GeometryType:
case Point.InnerGeometryType:
WritePoint(writer, value as Point);
break;
case LineString.GeometryType:
case LineString.InnerGeometryType:
WriteLineString(writer, value as LineString);
break;
case MultiLineString.GeometryType:
case MultiLineString.InnerGeometryType:
WriteMultiLineString(writer, value as MultiLineString);
break;
case MultiPoint.GeometryType:
case MultiPoint.InnerGeometryType:
WriteMultiPoint(writer, value as MultiPoint);
break;
case MultiPolygon.GeometryType:
case MultiPolygon.InnerGeometryType:
WriteMultiPolygon(writer, value as MultiPolygon);
break;
case Polygon.GeometryType:
case Polygon.InnerGeometryType:
WritePolygon(writer, value as Polygon);
break;
}
Expand Down
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/LineString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
[JsonConverter(typeof(GeometryJsonConverter<LineString>))]
public sealed class LineString : Geometry<IEnumerable<Position>>
{
internal const string GeometryType = "LineString";
internal const string InnerGeometryType = "LineString";

public BoundingBox BBox { get; set; }

public LineString() : base(GeometryType) { }
public LineString() : base(InnerGeometryType) { }

public LineString(IEnumerable<Position> coordinates) : base(coordinates, GeometryType) { }
public LineString(IEnumerable<Position> coordinates) : base(coordinates, InnerGeometryType) { }

public LineString(IEnumerable<Position> coordinates, BoundingBox bbox) : this(coordinates) => BBox = bbox;
}
Expand Down
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/MultiLineString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
[JsonConverter(typeof(GeometryJsonConverter<MultiLineString>))]
public sealed class MultiLineString : Geometry<IEnumerable<IEnumerable<Position>>>
{
internal const string GeometryType = "MultiLineString";
internal const string InnerGeometryType = "MultiLineString";
public BoundingBox BBox { get; set; }
public MultiLineString() : base(GeometryType) { }
public MultiLineString(IEnumerable<IEnumerable<Position>> coordinates) : base(coordinates, GeometryType) { }
public MultiLineString() : base(InnerGeometryType) { }
public MultiLineString(IEnumerable<IEnumerable<Position>> coordinates) : base(coordinates, InnerGeometryType) { }

public MultiLineString(IEnumerable<IEnumerable<Position>> coordinates, BoundingBox bbox) : this(coordinates) => BBox = bbox;
}
Expand Down
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/MultiPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
[JsonConverter(typeof(GeometryJsonConverter<MultiPoint>))]
public sealed class MultiPoint : Geometry<IEnumerable<Position>>
{
internal const string GeometryType = "MultiPoint";
internal const string InnerGeometryType = "MultiPoint";
public BoundingBox BBox { get; set; }

public MultiPoint() : base(GeometryType) { }
public MultiPoint() : base(InnerGeometryType) { }

public MultiPoint(IEnumerable<Position> coordinates) : base(coordinates, GeometryType) { }
public MultiPoint(IEnumerable<Position> coordinates) : base(coordinates, InnerGeometryType) { }

public MultiPoint(IEnumerable<Position> coordinates, BoundingBox bbox) : this(coordinates) => BBox = bbox;
}
Expand Down
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/MultiPolygon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
[JsonConverter(typeof(GeometryJsonConverter<MultiPolygon>))]
public sealed class MultiPolygon : Geometry<IEnumerable<IEnumerable<IEnumerable<Position>>>>
{
internal const string GeometryType = "MultiPolygon";
internal const string InnerGeometryType = "MultiPolygon";
public BoundingBox BBox { get; set; }
public MultiPolygon() : base(GeometryType) { }
public MultiPolygon(IEnumerable<IEnumerable<IEnumerable<Position>>> coordinates) : base(coordinates, GeometryType) { }
public MultiPolygon() : base(InnerGeometryType) { }
public MultiPolygon(IEnumerable<IEnumerable<IEnumerable<Position>>> coordinates) : base(coordinates, InnerGeometryType) { }
public MultiPolygon(IEnumerable<IEnumerable<IEnumerable<Position>>> coordinates, BoundingBox bbox) : this(coordinates) => BBox = bbox;
}
}
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
[JsonConverter(typeof(GeometryJsonConverter<Point>))]
public class Point : Geometry<Position>
{
internal const string GeometryType = "Point";
public Point() : base(GeometryType) { }
internal const string InnerGeometryType = "Point";
public Point() : base(InnerGeometryType) { }

public Point(Position coordinates) : base(coordinates, GeometryType) { }
public Point(Position coordinates) : base(coordinates, InnerGeometryType) { }
}
}
6 changes: 3 additions & 3 deletions src/AzureMapsControl.Components/Atlas/Polygon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
[JsonConverter(typeof(GeometryJsonConverter<Polygon>))]
public sealed class Polygon : Geometry<IEnumerable<IEnumerable<Position>>>
{
internal const string GeometryType = "Polygon";
internal const string InnerGeometryType = "Polygon";
public BoundingBox BBox { get; set; }

public Polygon() : base(GeometryType) { }
public Polygon() : base(InnerGeometryType) { }

public Polygon(IEnumerable<IEnumerable<Position>> coordinates) : base(coordinates, GeometryType) { }
public Polygon(IEnumerable<IEnumerable<Position>> coordinates) : base(coordinates, InnerGeometryType) { }

public Polygon(IEnumerable<IEnumerable<Position>> coordinates, BoundingBox bbox) : this(coordinates) => BBox = bbox;
}
Expand Down
5 changes: 4 additions & 1 deletion src/AzureMapsControl.Components/Map/MapMouseEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
public sealed class MapMouseEventArgs : MapEventArgs
{
public string LayerId { get; }
public IEnumerable<Feature> Shapes { get; }
public IEnumerable<Shape<Geometry>> Shapes { get; }
public IEnumerable<Feature<Geometry>> Features { get; }
public Pixel Pixel { get; }
public Position Position { get; }

internal MapMouseEventArgs(Map map, MapJsEventArgs eventArgs) : base(map, eventArgs.Type)
{
Features = eventArgs.Features;
LayerId = eventArgs.LayerId;
Pixel = eventArgs.Pixel;
Position = eventArgs.Position;
Shapes = eventArgs.Shapes;
}
}
}
3 changes: 2 additions & 1 deletion src/AzureMapsControl.Components/Map/MapTouchEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public sealed class MapTouchEventArgs : MapEventArgs
{
public string LayerId { get; }
public IEnumerable<Feature> Shapes { get; }
public IEnumerable<Shape<Geometry>> Shapes { get; }
public Pixel Pixel { get; }
public IEnumerable<Pixel> Pixels { get; }
public Position Position { get; }
Expand All @@ -22,6 +22,7 @@ internal MapTouchEventArgs(Map map, MapJsEventArgs eventArgs) : base(map, eventA
Pixels = eventArgs.Pixels;
Position = eventArgs.Position;
Positions = eventArgs.Positions;
Shapes = eventArgs.Shapes;
}
}
}

0 comments on commit 40bbc77

Please sign in to comment.