1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
package orb
// Geometry is an interface that represents the shared attributes
// of a geometry.
type Geometry interface {
GeoJSONType() string
Dimensions() int // e.g. 0d, 1d, 2d
Bound() Bound
// requiring because sub package type switch over all possible types.
private()
}
// compile time checks
var (
_ Geometry = Point{}
_ Geometry = MultiPoint{}
_ Geometry = LineString{}
_ Geometry = MultiLineString{}
_ Geometry = Ring{}
_ Geometry = Polygon{}
_ Geometry = MultiPolygon{}
_ Geometry = Bound{}
_ Geometry = Collection{}
)
func (p Point) private() {}
func (mp MultiPoint) private() {}
func (ls LineString) private() {}
func (mls MultiLineString) private() {}
func (r Ring) private() {}
func (p Polygon) private() {}
func (mp MultiPolygon) private() {}
func (b Bound) private() {}
func (c Collection) private() {}
// AllGeometries lists all possible types and values that a geometry
// interface can be. It should be used only for testing to verify
// functions that accept a Geometry will work in all cases.
var AllGeometries = []Geometry{
nil,
Point{},
MultiPoint{},
LineString{},
MultiLineString{},
Ring{},
Polygon{},
MultiPolygon{},
Bound{},
Collection{},
// nil values
MultiPoint(nil),
LineString(nil),
MultiLineString(nil),
Ring(nil),
Polygon(nil),
MultiPolygon(nil),
Collection(nil),
// Collection of Collection
Collection{Collection{Point{}}},
}
// A Collection is a collection of geometries that is also a Geometry.
type Collection []Geometry
// GeoJSONType returns the geometry collection type.
func (c Collection) GeoJSONType() string {
return "GeometryCollection"
}
// Dimensions returns the max of the dimensions of the collection.
func (c Collection) Dimensions() int {
max := -1
for _, g := range c {
if d := g.Dimensions(); d > max {
max = d
}
}
return max
}
// Bound returns the bounding box of all the Geometries combined.
func (c Collection) Bound() Bound {
if len(c) == 0 {
return emptyBound
}
var b Bound
start := -1
for i, g := range c {
if g != nil {
start = i
b = g.Bound()
break
}
}
if start == -1 {
return emptyBound
}
for i := start + 1; i < len(c); i++ {
if c[i] == nil {
continue
}
b = b.Union(c[i].Bound())
}
return b
}
// Equal compares two collections. Returns true if lengths are the same
// and all the sub geometries are the same and in the same order.
func (c Collection) Equal(collection Collection) bool {
if len(c) != len(collection) {
return false
}
for i, g := range c {
if !Equal(g, collection[i]) {
return false
}
}
return true
}
// Clone returns a deep copy of the collection.
func (c Collection) Clone() Collection {
if c == nil {
return nil
}
nc := make(Collection, len(c))
for i, g := range c {
nc[i] = Clone(g)
}
return nc
}
|