Fix native map services and add provider selection
This commit is contained in:
1 parent
56211e4b25
commit
3ea51a6842
9 files changed
+1408
-129
No files matched your search
@@ -0,0 +1,85 @@
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace LMEMappeCatastaliApp.Services;
|
||||
|
||||
public sealed class OfficialCadastreService
|
||||
{
|
||||
private const string WfsEndpoint = "https://wfs.cartografia.agenziaentrate.gov.it/inspire/wfs/owfs01.php";
|
||||
private readonly HttpClient _httpClient = new()
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(30)
|
||||
};
|
||||
|
||||
public OfficialCadastreService()
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("LMEMappeCatastali/0.2");
|
||||
_httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/gml+xml");
|
||||
}
|
||||
|
||||
public async Task<string> GetParcelsNearAsync(
|
||||
double latitude,
|
||||
double longitude,
|
||||
double radiusMeters,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var meters = Math.Clamp(radiusMeters, 2, 30);
|
||||
var deltaLatitude = meters / 111_320d;
|
||||
var longitudeScale = Math.Cos(latitude * Math.PI / 180d);
|
||||
var deltaLongitude = meters / (111_320d * Math.Max(0.1, longitudeScale));
|
||||
var bbox = string.Join(",",
|
||||
[
|
||||
Format(latitude - deltaLatitude),
|
||||
Format(longitude - deltaLongitude),
|
||||
Format(latitude + deltaLatitude),
|
||||
Format(longitude + deltaLongitude)
|
||||
]);
|
||||
|
||||
var query = new Dictionary<string, string>
|
||||
{
|
||||
["language"] = "ita",
|
||||
["SERVICE"] = "WFS",
|
||||
["VERSION"] = "2.0.0",
|
||||
["TYPENAMES"] = "CP:CadastralParcel",
|
||||
["SRSNAME"] = "urn:ogc:def:crs:EPSG::6706",
|
||||
["BBOX"] = bbox,
|
||||
["REQUEST"] = "GetFeature",
|
||||
["COUNT"] = "20"
|
||||
};
|
||||
|
||||
var url = WfsEndpoint + "?" + string.Join("&", query.Select(item =>
|
||||
$"{Uri.EscapeDataString(item.Key)}={Uri.EscapeDataString(item.Value)}"));
|
||||
|
||||
using var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseContentRead, cancellationToken);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new HttpRequestException($"Il servizio WFS AdE ha risposto {((int)response.StatusCode)}.");
|
||||
}
|
||||
|
||||
var xml = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
ThrowIfExceptionReport(xml);
|
||||
return xml;
|
||||
}
|
||||
|
||||
private static string Format(double value) => value.ToString("R", CultureInfo.InvariantCulture);
|
||||
|
||||
private static void ThrowIfExceptionReport(string xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
var document = XDocument.Parse(xml);
|
||||
var exceptionText = document.Descendants()
|
||||
.FirstOrDefault(element => element.Name.LocalName == "ExceptionText")
|
||||
?.Value
|
||||
.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(exceptionText))
|
||||
{
|
||||
throw new InvalidOperationException($"Servizio WFS AdE: {exceptionText}");
|
||||
}
|
||||
}
|
||||
catch (System.Xml.XmlException error)
|
||||
{
|
||||
throw new InvalidDataException("Il servizio WFS AdE ha restituito una risposta non valida.", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user