Add mapped Pro fiducial point layer
This commit is contained in:
1 parent
7b642afe2d
commit
85e1c93d8a
4 files changed
+360
-19
No files matched your search
@@ -1,5 +1,6 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace LMEMappeCatastaliApp.Services;
|
||||
@@ -7,6 +8,7 @@ namespace LMEMappeCatastaliApp.Services;
|
||||
public sealed partial class FiducialPointService
|
||||
{
|
||||
private const string ServiceBaseUrl = "https://www1.agenziaentrate.gov.it/servizi/Monografie/";
|
||||
private const string MappedPointsUrl = "https://cartografia.globogis.it/arcgis/rest/services/fiduciali/Punti_fiduciali/MapServer/2/query";
|
||||
private readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(30) };
|
||||
|
||||
public FiducialPointService()
|
||||
@@ -77,6 +79,105 @@ public sealed partial class FiducialPointService
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<MappedFiducialPoint>> GetMappedFiducialsAsync(
|
||||
string municipalityCode,
|
||||
string sheet,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var municipality = NormalizeCode(municipalityCode);
|
||||
if (!int.TryParse(new string(sheet.Where(char.IsDigit).ToArray()), out var sheetNumber))
|
||||
{
|
||||
throw new ArgumentException("Numero di foglio non valido.", nameof(sheet));
|
||||
}
|
||||
|
||||
var query = new Dictionary<string, string>
|
||||
{
|
||||
["f"] = "json",
|
||||
["where"] = $"COMUNENAZI='{municipality}' AND FOGLIO={sheetNumber}",
|
||||
["outFields"] = "ETICHETTA,PARTICELLA,NORD,EST,ATTENDIBIL,QUOTA,DATAAGGIOR,IDORIGINE,URL_AGENZI,FOGLIO,ALLEGATO,FIDUCIALE",
|
||||
["returnGeometry"] = "true",
|
||||
["outSR"] = "3857",
|
||||
["resultRecordCount"] = "500"
|
||||
};
|
||||
var url = $"{MappedPointsUrl}?{string.Join('&', query.Select(item => $"{item.Key}={Uri.EscapeDataString(item.Value)}"))}";
|
||||
using var response = await _httpClient.GetAsync(url, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken);
|
||||
using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken);
|
||||
if (document.RootElement.TryGetProperty("error", out var error))
|
||||
{
|
||||
throw new InvalidOperationException(error.TryGetProperty("message", out var message)
|
||||
? message.GetString()
|
||||
: "Servizio cartografico PF non disponibile.");
|
||||
}
|
||||
|
||||
if (!document.RootElement.TryGetProperty("features", out var features))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return features.EnumerateArray()
|
||||
.Select(feature => ParseMappedPoint(feature, municipality))
|
||||
.Where(point => point is not null)
|
||||
.Cast<MappedFiducialPoint>()
|
||||
.DistinctBy(point => point.Identifier, StringComparer.OrdinalIgnoreCase)
|
||||
.OrderBy(point => point.Identifier, StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static MappedFiducialPoint? ParseMappedPoint(JsonElement feature, string municipalityCode)
|
||||
{
|
||||
if (!feature.TryGetProperty("geometry", out var geometry)
|
||||
|| !TryGetDouble(geometry, "x", out var x)
|
||||
|| !TryGetDouble(geometry, "y", out var y))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var attributes = feature.GetProperty("attributes");
|
||||
var label = GetString(attributes, "ETICHETTA");
|
||||
var identifier = FormatIdentifier(label);
|
||||
if (identifier == label)
|
||||
{
|
||||
var sheet = GetString(attributes, "FOGLIO").PadLeft(4, '0');
|
||||
var number = GetString(attributes, "FIDUCIALE").PadLeft(2, '0');
|
||||
identifier = $"PF{number}/{sheet}/{municipalityCode}";
|
||||
}
|
||||
|
||||
const double earthRadius = 6378137d;
|
||||
var longitude = x / earthRadius * 180d / Math.PI;
|
||||
var latitude = (2d * Math.Atan(Math.Exp(y / earthRadius)) - Math.PI / 2d) * 180d / Math.PI;
|
||||
return new MappedFiducialPoint(
|
||||
identifier,
|
||||
latitude,
|
||||
longitude,
|
||||
GetNullableDouble(attributes, "NORD"),
|
||||
GetNullableDouble(attributes, "EST"),
|
||||
GetString(attributes, "ATTENDIBIL"),
|
||||
GetNullableDouble(attributes, "QUOTA"),
|
||||
GetString(attributes, "PARTICELLA"),
|
||||
GetString(attributes, "DATAAGGIOR"),
|
||||
GetString(attributes, "IDORIGINE"));
|
||||
}
|
||||
|
||||
private static bool TryGetDouble(JsonElement element, string name, out double value)
|
||||
{
|
||||
value = 0;
|
||||
return element.TryGetProperty(name, out var property)
|
||||
&& (property.ValueKind == JsonValueKind.Number
|
||||
? property.TryGetDouble(out value)
|
||||
: double.TryParse(property.ToString(), System.Globalization.NumberStyles.Float,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out value));
|
||||
}
|
||||
|
||||
private static double? GetNullableDouble(JsonElement element, string name) =>
|
||||
TryGetDouble(element, name, out var value) ? value : null;
|
||||
|
||||
private static string GetString(JsonElement element, string name) =>
|
||||
element.TryGetProperty(name, out var property) && property.ValueKind != JsonValueKind.Null
|
||||
? property.ToString().Trim()
|
||||
: string.Empty;
|
||||
|
||||
private async Task<string> GetHtmlAsync(string relativeUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
using var response = await _httpClient.GetAsync(ServiceBaseUrl + relativeUrl, cancellationToken);
|
||||
@@ -146,3 +247,16 @@ public sealed partial class FiducialPointService
|
||||
public sealed record FiducialAreaOption(string Code, string Name);
|
||||
|
||||
public sealed record FiducialPointEntry(string Identifier, string MonographUrl);
|
||||
|
||||
public sealed record MappedFiducialPoint(
|
||||
string Identifier,
|
||||
double Latitude,
|
||||
double Longitude,
|
||||
double? CadastralNorth,
|
||||
double? CadastralEast,
|
||||
string Reliability,
|
||||
double? Elevation,
|
||||
string Parcel,
|
||||
string UpdatedAt,
|
||||
string OriginId,
|
||||
string MonographUrl = "");
|
||||
Reference in new issue
Block a user