github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/geo/geomfn/geomfn.go (about) 1 // Copyright 2020 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // Package geomfn contains functions that are used for geometry-based builtins. 12 package geomfn 13 14 import ( 15 "github.com/cockroachdb/cockroach/pkg/geo" 16 "github.com/cockroachdb/errors" 17 "github.com/twpayne/go-geom" 18 ) 19 20 // flattenGeometry flattens a geo.Geometry object. 21 func flattenGeometry(g *geo.Geometry, emptyBehavior geo.EmptyBehavior) ([]geom.T, error) { 22 f, err := g.AsGeomT() 23 if err != nil { 24 return nil, err 25 } 26 return flattenGeomT(f, emptyBehavior) 27 } 28 29 // flattenGeomT decomposes geom.T collections to individual geom.T components. 30 func flattenGeomT(g geom.T, emptyBehavior geo.EmptyBehavior) ([]geom.T, error) { 31 if g.Empty() { 32 switch emptyBehavior { 33 case geo.EmptyBehaviorOmit: 34 return nil, nil 35 case geo.EmptyBehaviorError: 36 return nil, geo.NewEmptyGeometryError() 37 default: 38 return nil, errors.Newf("programmer error: unknown behavior") 39 } 40 } 41 switch g := g.(type) { 42 case *geom.Point: 43 return []geom.T{g}, nil 44 case *geom.LineString: 45 return []geom.T{g}, nil 46 case *geom.Polygon: 47 return []geom.T{g}, nil 48 case *geom.MultiPoint: 49 ret := make([]geom.T, g.NumPoints()) 50 for i := 0; i < g.NumPoints(); i++ { 51 ret[i] = g.Point(i) 52 } 53 return ret, nil 54 case *geom.MultiLineString: 55 ret := make([]geom.T, g.NumLineStrings()) 56 for i := 0; i < g.NumLineStrings(); i++ { 57 ret[i] = g.LineString(i) 58 } 59 return ret, nil 60 case *geom.MultiPolygon: 61 ret := make([]geom.T, g.NumPolygons()) 62 for i := 0; i < g.NumPolygons(); i++ { 63 ret[i] = g.Polygon(i) 64 } 65 return ret, nil 66 case *geom.GeometryCollection: 67 ret := make([]geom.T, 0, g.NumGeoms()) 68 for _, subG := range g.Geoms() { 69 if subG.Empty() { 70 switch emptyBehavior { 71 case geo.EmptyBehaviorOmit: 72 continue 73 case geo.EmptyBehaviorError: 74 return nil, geo.NewEmptyGeometryError() 75 default: 76 return nil, errors.Newf("programmer error: unknown behavior") 77 } 78 } 79 ret = append(ret, subG) 80 } 81 return ret, nil 82 } 83 return nil, errors.Newf("unknown geom: %T", g) 84 }