@@ -22,7 +22,7 @@ public class SqlServerBytesWriter
22
22
{
23
23
private bool _emitZ = true ;
24
24
private bool _emitM = true ;
25
-
25
+
26
26
/// <summary>
27
27
/// Gets or sets the desired <see cref="IO.ByteOrder"/>. Returns <see cref="IO.ByteOrder.LittleEndian"/> since
28
28
/// it's required. Setting does nothing.
@@ -124,6 +124,12 @@ private Geography ToGeography(Geometry geometry)
124
124
return new Geography { SRID = - 1 } ;
125
125
}
126
126
127
+ // Check if geometry has z- or m-ordinate values
128
+ var checkZM = new CheckZMFilter ( ) ;
129
+ geometry . Apply ( checkZM ) ;
130
+ bool emitZ = _emitZ & checkZM . HasZ ;
131
+ bool emitM = _emitM & checkZM . HasM ;
132
+
127
133
var geometries = new Queue < ( Geometry , int ) > ( ) ;
128
134
geometries . Enqueue ( ( geometry , - 1 ) ) ;
129
135
@@ -140,7 +146,6 @@ private Geography ToGeography(Geometry geometry)
140
146
141
147
int figureOffset = geography . Figures . Count ;
142
148
bool figureAdded = false ;
143
-
144
149
switch ( currentGeometry )
145
150
{
146
151
case Point point :
@@ -193,25 +198,30 @@ private Geography ToGeography(Geometry geometry)
193
198
194
199
bool addFigure ( Geometry g , FigureAttribute figureAttribute )
195
200
{
201
+ CoordinateSequence sequence ;
202
+ if ( g is Point p ) sequence = p . CoordinateSequence ;
203
+ else if ( g is LineString l ) sequence = l . CoordinateSequence ;
204
+ else throw new ArgumentException ( "Unexpected geometry type" , nameof ( g ) ) ;
205
+
196
206
int pointOffset = geography . Points . Count ;
197
207
bool pointsAdded = false ;
198
208
199
- foreach ( var coordinate in g . Coordinates )
209
+ for ( int i = 0 ; i < sequence . Count ; i ++ )
200
210
{
201
211
geography . Points . Add (
202
212
IsGeography
203
- ? new SqlPoint { Long = coordinate . X , Lat = coordinate . Y }
204
- : new SqlPoint { X = coordinate . X , Y = coordinate . Y } ) ;
213
+ ? new SqlPoint { Long = sequence . GetX ( i ) , Lat = sequence . GetY ( i ) }
214
+ : new SqlPoint { X = sequence . GetX ( i ) , Y = sequence . GetY ( i ) } ) ;
205
215
pointsAdded = true ;
206
216
207
- if ( _emitZ )
217
+ if ( emitZ )
208
218
{
209
- geography . ZValues . Add ( coordinate . Z ) ;
219
+ geography . ZValues . Add ( sequence . GetZ ( i ) ) ;
210
220
}
211
221
212
- if ( _emitM )
222
+ if ( emitM )
213
223
{
214
- geography . MValues . Add ( coordinate . M ) ;
224
+ geography . MValues . Add ( sequence . GetM ( i ) ) ;
215
225
}
216
226
}
217
227
@@ -231,16 +241,6 @@ bool addFigure(Geometry g, FigureAttribute figureAttribute)
231
241
}
232
242
}
233
243
234
- if ( geography . ZValues . All ( double . IsNaN ) )
235
- {
236
- geography . ZValues . Clear ( ) ;
237
- }
238
-
239
- if ( geography . MValues . All ( double . IsNaN ) )
240
- {
241
- geography . MValues . Clear ( ) ;
242
- }
243
-
244
244
return geography ;
245
245
}
246
246
@@ -254,5 +254,43 @@ private OpenGisType ToOpenGisType(OgcGeometryType type)
254
254
255
255
return ( OpenGisType ) type ;
256
256
}
257
+
258
+ /// <summary>
259
+ /// Filter class to evaluate if a geometry has z- and m-ordinate values.
260
+ /// </summary>
261
+ /// <remarks>Used <c>IGeometryComponentFilter</c> because <c>IEntireCoordinateSequence</c> is not available in NTS v2.0</remarks>
262
+ private class CheckZMFilter : IGeometryComponentFilter
263
+ {
264
+ /// <summary>
265
+ /// Geometry has z-ordinate values
266
+ /// </summary>
267
+ public bool HasZ { get ; private set ; }
268
+
269
+ /// <summary>
270
+ /// Geometry has m-ordinate values
271
+ /// </summary>
272
+ public bool HasM { get ; private set ; }
273
+
274
+ void IGeometryComponentFilter . Filter ( Geometry geom )
275
+ {
276
+ CoordinateSequence seq = null ;
277
+ switch ( geom )
278
+ {
279
+ case Point p :
280
+ seq = p . CoordinateSequence ;
281
+ break ;
282
+ case LineString ls :
283
+ seq = ls . CoordinateSequence ;
284
+ break ;
285
+ }
286
+
287
+ // If we don't have a sequence we don't have anything to evaluate
288
+ if ( seq == null ) return ;
289
+
290
+ // Update properties
291
+ if ( seq . HasZ ) HasZ = true ;
292
+ if ( seq . HasM ) HasM = true ;
293
+ }
294
+ }
257
295
}
258
296
}
0 commit comments