forked from twpayne/go-geom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linestring.go
104 lines (91 loc) · 2.57 KB
/
linestring.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
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
package geom
// A LineString represents a single, unbroken line, linearly interpreted
// between zero or more control points.
type LineString struct {
geom1
}
// NewLineString returns a new LineString with layout l and no control points.
func NewLineString(l Layout) *LineString {
return NewLineStringFlat(l, nil)
}
// NewLineStringFlat returns a new LineString with layout l and control points
// flatCoords.
func NewLineStringFlat(layout Layout, flatCoords []float64) *LineString {
ls := new(LineString)
ls.layout = layout
ls.stride = layout.Stride()
ls.flatCoords = flatCoords
return ls
}
// Area returns the length of ls, i.e. zero.
func (ls *LineString) Area() float64 {
return 0
}
// Clone returns a copy of ls that does not alias ls.
func (ls *LineString) Clone() *LineString {
return deriveCloneLineString(ls)
}
// Empty returns false.
func (ls *LineString) Empty() bool {
return false
}
// Interpolate returns the index and delta of val in dimension dim.
func (ls *LineString) Interpolate(val float64, dim int) (int, float64) {
n := len(ls.flatCoords)
if n == 0 {
panic("geom: empty linestring")
}
if val <= ls.flatCoords[dim] {
return 0, 0
}
if ls.flatCoords[n-ls.stride+dim] <= val {
return (n - 1) / ls.stride, 0
}
low := 0
high := n / ls.stride
for low < high {
mid := (low + high) / 2
if val < ls.flatCoords[mid*ls.stride+dim] {
high = mid
} else {
low = mid + 1
}
}
low--
val0 := ls.flatCoords[low*ls.stride+dim]
if val == val0 {
return low, 0
}
val1 := ls.flatCoords[(low+1)*ls.stride+dim]
return low, (val - val0) / (val1 - val0)
}
// Length returns the length of ls.
func (ls *LineString) Length() float64 {
return length1(ls.flatCoords, 0, len(ls.flatCoords), ls.stride)
}
// MustSetCoords is like SetCoords but it panics on any error.
func (ls *LineString) MustSetCoords(coords []Coord) *LineString {
Must(ls.SetCoords(coords))
return ls
}
// SetCoords sets the coordinates of ls.
func (ls *LineString) SetCoords(coords []Coord) (*LineString, error) {
if err := ls.setCoords(coords); err != nil {
return nil, err
}
return ls, nil
}
// SetSRID sets the SRID of ls.
func (ls *LineString) SetSRID(srid int) *LineString {
ls.srid = srid
return ls
}
// SubLineString returns a LineString from starts at index start and stops at
// index stop of ls. The returned LineString aliases ls.
func (ls *LineString) SubLineString(start, stop int) *LineString {
return NewLineStringFlat(ls.layout, ls.flatCoords[start*ls.stride:stop*ls.stride])
}
// Swap swaps the values of ls and ls2.
func (ls *LineString) Swap(ls2 *LineString) {
*ls, *ls2 = *ls2, *ls
}