93 lines
3.5 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
}
|