summaryrefslogtreecommitdiffstats
path: root/src/Cepis/Geo.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cepis/Geo.cs')
-rw-r--r--src/Cepis/Geo.cs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/Cepis/Geo.cs b/src/Cepis/Geo.cs
new file mode 100644
index 0000000..75dfa8b
--- /dev/null
+++ b/src/Cepis/Geo.cs
@@ -0,0 +1,67 @@
+using System.Text.Json.Serialization;
+
+namespace Cepis;
+
+/// <summary>
+/// The CEP's coordinate, when the database has one.
+/// </summary>
+/// <remarks>
+/// <para>
+/// The point is the <b>median</b> of the coordinates of that CEP's addresses,
+/// not the mean: one badly geocoded address 40 km away shifts a mean and does
+/// not move a median.
+/// </para>
+/// <para>
+/// Always check <see cref="Precisao"/> before using <see cref="Lat"/> and
+/// <see cref="Lon"/> for distance. <c>"logradouro"</c> means the point is a
+/// stretch of street and <see cref="RaioM"/> lands around 100–150 m — good for
+/// maps and for distance. <c>"localidade"</c> means the CEP <i>is</i> the whole
+/// municipality (a city-wide general CEP) and the point is its centroid, with
+/// <see cref="RaioM"/> running from 7 km to 40 km; computing shipping from that
+/// is wrong by tens of kilometres.
+/// </para>
+/// <para>
+/// <see cref="RaioM"/> is the radius containing 90% of that CEP's addresses. It
+/// exists precisely so that error cannot pass unnoticed.
+/// </para>
+/// <para>
+/// The property names are the API's own, with only the casing adapted:
+/// <c>lat</c>, <c>lon</c>, <c>raio_m</c> and <c>precisao</c> on the wire.
+/// </para>
+/// </remarks>
+public sealed record Geo
+{
+ /// <summary>Latitude in decimal degrees, WGS 84. Wire name <c>lat</c>.</summary>
+ [JsonPropertyName("lat")]
+ public double Lat { get; init; }
+
+ /// <summary>Longitude in decimal degrees, WGS 84. Wire name <c>lon</c>.</summary>
+ [JsonPropertyName("lon")]
+ public double Lon { get; init; }
+
+ /// <summary>
+ /// The radius, in metres, containing 90% of that CEP's addresses. Wire name
+ /// <c>raio_m</c>.
+ /// </summary>
+ [JsonPropertyName("raio_m")]
+ public int RaioM { get; init; }
+
+ /// <summary>
+ /// What the point describes: <c>"logradouro"</c> for a stretch of street,
+ /// <c>"localidade"</c> for a municipality centroid. Wire name
+ /// <c>precisao</c>.
+ /// </summary>
+ [JsonPropertyName("precisao")]
+ public string Precisao { get; init; } = "";
+
+ /// <summary>
+ /// <see langword="true"/> when the coordinate points at a street rather than
+ /// a municipality.
+ /// </summary>
+ /// <remarks>
+ /// Shorthand for <c>Precisao == "logradouro"</c>, which is the check to make
+ /// before using the point to measure distance.
+ /// </remarks>
+ [JsonIgnore]
+ public bool IsPrecise => Precisao == "logradouro";
+}