forked from go-spatial/geom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
polygon.go
67 lines (55 loc) · 1.69 KB
/
polygon.go
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
package geom
import (
"errors"
)
// ErrNilPolygon is thrown when a polygon is nil but shouldn't be
var ErrNilPolygon = errors.New("geom: nil Polygon")
// ErrInvalidLinearRing is thrown when a LinearRing is malformed
var ErrInvalidLinearRing = errors.New("geom: invalid LinearRing")
// ErrInvalidPolygon is thrown when a Polygon is malformed
var ErrInvalidPolygon = errors.New("geom: invalid Polygon")
// Polygon is a geometry consisting of multiple closed LineStrings.
// There must be only one exterior LineString with a clockwise winding order.
// There may be one or more interior LineStrings with a counterclockwise winding orders.
// The last point in the linear ring will not match the first point.
type Polygon [][][2]float64
// LinearRings returns the coordinates of the linear rings
func (p Polygon) LinearRings() [][][2]float64 {
return p
}
// SetLinearRings modifies the array of 2D coordinates
func (p *Polygon) SetLinearRings(input [][][2]float64) (err error) {
if p == nil {
return ErrNilPolygon
}
*p = append((*p)[:0], input...)
return
}
// AsSegments returns the polygon as a slice of lines. This will make no attempt to only add unique segments.
func (p Polygon) AsSegments() (segs [][]Line, err error) {
if len(p) == 0 {
return nil, nil
}
segs = make([][]Line, 0, len(p))
for i := range p {
switch len(p[i]) {
case 0, 1, 2:
continue
// TODO(gdey) : why are we getting invalid points.
/*
case 1, 2:
return nil, ErrInvalidLinearRing
*/
default:
pilen := len(p[i])
subr := make([]Line, pilen)
pj := pilen - 1
for j := 0; j < pilen; j++ {
subr[j] = Line{p[i][pj], p[i][j]}
pj = j
}
segs = append(segs, subr)
}
}
return segs, nil
}