refactor geom api: make ring private

Oliver Tonnhofer 2015-04-30 10:05:22 +02:00
parent 7c438fb867
commit 171e1c24fa
4 changed files with 55 additions and 55 deletions

View File

@ -26,19 +26,19 @@ func (e *GeomError) Level() int {
return e.level
}
func NewGeomError(message string, level int) *GeomError {
func newGeomError(message string, level int) *GeomError {
return &GeomError{message, level}
}
var (
ErrorOneNodeWay = NewGeomError("need at least two separate nodes for way", 0)
ErrorNoRing = NewGeomError("linestrings do not form ring", 0)
ErrorOneNodeWay = newGeomError("need at least two separate nodes for way", 0)
ErrorNoRing = newGeomError("linestrings do not form ring", 0)
)
func Point(g *geos.Geos, node element.Node) (*geos.Geom, error) {
geom := g.Point(node.Long, node.Lat)
if geom == nil {
return nil, NewGeomError("couldn't create point", 1)
return nil, newGeomError("couldn't create point", 1)
}
g.DestroyLater(geom)
return geom, nil

View File

@ -9,7 +9,7 @@ import (
)
type PreparedRelation struct {
rings []*Ring
rings []*ring
rel *element.Relation
srid int
}
@ -46,7 +46,7 @@ func (prep *PreparedRelation) Build() (Geometry, error) {
return Geometry{Geom: geom, Wkb: wkb}, nil
}
func destroyRings(g *geos.Geos, rings []*Ring) {
func destroyRings(g *geos.Geos, rings []*ring) {
for _, r := range rings {
if r.geom != nil {
g.Destroy(r.geom)
@ -55,11 +55,11 @@ func destroyRings(g *geos.Geos, rings []*Ring) {
}
}
func buildRings(rel *element.Relation, maxRingGap float64) ([]*Ring, error) {
var rings []*Ring
var incompleteRings []*Ring
var completeRings []*Ring
var mergedRings []*Ring
func buildRings(rel *element.Relation, maxRingGap float64) ([]*ring, error) {
var rings []*ring
var incompleteRings []*ring
var completeRings []*ring
var mergedRings []*ring
var err error
g := geos.NewGeos()
defer g.Finish()
@ -76,12 +76,12 @@ func buildRings(rel *element.Relation, maxRingGap float64) ([]*Ring, error) {
if member.Way == nil {
continue
}
rings = append(rings, NewRing(member.Way))
rings = append(rings, newRing(member.Way))
}
// create geometries for closed rings, collect incomplete rings
for _, r := range rings {
if r.IsClosed() {
if r.isClosed() {
r.geom, err = Polygon(g, r.nodes)
if err != nil {
return nil, err
@ -99,7 +99,7 @@ func buildRings(rel *element.Relation, maxRingGap float64) ([]*Ring, error) {
}
// create geometries for merged rings
for _, ring := range mergedRings {
if !ring.IsClosed() && !ring.TryClose(maxRingGap) {
if !ring.isClosed() && !ring.tryClose(maxRingGap) {
err = ErrorNoRing // for defer
return nil, err
}
@ -115,22 +115,22 @@ func buildRings(rel *element.Relation, maxRingGap float64) ([]*Ring, error) {
for _, r := range completeRings {
r.area = r.geom.Area()
}
sort.Sort(SortableRingsDesc(completeRings))
sort.Sort(sortableRingsDesc(completeRings))
return completeRings, nil
}
type SortableRingsDesc []*Ring
type sortableRingsDesc []*ring
func (r SortableRingsDesc) Len() int { return len(r) }
func (r SortableRingsDesc) Less(i, j int) bool { return r[i].area > r[j].area }
func (r SortableRingsDesc) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r sortableRingsDesc) Len() int { return len(r) }
func (r sortableRingsDesc) Less(i, j int) bool { return r[i].area > r[j].area }
func (r sortableRingsDesc) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
// buildRelGeometry builds the geometry of rel by creating a multipolygon of all rings.
// rings need to be sorted by area (large to small).
func buildRelGeometry(g *geos.Geos, rel *element.Relation, rings []*Ring) (*geos.Geom, error) {
func buildRelGeometry(g *geos.Geos, rel *element.Relation, rings []*ring) (*geos.Geom, error) {
totalRings := len(rings)
shells := map[*Ring]bool{rings[0]: true}
shells := map[*ring]bool{rings[0]: true}
for i := 0; i < totalRings; i++ {
testGeom := g.Prepare(rings[i].geom)
if testGeom == nil {
@ -252,7 +252,7 @@ func relationTags(relTags, wayTags element.Tags) element.Tags {
// ringIsHole returns true if rings[idx] is a hole, False if it is a
// shell (also if hole in a hole, etc)
func ringIsHole(rings []*Ring, idx int) bool {
func ringIsHole(rings []*ring, idx int) bool {
containedCounter := 0
for {

View File

@ -5,36 +5,36 @@ import (
"github.com/omniscale/imposm3/geom/geos"
)
type Ring struct {
type ring struct {
ways []*element.Way
refs []int64
nodes []element.Node
geom *geos.Geom
holes map[*Ring]bool
holes map[*ring]bool
containedBy int
area float64
outer bool
inserted map[int64]bool
}
func (r *Ring) IsClosed() bool {
func (r *ring) isClosed() bool {
return len(r.refs) >= 4 && r.refs[0] == r.refs[len(r.refs)-1]
}
func (r *Ring) TryClose(maxRingGap float64) bool {
func (r *ring) tryClose(maxRingGap float64) bool {
return element.TryCloseWay(r.refs, r.nodes, maxRingGap)
}
func NewRing(way *element.Way) *Ring {
ring := Ring{}
ring.ways = []*element.Way{way}
ring.refs = make([]int64, len(way.Refs))
ring.nodes = make([]element.Node, len(way.Nodes))
ring.containedBy = -1
ring.holes = make(map[*Ring]bool)
copy(ring.refs, way.Refs)
copy(ring.nodes, way.Nodes)
return &ring
func newRing(way *element.Way) *ring {
r := ring{}
r.ways = []*element.Way{way}
r.refs = make([]int64, len(way.Refs))
r.nodes = make([]element.Node, len(way.Nodes))
r.containedBy = -1
r.holes = make(map[*ring]bool)
copy(r.refs, way.Refs)
copy(r.nodes, way.Nodes)
return &r
}
func reverseRefs(refs []int64) {
@ -49,8 +49,8 @@ func reverseNodes(nodes []element.Node) {
}
}
func mergeRings(rings []*Ring) []*Ring {
endpoints := make(map[int64]*Ring)
func mergeRings(rings []*ring) []*ring {
endpoints := make(map[int64]*ring)
for _, ring := range rings {
if len(ring.refs) < 2 {
@ -114,11 +114,11 @@ func mergeRings(rings []*Ring) []*Ring {
endpoints[right] = ring
}
}
uniqueRings := make(map[*Ring]bool)
uniqueRings := make(map[*ring]bool)
for _, ring := range endpoints {
uniqueRings[ring] = true
}
result := make([]*Ring, 0, len(uniqueRings))
result := make([]*ring, 0, len(uniqueRings))
for ring, _ := range uniqueRings {
result = append(result, ring)
}

View File

@ -16,7 +16,7 @@ func TestRingMerge(t *testing.T) {
element.Node{},
element.Node{},
}
r1 := NewRing(&w1)
r1 := newRing(&w1)
w2 := element.Way{}
w2.Id = 2
@ -26,8 +26,8 @@ func TestRingMerge(t *testing.T) {
element.Node{},
element.Node{},
}
r2 := NewRing(&w2)
rings := []*Ring{r1, r2}
r2 := newRing(&w2)
rings := []*ring{r1, r2}
result := mergeRings(rings)
if len(result) != 1 {
@ -52,14 +52,14 @@ func TestRingMergeMissingRefs(t *testing.T) {
element.Node{},
element.Node{},
}
r1 := NewRing(&w1)
r1 := newRing(&w1)
w2 := element.Way{}
w2.Id = 2
w2.Refs = []int64{}
w2.Nodes = []element.Node{}
r2 := NewRing(&w2)
rings := []*Ring{r1, r2}
r2 := newRing(&w2)
rings := []*ring{r1, r2}
result := mergeRings(rings)
if len(result) != 1 {
@ -80,7 +80,7 @@ func TestRingMergeReverseEndpoints(t *testing.T) {
element.Node{},
element.Node{},
}
r1 := NewRing(&w1)
r1 := newRing(&w1)
w2 := element.Way{}
w2.Id = 2
@ -90,7 +90,7 @@ func TestRingMergeReverseEndpoints(t *testing.T) {
element.Node{},
element.Node{},
}
r2 := NewRing(&w2)
r2 := newRing(&w2)
w3 := element.Way{}
w3.Id = 3
@ -100,9 +100,9 @@ func TestRingMergeReverseEndpoints(t *testing.T) {
element.Node{},
element.Node{},
}
r3 := NewRing(&w3)
r3 := newRing(&w3)
rings := []*Ring{r1, r2, r3}
rings := []*ring{r1, r2, r3}
result := mergeRings(rings)
if len(result) != 1 {
@ -168,11 +168,11 @@ func TestRingMergePermutations(t *testing.T) {
w4.Refs = ways[indices[3]]
w4.Nodes = []element.Node{element.Node{}, element.Node{}, element.Node{}, element.Node{}}
rings := []*Ring{
&Ring{ways: []*element.Way{&w1}, refs: w1.Refs, nodes: w1.Nodes},
&Ring{ways: []*element.Way{&w2}, refs: w2.Refs, nodes: w2.Nodes},
&Ring{ways: []*element.Way{&w3}, refs: w3.Refs, nodes: w3.Nodes},
&Ring{ways: []*element.Way{&w4}, refs: w4.Refs, nodes: w4.Nodes},
rings := []*ring{
&ring{ways: []*element.Way{&w1}, refs: w1.Refs, nodes: w1.Nodes},
&ring{ways: []*element.Way{&w2}, refs: w2.Refs, nodes: w2.Nodes},
&ring{ways: []*element.Way{&w3}, refs: w3.Refs, nodes: w3.Nodes},
&ring{ways: []*element.Way{&w4}, refs: w4.Refs, nodes: w4.Nodes},
}
result := mergeRings(rings)
if len(result) != 1 {