2026-03-06 15:22:02 +01:00

93 lines
3.5 KiB
C#

using Manager.DTOs;
using NetTopologySuite;
using NetTopologySuite.Geometries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace ManagerService.Helpers
{
public static class GeometryMapper
{
public static GeometryDTO ToDto(this Geometry geometry)
{
return geometry switch
{
Point point => new GeometryDTO
{
type = "Point",
coordinates = new List<double> { point.X, point.Y }
},
LineString line => new GeometryDTO
{
type = "LineString",
coordinates = line.Coordinates
.Select(coord => new List<double> { coord.X, coord.Y })
.ToList()
},
Polygon polygon => new GeometryDTO
{
type = "Polygon",
coordinates = new List<List<List<double>>>
{
polygon.ExteriorRing.Coordinates
.Select(coord => new List<double> { coord.X, coord.Y })
.ToList()
}
},
_ => throw new NotSupportedException($"Geometry type {geometry.GeometryType} not supported.")
};
}
public static Geometry FromDto(this GeometryDTO dto, GeometryFactory factory = null!)
{
factory ??= NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
return dto.type switch
{
"Point" => CreatePoint(dto, factory),
"LineString" => CreateLineString(dto, factory),
"Polygon" => CreatePolygon(dto, factory),
_ => throw new NotSupportedException($"DTO type {dto.type} not supported.")
};
}
private static T DeserializeCoordinates<T>(object coordinates)
{
if (coordinates is JsonElement jsonElement)
return jsonElement.Deserialize<T>();
// Newtonsoft JToken (JArray etc.) — convert via JSON string
var json = JsonConvert.SerializeObject(coordinates);
return System.Text.Json.JsonSerializer.Deserialize<T>(json);
}
private static Point CreatePoint(GeometryDTO dto, GeometryFactory factory)
{
var coords = DeserializeCoordinates<List<double>>(dto.coordinates);
return factory.CreatePoint(new CoordinateZ(coords[0], coords[1], 0.0));
}
private static LineString CreateLineString(GeometryDTO dto, GeometryFactory factory)
{
var coords = DeserializeCoordinates<List<List<double>>>(dto.coordinates);
var coordinates = coords.Select(c => new CoordinateZ(c[0], c[1], 0.0)).ToArray();
return factory.CreateLineString(coordinates);
}
private static Polygon CreatePolygon(GeometryDTO dto, GeometryFactory factory)
{
var rings = DeserializeCoordinates<List<List<List<double>>>>(dto.coordinates);
var exterior = rings.First().Select(c => new CoordinateZ(c[0], c[1], 0.0)).ToArray();
// NTS requires closed rings
if (exterior.Length > 0 && !exterior.First().Equals2D(exterior.Last()))
exterior = exterior.Append(exterior.First()).ToArray();
return factory.CreatePolygon(exterior);
}
}
}