-
Notifications
You must be signed in to change notification settings - Fork 533
Expand file tree
/
Copy pathCrsSTJConverter.cs
More file actions
128 lines (115 loc) · 5.34 KB
/
CrsSTJConverter.cs
File metadata and controls
128 lines (115 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------
namespace Microsoft.Azure.Cosmos.Spatial.Converters.STJConverters
{
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Azure.Documents;
/// <summary>
/// Converter used to support System.Text.Json serialization/deserialization of Crs (Coordinate Reference System).
/// Handles NamedCrs, LinkedCrs, and Unspecified CRS types.
/// Ensures output format matches Newtonsoft.Json exactly.
/// </summary>
internal sealed class CrsSTJConverter : JsonConverter<Crs>
{
public override bool HandleNull => true;
/// <summary>
/// Deserializes a CRS from JSON.
/// Supports named CRS (e.g., EPSG:4326) and linked CRS with optional type.
/// Returns Crs.Unspecified for null values.
/// </summary>
public override Crs Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return Crs.Unspecified;
}
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException(RMResources.JsonUnexpectedToken);
}
JsonElement rootElement = JsonDocument.ParseValue(ref reader).RootElement;
if (!rootElement.TryGetProperty(STJMetaDataFields.Properties, out JsonElement properties) || (properties.ValueKind != JsonValueKind.Object))
{
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
if (!rootElement.TryGetProperty(STJMetaDataFields.Type, out JsonElement crsType) || crsType.ValueKind != JsonValueKind.String)
{
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
switch (crsType.GetString())
{
case "name":
if (!properties.TryGetProperty(STJMetaDataFields.Name, out JsonElement crsName) || crsName.ValueKind != JsonValueKind.String)
{
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
return new NamedCrs(crsName.GetString());
case "link":
if (!properties.TryGetProperty(STJMetaDataFields.Href, out JsonElement crsHref) || crsHref.ValueKind != JsonValueKind.String)
{
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
if (properties.TryGetProperty(STJMetaDataFields.Type, out JsonElement crsHrefType))
{
if (crsHrefType.ValueKind != JsonValueKind.String)
{
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
return new LinkedCrs(crsHref.GetString(), crsHrefType.GetString());
}
return new LinkedCrs(crsHref.GetString());
default:
throw new JsonException(RMResources.SpatialFailedToDeserializeCrs);
}
}
/// <summary>
/// Serializes a CRS to JSON.
/// Outputs different JSON structures based on CRS type (Named, Linked, or Unspecified).
/// </summary>
public override void Write(Utf8JsonWriter writer, Crs crs, JsonSerializerOptions options)
{
if (crs == null)
{
writer.WriteNullValue();
return;
}
switch (crs.Type)
{
case CrsType.Linked:
{
writer.WriteStartObject();
LinkedCrs linkedCrs = (LinkedCrs)crs;
writer.WriteString(STJMetaDataFields.Type, "link");
writer.WritePropertyName(STJMetaDataFields.Properties);
writer.WriteStartObject();
writer.WriteString(STJMetaDataFields.Href, linkedCrs.Href);
if (linkedCrs.HrefType != null)
{
writer.WriteString(STJMetaDataFields.Type, linkedCrs.HrefType);
}
writer.WriteEndObject();
writer.WriteEndObject();
break;
}
case CrsType.Named:
{
writer.WriteStartObject();
NamedCrs namedCrs = (NamedCrs)crs;
writer.WriteString(STJMetaDataFields.Type, "name");
writer.WritePropertyName(STJMetaDataFields.Properties);
writer.WriteStartObject();
writer.WriteString(STJMetaDataFields.Name, namedCrs.Name);
writer.WriteEndObject();
writer.WriteEndObject();
break;
}
case CrsType.Unspecified:
writer.WriteNullValue();
break;
}
}
}
}