2020 // ErrUnsupportedGeometry is returned when geometry type is not supported by this lib.
2121 ErrUnsupportedGeometry = errors .New ("wkt: unsupported geometry" )
2222
23- doubleParen = regexp .MustCompile (`\)[\s|\t]*\)[\s|\t]*,[\s|\t]*\([\s|\t]*\(` )
24- singleParen = regexp .MustCompile (`\)[\s|\t]*,[\s|\t]*\(` )
25- noParen = regexp .MustCompile (`[\s|\t]*,[\s|\t]*` )
23+ doubleParen = regexp .MustCompile (`\)[\s|\t]*\)( [\s|\t]*,[\s|\t]*) \([\s|\t]*\(` )
24+ singleParen = regexp .MustCompile (`\)( [\s|\t]*,[\s|\t]*) \(` )
25+ noParen = regexp .MustCompile (`( [\s|\t]*,[\s|\t]*) ` )
2626)
2727
2828// UnmarshalPoint returns the point represented by the wkt string.
@@ -125,18 +125,24 @@ func UnmarshalCollection(s string) (p orb.Collection, err error) {
125125}
126126
127127// trimSpaceBrackets trim space and brackets
128- func trimSpaceBrackets (s string ) string {
128+ func trimSpaceBrackets (s string ) ( string , error ) {
129129 s = strings .Trim (s , " " )
130130 if len (s ) == 0 {
131- return ""
131+ return "" , nil
132132 }
133+
133134 if s [0 ] == '(' {
134135 s = s [1 :]
136+ } else {
137+ return "" , ErrNotWKT
135138 }
139+
136140 if s [len (s )- 1 ] == ')' {
137141 s = s [:len (s )- 1 ]
142+ } else {
143+ return "" , ErrNotWKT
138144 }
139- return strings .Trim (s , " " )
145+ return strings .Trim (s , " " ), nil
140146}
141147
142148// parsePoint pase point by (x y)
@@ -193,134 +199,199 @@ func Unmarshal(s string) (geom orb.Geometry, err error) {
193199 if s == "GEOMETRYCOLLECTION EMPTY" {
194200 return orb.Collection {}, nil
195201 }
196- s = strings .Replace (s , "GEOMETRYCOLLECTION" , "" , - 1 )
202+
203+ s = strings .ReplaceAll (s , "GEOMETRYCOLLECTION" , "" )
197204 if len (s ) == 0 {
198205 return nil , ErrNotWKT
199206 }
200- c := orb.Collection {}
201- ms := splitGeometryCollection (s )
202- if len (ms ) == 0 {
207+
208+ tc := orb.Collection {}
209+ geometries := splitGeometryCollection (s )
210+ if len (geometries ) == 0 {
203211 return nil , err
204212 }
205- for _ , v := range ms {
206- if len (v ) == 0 {
213+
214+ for _ , g := range geometries {
215+ if len (g ) == 0 {
207216 continue
208217 }
209- g , err := Unmarshal (v )
218+
219+ tg , err := Unmarshal (g )
210220 if err != nil {
211221 return nil , err
212222 }
213- c = append (c , g )
223+
224+ tc = append (tc , tg )
214225 }
215- geom = c
226+
227+ geom = tc
216228
217229 case strings .Contains (s , "MULTIPOINT" ):
218230 if s == "MULTIPOINT EMPTY" {
219231 return orb.MultiPoint {}, nil
220232 }
221- s = strings .Replace (s , "MULTIPOINT" , "" , - 1 )
222- s = trimSpaceBrackets (s )
233+
234+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "MULTIPOINT" , "" ))
235+ if err != nil {
236+ return nil , err
237+ }
238+
223239 ps := splitByRegexp (s , noParen )
224- mp := orb.MultiPoint {}
240+ tmp := orb.MultiPoint {}
225241 for _ , p := range ps {
226- tp , err := parsePoint ( trimSpaceBrackets (p ) )
242+ p , err := trimSpaceBrackets (p )
227243 if err != nil {
228244 return nil , err
229245 }
230- mp = append (mp , tp )
246+
247+ tp , err := parsePoint (p )
248+ if err != nil {
249+ return nil , err
250+ }
251+
252+ tmp = append (tmp , tp )
231253 }
232- geom = mp
254+
255+ geom = tmp
233256
234257 case strings .Contains (s , "POINT" ):
235- s = strings .Replace (s , "POINT" , "" , - 1 )
236- tp , err := parsePoint (trimSpaceBrackets (s ))
258+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "POINT" , "" ))
259+ if err != nil {
260+ return nil , err
261+ }
262+
263+ tp , err := parsePoint (s )
237264 if err != nil {
238265 return nil , err
239266 }
267+
240268 geom = tp
241269
242270 case strings .Contains (s , "MULTILINESTRING" ):
243271 if s == "MULTILINESTRING EMPTY" {
244272 return orb.MultiLineString {}, nil
245273 }
246- s = strings .Replace (s , "MULTILINESTRING" , "" , - 1 )
247- ml := orb.MultiLineString {}
248- for _ , l := range splitByRegexp (trimSpaceBrackets (s ), singleParen ) {
249- tl := orb.LineString {}
250- for _ , p := range splitByRegexp (trimSpaceBrackets (l ), noParen ) {
251- tp , err := parsePoint (trimSpaceBrackets (p ))
274+
275+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "MULTILINESTRING" , "" ))
276+ if err != nil {
277+ return nil , err
278+ }
279+
280+ tmls := orb.MultiLineString {}
281+ for _ , ls := range splitByRegexp (s , singleParen ) {
282+ ls , err := trimSpaceBrackets (ls )
283+ if err != nil {
284+ return nil , err
285+ }
286+
287+ tls := orb.LineString {}
288+ for _ , p := range splitByRegexp (ls , noParen ) {
289+ tp , err := parsePoint (p )
252290 if err != nil {
253291 return nil , err
254292 }
255- tl = append (tl , tp )
293+ tls = append (tls , tp )
256294 }
257- ml = append (ml , tl )
295+ tmls = append (tmls , tls )
258296 }
259- geom = ml
297+
298+ geom = tmls
260299
261300 case strings .Contains (s , "LINESTRING" ):
262301 if s == "LINESTRING EMPTY" {
263302 return orb.LineString {}, nil
264303 }
265- s = strings .Replace (s , "LINESTRING" , "" , - 1 )
266- s = trimSpaceBrackets (s )
267- ps := splitByRegexp (s , noParen )
268- ls := orb.LineString {}
269- for _ , p := range ps {
270- tp , err := parsePoint (trimSpaceBrackets (p ))
304+
305+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "LINESTRING" , "" ))
306+ if err != nil {
307+ return nil , err
308+ }
309+
310+ ls := splitByRegexp (s , noParen )
311+ tls := orb.LineString {}
312+ for _ , p := range ls {
313+ tp , err := parsePoint (p )
271314 if err != nil {
272315 return nil , err
273316 }
274- ls = append (ls , tp )
317+
318+ tls = append (tls , tp )
275319 }
276- geom = ls
320+
321+ geom = tls
277322
278323 case strings .Contains (s , "MULTIPOLYGON" ):
279324 if s == "MULTIPOLYGON EMPTY" {
280325 return orb.MultiPolygon {}, nil
281326 }
282- s = strings .Replace (s , "MULTIPOLYGON" , "" , - 1 )
283- mpol := orb.MultiPolygon {}
284-
285- for _ , ps := range splitByRegexp (trimSpaceBrackets (s ), doubleParen ) {
286- pol := orb.Polygon {}
287- for _ , ls := range splitByRegexp (trimSpaceBrackets (ps ), singleParen ) {
288- ring := orb.Ring {}
289- for _ , p := range splitByRegexp (ls , noParen ) {
290- tp , err := parsePoint (trimSpaceBrackets (p ))
327+
328+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "MULTIPOLYGON" , "" ))
329+ if err != nil {
330+ return nil , err
331+ }
332+
333+ tmpoly := orb.MultiPolygon {}
334+ for _ , poly := range splitByRegexp (s , doubleParen ) {
335+ poly , err := trimSpaceBrackets (poly )
336+ if err != nil {
337+ return nil , err
338+ }
339+
340+ tpoly := orb.Polygon {}
341+ for _ , r := range splitByRegexp (poly , singleParen ) {
342+ r , err := trimSpaceBrackets (r )
343+ if err != nil {
344+ return nil , err
345+ }
346+
347+ tr := orb.Ring {}
348+ for _ , p := range splitByRegexp (r , noParen ) {
349+ tp , err := parsePoint (p )
291350 if err != nil {
292351 return nil , err
293352 }
294- ring = append (ring , tp )
353+
354+ tr = append (tr , tp )
295355 }
296- pol = append (pol , ring )
356+
357+ tpoly = append (tpoly , tr )
297358 }
298- mpol = append (mpol , pol )
359+
360+ tmpoly = append (tmpoly , tpoly )
299361 }
300- geom = mpol
362+
363+ geom = tmpoly
301364
302365 case strings .Contains (s , "POLYGON" ):
303366 if s == "POLYGON EMPTY" {
304367 return orb.Polygon {}, nil
305368 }
306- s = strings .Replace (s , "POLYGON" , "" , - 1 )
307- s = trimSpaceBrackets (s )
308-
309- rs := splitByRegexp (s , singleParen )
310- pol := make (orb.Polygon , 0 , len (rs ))
311- for _ , r := range rs {
312- ps := splitByRegexp (trimSpaceBrackets (r ), noParen )
313- ring := orb.Ring {}
369+
370+ s , err := trimSpaceBrackets (strings .ReplaceAll (s , "POLYGON" , "" ))
371+ if err != nil {
372+ return nil , err
373+ }
374+
375+ rings := splitByRegexp (s , singleParen )
376+ tpoly := make (orb.Polygon , 0 , len (rings ))
377+ for _ , r := range rings {
378+ r , err := trimSpaceBrackets (r )
379+ if err != nil {
380+ return nil , err
381+ }
382+
383+ ps := splitByRegexp (r , noParen )
384+ tring := orb.Ring {}
314385 for _ , p := range ps {
315- tp , err := parsePoint (trimSpaceBrackets ( p ) )
386+ tp , err := parsePoint (p )
316387 if err != nil {
317388 return nil , err
318389 }
319- ring = append (ring , tp )
390+ tring = append (tring , tp )
320391 }
321- pol = append (pol , ring )
392+ tpoly = append (tpoly , tring )
322393 }
323- geom = pol
394+ geom = tpoly
324395 default :
325396 return nil , ErrUnsupportedGeometry
326397 }
@@ -329,12 +400,12 @@ func Unmarshal(s string) (geom orb.Geometry, err error) {
329400}
330401
331402func splitByRegexp (s string , re * regexp.Regexp ) []string {
332- indexes := re .FindAllStringIndex (s , - 1 )
403+ indexes := re .FindAllStringSubmatchIndex (s , - 1 )
333404 start := 0
334405 result := make ([]string , len (indexes )+ 1 )
335406 for i , element := range indexes {
336- result [i ] = s [start :element [0 ]]
337- start = element [1 ]
407+ result [i ] = s [start :element [2 ]]
408+ start = element [3 ]
338409 }
339410 result [len (indexes )] = s [start :]
340411 return result
0 commit comments