Mercurial > gemma
changeset 768:3219e7e34953
Join neighbored linestring segments in octree cross sections and sort them along the input line.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 25 Sep 2018 17:45:44 +0200 |
parents | dedf252b3e01 |
children | ba2007b746ef |
files | pkg/octree/vertex.go |
diffstat | 1 files changed, 81 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/octree/vertex.go Tue Sep 25 17:39:00 2018 +0200 +++ b/pkg/octree/vertex.go Tue Sep 25 17:45:44 2018 +0200 @@ -6,6 +6,7 @@ "io" "log" "math" + "sort" ) type ( @@ -161,10 +162,87 @@ return nil } +func linearScale(x1, y1, x2, y2 float64) func(Vertex) float64 { + dx := x2 - x1 + dy := y2 - y1 + + switch { + case dx != 0: + return func(v Vertex) float64 { + return (v.X - x1) / dx + } + case dy != 0: + return func(v Vertex) float64 { + return (v.Y - y1) / dy + } + default: + return func(Vertex) float64 { + return 0 + } + } +} + +func (ls LineStringZ) order(position func(Vertex) float64) { + type posVertex struct { + pos float64 + v Vertex + } + positions := make([]posVertex, len(ls)) + for i, v := range ls { + positions[i] = posVertex{position(v), v} + } + sort.Slice(positions, func(i, j int) bool { + return positions[i].pos < positions[j].pos + }) + for i := range positions { + ls[i] = positions[i].v + } +} + +func (v Vertex) EpsEquals(w Vertex) bool { + const eqs = 1e-5 + return math.Abs(v.X-w.X) < eps && + math.Abs(v.Y-w.Y) < eps && math.Abs(v.Z-w.Z) < eps +} + func (mls MultiLineStringZ) JoinOnLine(x1, y1, x2, y2 float64) MultiLineStringZ { - // TODO: Implement me! - log.Println("MultiLineStringZ.JoinOnLine is not implemented, yet!") - return mls + + position := linearScale(x1, y1, x2, y2) + + type posLineString struct { + pos float64 + line LineStringZ + } + + positions := make([]posLineString, 0, len(mls)) + + for _, ls := range mls { + if len(ls) == 0 { + continue + } + // order the atoms first + ls.order(position) + positions = append(positions, posLineString{position(ls[0]), ls}) + } + + sort.Slice(positions, func(i, j int) bool { + return positions[i].pos < positions[j].pos + }) + + out := make(MultiLineStringZ, 0, len(positions)) + + for i := range positions { + curr := positions[i].line + if l := len(out); l > 0 { + if last := out[l-1]; last[len(last)-1].EpsEquals(curr[0]) { + out[l-1] = append(last[:len(last)-1], curr...) + continue + } + } + out = append(out, curr) + } + + return out } func (v *Vertex) Write(w io.Writer) error {