@@ -19,93 +19,93 @@ public static IGeometryObject Decode(byte[] wkb)
19
19
return ParseShape ( wkb , ref v_pos ) ;
20
20
}
21
21
22
- private static Point ParsePoint ( byte [ ] wkb , ref int wkbPosition )
22
+ private static Point ParsePoint ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
23
23
{
24
24
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
25
25
26
- CheckType ( WkbGeometryType . Point , wkbGeometryType ) ;
26
+ CheckBaseType ( WkbGeometryType . Point , wkbGeometryType ) ;
27
27
28
- Position geographicalPosition = GetGeographicPosition ( wkb , ref wkbPosition ) ;
28
+ Position geographicalPosition = GetGeographicPosition ( wkb , ref wkbPosition , hasAltitude ) ;
29
29
30
30
return new Point ( geographicalPosition ) ;
31
31
}
32
32
33
- private static LineString ParseLineString ( byte [ ] wkb , ref int wkbPosition )
33
+ private static LineString ParseLineString ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
34
34
{
35
35
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
36
36
37
- CheckType ( WkbGeometryType . LineString , wkbGeometryType ) ;
37
+ CheckBaseType ( WkbGeometryType . LineString , wkbGeometryType ) ;
38
38
39
- Position [ ] positions = ParsePositions ( wkb , ref wkbPosition ) ;
39
+ Position [ ] positions = ParsePositions ( wkb , ref wkbPosition , hasAltitude ) ;
40
40
41
41
return new LineString ( positions ) ;
42
42
}
43
43
44
- private static Polygon ParsePolygon ( byte [ ] wkb , ref int wkbPosition )
44
+ private static Polygon ParsePolygon ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
45
45
{
46
46
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
47
47
48
- CheckType ( WkbGeometryType . Polygon , wkbGeometryType ) ;
48
+ CheckBaseType ( WkbGeometryType . Polygon , wkbGeometryType ) ;
49
49
50
50
var numberOfLines = GetUInt32 ( wkb , ref wkbPosition ) ;
51
51
var lines = new List < LineString > ( ) ;
52
52
53
53
for ( var v_ls = 0 ; v_ls < numberOfLines ; ++ v_ls )
54
54
{
55
- Position [ ] positions = ParsePositions ( wkb , ref wkbPosition ) ;
55
+ Position [ ] positions = ParsePositions ( wkb , ref wkbPosition , hasAltitude ) ;
56
56
57
57
lines . Add ( new LineString ( positions ) ) ;
58
58
}
59
59
60
60
return new Polygon ( lines ) ;
61
61
}
62
62
63
- private static MultiPoint ParseMultiPoint ( byte [ ] wkb , ref int wkbPosition )
63
+ private static MultiPoint ParseMultiPoint ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
64
64
{
65
65
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
66
66
67
- CheckType ( WkbGeometryType . MultiPoint , wkbGeometryType ) ;
67
+ CheckBaseType ( WkbGeometryType . MultiPoint , wkbGeometryType ) ;
68
68
69
69
var numberOfPoints = GetUInt32 ( wkb , ref wkbPosition ) ;
70
70
var points = new List < Point > ( ) ;
71
71
72
72
for ( var i = 0 ; i < numberOfPoints ; ++ i )
73
73
{
74
- points . Add ( ParsePoint ( wkb , ref wkbPosition ) ) ;
74
+ points . Add ( ParsePoint ( wkb , ref wkbPosition , hasAltitude ) ) ;
75
75
}
76
76
77
77
return new MultiPoint ( points ) ;
78
78
}
79
79
80
- private static MultiLineString ParseMultiLineString ( byte [ ] wkb , ref int wkbPosition )
80
+ private static MultiLineString ParseMultiLineString ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
81
81
{
82
82
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
83
83
84
- CheckType ( WkbGeometryType . MultiLineString , wkbGeometryType ) ;
84
+ CheckBaseType ( WkbGeometryType . MultiLineString , wkbGeometryType ) ;
85
85
86
86
var numberOfLines = GetUInt32 ( wkb , ref wkbPosition ) ;
87
87
var lines = new List < LineString > ( ) ;
88
88
89
89
for ( var i = 0 ; i < numberOfLines ; ++ i )
90
90
{
91
- lines . Add ( ParseLineString ( wkb , ref wkbPosition ) ) ;
91
+ lines . Add ( ParseLineString ( wkb , ref wkbPosition , hasAltitude ) ) ;
92
92
}
93
93
94
94
return new MultiLineString ( lines ) ;
95
95
}
96
96
97
- private static MultiPolygon ParseMultiPolygon ( byte [ ] wkb , ref int wkbPosition )
97
+ private static MultiPolygon ParseMultiPolygon ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
98
98
{
99
99
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
100
100
101
- CheckType ( WkbGeometryType . MultiPolygon , wkbGeometryType ) ;
101
+ CheckBaseType ( WkbGeometryType . MultiPolygon , wkbGeometryType ) ;
102
102
103
103
var numberOfPolygons = GetUInt32 ( wkb , ref wkbPosition ) ;
104
104
var polygons = new List < Polygon > ( ) ;
105
105
106
106
for ( var i = 0 ; i < numberOfPolygons ; ++ i )
107
107
{
108
- polygons . Add ( ParsePolygon ( wkb , ref wkbPosition ) ) ;
108
+ polygons . Add ( ParsePolygon ( wkb , ref wkbPosition , hasAltitude ) ) ;
109
109
}
110
110
111
111
return new MultiPolygon ( polygons ) ;
@@ -115,7 +115,7 @@ private static GeometryCollection ParseGeometryCollection(byte[] wkb, ref int wk
115
115
{
116
116
var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
117
117
118
- CheckType ( WkbGeometryType . GeometryCollection , wkbGeometryType ) ;
118
+ CheckBaseType ( WkbGeometryType . GeometryCollection , wkbGeometryType ) ;
119
119
120
120
var numberOfShapes = GetUInt32 ( wkb , ref wkbPosition ) ;
121
121
var geometries = new List < IGeometryObject > ( ) ;
@@ -131,26 +131,34 @@ private static GeometryCollection ParseGeometryCollection(byte[] wkb, ref int wk
131
131
private static IGeometryObject ParseShape ( byte [ ] wkb , ref int wkbPosition )
132
132
{
133
133
var v_type = BitConverter . ToUInt32 ( wkb , wkbPosition + 1 ) ;
134
+ var baseType = v_type % 1000 ;
135
+ bool hasAltitude = v_type / 1000 == 1 || v_type / 1000 == 3 ;
136
+ bool hasMeasure = v_type / 1000 == 2 || v_type / 1000 == 3 ;
134
137
135
- switch ( v_type )
138
+ if ( hasMeasure )
139
+ {
140
+ throw new ArgumentOutOfRangeException ( "WKB data with an M value is currently not supported." ) ;
141
+ }
142
+
143
+ switch ( baseType )
136
144
{
137
145
case ( uint ) WkbGeometryType . Point :
138
- return ParsePoint ( wkb , ref wkbPosition ) ;
146
+ return ParsePoint ( wkb , ref wkbPosition , hasAltitude ) ;
139
147
140
148
case ( uint ) WkbGeometryType . LineString :
141
- return ParseLineString ( wkb , ref wkbPosition ) ;
149
+ return ParseLineString ( wkb , ref wkbPosition , hasAltitude ) ;
142
150
143
151
case ( uint ) WkbGeometryType . Polygon :
144
- return ParsePolygon ( wkb , ref wkbPosition ) ;
152
+ return ParsePolygon ( wkb , ref wkbPosition , hasAltitude ) ;
145
153
146
154
case ( uint ) WkbGeometryType . MultiPoint :
147
- return ParseMultiPoint ( wkb , ref wkbPosition ) ;
155
+ return ParseMultiPoint ( wkb , ref wkbPosition , hasAltitude ) ;
148
156
149
157
case ( uint ) WkbGeometryType . MultiLineString :
150
- return ParseMultiLineString ( wkb , ref wkbPosition ) ;
158
+ return ParseMultiLineString ( wkb , ref wkbPosition , hasAltitude ) ;
151
159
152
160
case ( uint ) WkbGeometryType . MultiPolygon :
153
- return ParseMultiPolygon ( wkb , ref wkbPosition ) ;
161
+ return ParseMultiPolygon ( wkb , ref wkbPosition , hasAltitude ) ;
154
162
155
163
case ( uint ) WkbGeometryType . GeometryCollection :
156
164
return ParseGeometryCollection ( wkb , ref wkbPosition ) ;
@@ -174,24 +182,25 @@ private static double GetDouble(byte[] wkb, ref int wkbPosition)
174
182
return doubleConversion ;
175
183
}
176
184
177
- private static Position [ ] ParsePositions ( byte [ ] wkb , ref int wkbPosition )
185
+ private static Position [ ] ParsePositions ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
178
186
{
179
187
var numberOfPoints = GetUInt32 ( wkb , ref wkbPosition ) ;
180
188
Position [ ] positions = new Position [ numberOfPoints ] ;
181
189
182
190
for ( var i = 0 ; i < numberOfPoints ; ++ i )
183
191
{
184
- positions [ i ] = GetGeographicPosition ( wkb , ref wkbPosition ) ;
192
+ positions [ i ] = GetGeographicPosition ( wkb , ref wkbPosition , hasAltitude ) ;
185
193
}
186
194
187
195
return positions ;
188
196
}
189
197
190
- private static Position GetGeographicPosition ( byte [ ] wkb , ref int wkbPosition )
198
+ private static Position GetGeographicPosition ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
191
199
{
192
- var longitud = GetDouble ( wkb , ref wkbPosition ) ;
193
- var latitud = GetDouble ( wkb , ref wkbPosition ) ;
194
- return new Position ( latitud , longitud ) ;
200
+ var longitude = GetDouble ( wkb , ref wkbPosition ) ;
201
+ var latitude = GetDouble ( wkb , ref wkbPosition ) ;
202
+ var altitude = hasAltitude ? GetDouble ( wkb , ref wkbPosition ) : ( double ? ) null ;
203
+ return new Position ( latitude , longitude , altitude ) ;
195
204
}
196
205
197
206
private static uint GetType ( byte [ ] wkb , ref int wkbPosition )
@@ -206,9 +215,9 @@ private static uint GetType(byte[] wkb, ref int wkbPosition)
206
215
return GetUInt32 ( wkb , ref wkbPosition ) ;
207
216
}
208
217
209
- private static void CheckType ( WkbGeometryType expected , uint actual )
218
+ private static void CheckBaseType ( WkbGeometryType expected , uint actual )
210
219
{
211
- if ( actual != ( uint ) expected )
220
+ if ( actual % 1000 != ( uint ) expected )
212
221
{
213
222
throw new ArgumentException ( $ "Invalid wkb geometry type, expected { expected } , actual { actual } ") ;
214
223
}
0 commit comments