@@ -19,93 +19,93 @@ public static IGeometryObject Decode(byte[] wkb)
1919 return ParseShape ( wkb , ref v_pos ) ;
2020 }
2121
22- private static Point ParsePoint ( byte [ ] wkb , ref int wkbPosition )
22+ private static Point ParsePoint ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
2323 {
2424 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
2525
26- CheckType ( WkbGeometryType . Point , wkbGeometryType ) ;
26+ CheckBaseType ( WkbGeometryType . Point , wkbGeometryType ) ;
2727
28- Position geographicalPosition = GetGeographicPosition ( wkb , ref wkbPosition ) ;
28+ Position geographicalPosition = GetGeographicPosition ( wkb , ref wkbPosition , hasAltitude ) ;
2929
3030 return new Point ( geographicalPosition ) ;
3131 }
3232
33- private static LineString ParseLineString ( byte [ ] wkb , ref int wkbPosition )
33+ private static LineString ParseLineString ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
3434 {
3535 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
3636
37- CheckType ( WkbGeometryType . LineString , wkbGeometryType ) ;
37+ CheckBaseType ( WkbGeometryType . LineString , wkbGeometryType ) ;
3838
39- Position [ ] positions = ParsePositions ( wkb , ref wkbPosition ) ;
39+ Position [ ] positions = ParsePositions ( wkb , ref wkbPosition , hasAltitude ) ;
4040
4141 return new LineString ( positions ) ;
4242 }
4343
44- private static Polygon ParsePolygon ( byte [ ] wkb , ref int wkbPosition )
44+ private static Polygon ParsePolygon ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
4545 {
4646 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
4747
48- CheckType ( WkbGeometryType . Polygon , wkbGeometryType ) ;
48+ CheckBaseType ( WkbGeometryType . Polygon , wkbGeometryType ) ;
4949
5050 var numberOfLines = GetUInt32 ( wkb , ref wkbPosition ) ;
5151 var lines = new List < LineString > ( ) ;
5252
5353 for ( var v_ls = 0 ; v_ls < numberOfLines ; ++ v_ls )
5454 {
55- Position [ ] positions = ParsePositions ( wkb , ref wkbPosition ) ;
55+ Position [ ] positions = ParsePositions ( wkb , ref wkbPosition , hasAltitude ) ;
5656
5757 lines . Add ( new LineString ( positions ) ) ;
5858 }
5959
6060 return new Polygon ( lines ) ;
6161 }
6262
63- private static MultiPoint ParseMultiPoint ( byte [ ] wkb , ref int wkbPosition )
63+ private static MultiPoint ParseMultiPoint ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
6464 {
6565 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
6666
67- CheckType ( WkbGeometryType . MultiPoint , wkbGeometryType ) ;
67+ CheckBaseType ( WkbGeometryType . MultiPoint , wkbGeometryType ) ;
6868
6969 var numberOfPoints = GetUInt32 ( wkb , ref wkbPosition ) ;
7070 var points = new List < Point > ( ) ;
7171
7272 for ( var i = 0 ; i < numberOfPoints ; ++ i )
7373 {
74- points . Add ( ParsePoint ( wkb , ref wkbPosition ) ) ;
74+ points . Add ( ParsePoint ( wkb , ref wkbPosition , hasAltitude ) ) ;
7575 }
7676
7777 return new MultiPoint ( points ) ;
7878 }
7979
80- private static MultiLineString ParseMultiLineString ( byte [ ] wkb , ref int wkbPosition )
80+ private static MultiLineString ParseMultiLineString ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
8181 {
8282 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
8383
84- CheckType ( WkbGeometryType . MultiLineString , wkbGeometryType ) ;
84+ CheckBaseType ( WkbGeometryType . MultiLineString , wkbGeometryType ) ;
8585
8686 var numberOfLines = GetUInt32 ( wkb , ref wkbPosition ) ;
8787 var lines = new List < LineString > ( ) ;
8888
8989 for ( var i = 0 ; i < numberOfLines ; ++ i )
9090 {
91- lines . Add ( ParseLineString ( wkb , ref wkbPosition ) ) ;
91+ lines . Add ( ParseLineString ( wkb , ref wkbPosition , hasAltitude ) ) ;
9292 }
9393
9494 return new MultiLineString ( lines ) ;
9595 }
9696
97- private static MultiPolygon ParseMultiPolygon ( byte [ ] wkb , ref int wkbPosition )
97+ private static MultiPolygon ParseMultiPolygon ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
9898 {
9999 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
100100
101- CheckType ( WkbGeometryType . MultiPolygon , wkbGeometryType ) ;
101+ CheckBaseType ( WkbGeometryType . MultiPolygon , wkbGeometryType ) ;
102102
103103 var numberOfPolygons = GetUInt32 ( wkb , ref wkbPosition ) ;
104104 var polygons = new List < Polygon > ( ) ;
105105
106106 for ( var i = 0 ; i < numberOfPolygons ; ++ i )
107107 {
108- polygons . Add ( ParsePolygon ( wkb , ref wkbPosition ) ) ;
108+ polygons . Add ( ParsePolygon ( wkb , ref wkbPosition , hasAltitude ) ) ;
109109 }
110110
111111 return new MultiPolygon ( polygons ) ;
@@ -115,7 +115,7 @@ private static GeometryCollection ParseGeometryCollection(byte[] wkb, ref int wk
115115 {
116116 var wkbGeometryType = GetType ( wkb , ref wkbPosition ) ;
117117
118- CheckType ( WkbGeometryType . GeometryCollection , wkbGeometryType ) ;
118+ CheckBaseType ( WkbGeometryType . GeometryCollection , wkbGeometryType ) ;
119119
120120 var numberOfShapes = GetUInt32 ( wkb , ref wkbPosition ) ;
121121 var geometries = new List < IGeometryObject > ( ) ;
@@ -131,26 +131,34 @@ private static GeometryCollection ParseGeometryCollection(byte[] wkb, ref int wk
131131 private static IGeometryObject ParseShape ( byte [ ] wkb , ref int wkbPosition )
132132 {
133133 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 ;
134137
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 )
136144 {
137145 case ( uint ) WkbGeometryType . Point :
138- return ParsePoint ( wkb , ref wkbPosition ) ;
146+ return ParsePoint ( wkb , ref wkbPosition , hasAltitude ) ;
139147
140148 case ( uint ) WkbGeometryType . LineString :
141- return ParseLineString ( wkb , ref wkbPosition ) ;
149+ return ParseLineString ( wkb , ref wkbPosition , hasAltitude ) ;
142150
143151 case ( uint ) WkbGeometryType . Polygon :
144- return ParsePolygon ( wkb , ref wkbPosition ) ;
152+ return ParsePolygon ( wkb , ref wkbPosition , hasAltitude ) ;
145153
146154 case ( uint ) WkbGeometryType . MultiPoint :
147- return ParseMultiPoint ( wkb , ref wkbPosition ) ;
155+ return ParseMultiPoint ( wkb , ref wkbPosition , hasAltitude ) ;
148156
149157 case ( uint ) WkbGeometryType . MultiLineString :
150- return ParseMultiLineString ( wkb , ref wkbPosition ) ;
158+ return ParseMultiLineString ( wkb , ref wkbPosition , hasAltitude ) ;
151159
152160 case ( uint ) WkbGeometryType . MultiPolygon :
153- return ParseMultiPolygon ( wkb , ref wkbPosition ) ;
161+ return ParseMultiPolygon ( wkb , ref wkbPosition , hasAltitude ) ;
154162
155163 case ( uint ) WkbGeometryType . GeometryCollection :
156164 return ParseGeometryCollection ( wkb , ref wkbPosition ) ;
@@ -174,24 +182,25 @@ private static double GetDouble(byte[] wkb, ref int wkbPosition)
174182 return doubleConversion ;
175183 }
176184
177- private static Position [ ] ParsePositions ( byte [ ] wkb , ref int wkbPosition )
185+ private static Position [ ] ParsePositions ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
178186 {
179187 var numberOfPoints = GetUInt32 ( wkb , ref wkbPosition ) ;
180188 Position [ ] positions = new Position [ numberOfPoints ] ;
181189
182190 for ( var i = 0 ; i < numberOfPoints ; ++ i )
183191 {
184- positions [ i ] = GetGeographicPosition ( wkb , ref wkbPosition ) ;
192+ positions [ i ] = GetGeographicPosition ( wkb , ref wkbPosition , hasAltitude ) ;
185193 }
186194
187195 return positions ;
188196 }
189197
190- private static Position GetGeographicPosition ( byte [ ] wkb , ref int wkbPosition )
198+ private static Position GetGeographicPosition ( byte [ ] wkb , ref int wkbPosition , bool hasAltitude )
191199 {
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 ) ;
195204 }
196205
197206 private static uint GetType ( byte [ ] wkb , ref int wkbPosition )
@@ -206,9 +215,9 @@ private static uint GetType(byte[] wkb, ref int wkbPosition)
206215 return GetUInt32 ( wkb , ref wkbPosition ) ;
207216 }
208217
209- private static void CheckType ( WkbGeometryType expected , uint actual )
218+ private static void CheckBaseType ( WkbGeometryType expected , uint actual )
210219 {
211- if ( actual != ( uint ) expected )
220+ if ( actual % 1000 != ( uint ) expected )
212221 {
213222 throw new ArgumentException ( $ "Invalid wkb geometry type, expected { expected } , actual { actual } ") ;
214223 }
0 commit comments