simplefeatures
simplefeatures copied to clipboard
Implements ST_LineInterpolatePoint
Linear Referencing is so useful
import (
"github.com/peterstace/simplefeatures/geom"
)
const DISTMIN = 0.000001
type Segment struct {
Start, End geom.XY
}
func (s Segment) Length() float64 {
return s.End.Sub(s.Start).Length()
}
func distValid(dist float64) {
if dist < DISTMIN {
panic("dist can not < 0")
}
}
func (s Segment) Interpolate(dist float64) geom.XY {
distValid(dist)
length := s.Length()
if dist < length {
rate := dist / length
return s.Start.Add(s.End.Sub(s.Start).Scale(rate))
} else {
return s.End
}
}
func Interpolate(linestring geom.LineString, dist float64) geom.XY {
distValid(dist)
seq := linestring.Coordinates()
for i := 0; i < seq.Length(); i++ {
segment := Segment{Start: seq.GetXY(i), End: seq.GetXY(i + 1)}
length := segment.Length()
if dist <= length {
return segment.Interpolate(dist)
} else {
dist -= length
}
}
return geom.XY{X: -9999, Y: -9999}
}
Great suggestion, there are a bunch of other related functions that would be useful too: https://postgis.net/docs/reference.html#Linear_Referencing
I'll consider implementing these as the next major feature.
This is a high-quality spatial geometry analysis package I have some immature suggestions
- LineString with []Point may be easier to understand
- Coordinates are literally multiple points, and Coordinate may be more appropriate
- line composed of two points is called segment in JTS(https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/geom/LineSegment.java). export with Line is also very useful
The reason that LineString isn't implemented as []Point is that Point may optionally be empty (i.e. WKT POINT EMPTY). However, the coordinates that make up a LineString cannot be empty.
That's a good suggestion for exposing a Line object. There is an internal object that is very similar, I'll take a look to see what the implications of exposing it might be.
This was fixed. by #446 a while ago.