2013-04-29 21:36:30 +04:00
|
|
|
package geom
|
|
|
|
|
|
|
|
import (
|
|
|
|
"goposm/element"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Ring struct {
|
|
|
|
ways []*element.Way
|
|
|
|
refs []int64
|
2013-05-06 17:34:09 +04:00
|
|
|
nodes []element.Node
|
2013-04-29 21:36:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func reverseRefs(refs []int64) {
|
|
|
|
for i, j := 0, len(refs)-1; i < j; i, j = i+1, j-1 {
|
|
|
|
refs[i], refs[j] = refs[j], refs[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 17:34:09 +04:00
|
|
|
func reverseNodes(nodes []element.Node) {
|
2013-04-29 21:36:30 +04:00
|
|
|
for i, j := 0, len(nodes)-1; i < j; i, j = i+1, j-1 {
|
|
|
|
nodes[i], nodes[j] = nodes[j], nodes[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func mergeRings(rings []*Ring) []*Ring {
|
|
|
|
endpoints := make(map[int64]*Ring)
|
2013-05-06 17:34:09 +04:00
|
|
|
|
2013-04-29 21:36:30 +04:00
|
|
|
for _, ring := range rings {
|
|
|
|
left := ring.refs[0]
|
|
|
|
right := ring.refs[len(ring.refs)-1]
|
|
|
|
if origRing, ok := endpoints[left]; ok {
|
|
|
|
delete(endpoints, left)
|
|
|
|
if left == origRing.refs[len(origRing.refs)-1] {
|
|
|
|
origRing.refs = append(origRing.refs, ring.refs[1:]...)
|
|
|
|
origRing.nodes = append(origRing.nodes, ring.nodes[1:]...)
|
|
|
|
} else {
|
|
|
|
reverseRefs(origRing.refs)
|
|
|
|
origRing.refs = append(origRing.refs, ring.refs[1:]...)
|
|
|
|
reverseNodes(origRing.nodes)
|
|
|
|
origRing.nodes = append(origRing.nodes, ring.nodes[1:]...)
|
|
|
|
}
|
|
|
|
origRing.ways = append(origRing.ways, ring.ways...)
|
|
|
|
// TODO tags
|
|
|
|
if rightRing, ok := endpoints[right]; ok && rightRing != origRing {
|
|
|
|
// close gap
|
|
|
|
delete(endpoints, right)
|
2013-05-06 17:34:09 +04:00
|
|
|
if right == rightRing.refs[0] {
|
|
|
|
origRing.refs = append(origRing.refs, rightRing.refs[1:]...)
|
|
|
|
origRing.nodes = append(origRing.nodes, rightRing.nodes[1:]...)
|
2013-04-29 21:36:30 +04:00
|
|
|
} else {
|
2013-05-06 17:34:09 +04:00
|
|
|
reverseRefs(rightRing.refs)
|
|
|
|
origRing.refs = append(origRing.refs[:len(origRing.refs)-1], rightRing.refs...)
|
|
|
|
reverseNodes(rightRing.nodes)
|
|
|
|
origRing.nodes = append(origRing.nodes[:len(origRing.nodes)-1], rightRing.nodes...)
|
2013-04-29 21:36:30 +04:00
|
|
|
}
|
2013-05-06 17:34:09 +04:00
|
|
|
origRing.ways = append(origRing.ways, rightRing.ways...)
|
2013-04-29 21:36:30 +04:00
|
|
|
right := origRing.refs[len(origRing.refs)-1]
|
|
|
|
endpoints[right] = origRing
|
|
|
|
|
|
|
|
} else {
|
|
|
|
endpoints[right] = origRing
|
|
|
|
}
|
|
|
|
} else if origRing, ok := endpoints[right]; ok {
|
|
|
|
delete(endpoints, right)
|
|
|
|
if right == origRing.refs[0] {
|
|
|
|
origRing.refs = append(ring.refs[:len(ring.refs)-1], origRing.refs...)
|
|
|
|
origRing.nodes = append(ring.nodes[:len(ring.nodes)-1], origRing.nodes...)
|
|
|
|
} else {
|
|
|
|
reverseRefs(ring.refs)
|
2013-05-06 17:34:09 +04:00
|
|
|
origRing.refs = append(origRing.refs[:len(origRing.refs)-1], ring.refs...)
|
2013-04-29 21:36:30 +04:00
|
|
|
reverseNodes(ring.nodes)
|
2013-05-06 17:34:09 +04:00
|
|
|
origRing.nodes = append(origRing.nodes[:len(origRing.nodes)-1], ring.nodes...)
|
2013-04-29 21:36:30 +04:00
|
|
|
}
|
|
|
|
origRing.ways = append(origRing.ways, ring.ways...)
|
|
|
|
// TODO tags
|
|
|
|
endpoints[left] = origRing
|
|
|
|
} else {
|
|
|
|
endpoints[left] = ring
|
|
|
|
endpoints[right] = ring
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uniqueRings := make(map[*Ring]bool)
|
|
|
|
for _, ring := range endpoints {
|
|
|
|
uniqueRings[ring] = true
|
|
|
|
}
|
2013-04-30 16:01:28 +04:00
|
|
|
result := make([]*Ring, 0, len(uniqueRings))
|
2013-04-29 21:36:30 +04:00
|
|
|
for ring, _ := range uniqueRings {
|
|
|
|
result = append(result, ring)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|