using NetTopologySuite.Geometries; using NetTopologySuite.IO; namespace uWine.Core.Infrastructure.Helpers { public class CoordinatesHelper { public static string ToWktPolygon(Dictionary coordinatesDict) { if (coordinatesDict == null || !coordinatesDict.Any()) { throw new ArgumentException("Il dictionary di coordinate non può essere nullo o vuoto."); } // Ordina le coordinate in base alla chiave (indice) var orderedCoordinates = coordinatesDict.OrderBy(kv => kv.Key) .Select(kv => kv.Value) .ToList(); // Costruisci la stringa dei punti "longitude latitude" // Ricorda che i sistemi GIS spesso usano (longitude, latitude) ovvero (x, y) var points = orderedCoordinates.Select(c => $"{c.Longitude} {c.Latitude}"); // Aggiungi il primo punto alla fine per chiudere il poligono var firstPoint = orderedCoordinates.First(); var closedPoints = string.Join(",", points) + $",{firstPoint.Longitude} {firstPoint.Latitude}"; return $"POLYGON(({closedPoints}))"; } public static Dictionary WktPolygonToDictionary(string wktPolygon) { if (string.IsNullOrWhiteSpace(wktPolygon)) { throw new ArgumentException("La stringa WKT del poligono non può essere nulla o vuota."); } var reader = new WKTReader(); NetTopologySuite.Geometries.Geometry geometry = reader.Read(wktPolygon); if (!(geometry is Polygon polygon)) { throw new ArgumentException("La stringa WKT non rappresenta un poligono valido."); } var coordinatesDict = new Dictionary(); var points = polygon.ExteriorRing.Coordinates; // Ottieni i punti dell'anello esterno // Nota: i poligoni WKT ripetono il primo punto alla fine per chiudere. // Dobbiamo escludere l'ultimo punto se è identico al primo per non duplicarlo nel dictionary, // a meno che tu non voglia mantenere anche il punto di chiusura. int count = points.Length; if (count > 0 && points[0].Equals2D(points[count - 1])) { count--; // Escludi l'ultimo punto se è una duplicazione del primo } for (int i = 0; i < count; i++) { // Ricorda che NetTopologySuite usa (X, Y) che corrispondono a (Longitude, Latitude) per WGS84 coordinatesDict.Add(i, new Domain.Entities.Coordinates(points[i].Y, points[i].X )); } return coordinatesDict; } } }