forked from PhenX/PhenX.EntityFrameworkCore.BulkInsert
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSqlServerGeometryConverter.cs
More file actions
106 lines (79 loc) · 3.07 KB
/
SqlServerGeometryConverter.cs
File metadata and controls
106 lines (79 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System.Data.SqlTypes;
using Microsoft.SqlServer.Types;
using NetTopologySuite.Geometries;
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
using PhenX.EntityFrameworkCore.BulkInsert.Options;
namespace PhenX.EntityFrameworkCore.BulkInsert.SqlServer;
internal sealed class SqlServerGeometryConverter : IBulkValueConverter
{
public static readonly SqlServerGeometryConverter Instance = new();
private SqlServerGeometryConverter()
{
}
public bool TryConvertValue(object source, BulkInsertOptions options, out object result)
{
if (source is Geometry geometry)
{
var reversed = Reverse(geometry);
result = SqlGeometry.STGeomFromWKB(new SqlBytes(reversed.AsBinary()), options.SRID);
return true;
}
result = source;
return false;
}
private static Geometry Reverse(Geometry input)
{
switch (input)
{
case Point point:
return Reverse(point);
case LineString lineString:
return Reverse(lineString);
case Polygon polygon:
return Reverse(polygon);
case MultiPoint multiPoint:
return Reverse(multiPoint);
case MultiLineString multiLineString:
return Reverse(multiLineString);
case MultiPolygon mpoly:
return Reverse(mpoly);
case GeometryCollection gc:
return Reverse(gc);
default:
throw new NotSupportedException($"Unsupported geometry type: {input.GeometryType}");
}
}
private static Point Reverse(Point input)
{
return input.Factory.CreatePoint(Swap(input.Coordinate));
}
private static LineString Reverse(LineString input)
{
return input.Factory.CreateLineString(Swap(input.Coordinates));
}
private static MultiPoint Reverse(MultiPoint input)
{
return input.Factory.CreateMultiPoint(input.Geometries.OfType<Point>().Select(Reverse).ToArray());
}
private static MultiLineString Reverse(MultiLineString input)
{
return input.Factory.CreateMultiLineString(input.Geometries.OfType<LineString>().Select(Reverse).ToArray());
}
private static MultiPolygon Reverse(MultiPolygon input)
{
return input.Factory.CreateMultiPolygon(input.Geometries.OfType<Polygon>().Select(Reverse).ToArray());
}
private static GeometryCollection Reverse(GeometryCollection input)
{
return input.Factory.CreateGeometryCollection(input.Geometries.Select(Reverse).ToArray());
}
private static Polygon Reverse(Polygon input)
{
var factory = input.Factory;
return input.Factory.CreatePolygon(
factory.CreateLinearRing(Swap(input.Shell.Coordinates)),
input.Holes.Select(h => factory.CreateLinearRing(Swap(h.Coordinates))).ToArray());
}
private static Coordinate Swap(Coordinate c) => new Coordinate(c.Y, c.X);
private static Coordinate[] Swap(Coordinate[] coords) => coords.Select(Swap).ToArray();
}