improve memory handling of geos geometries
parent
4739fcc484
commit
5eed0502ea
14
geom/geom.go
14
geom/geom.go
|
@ -86,7 +86,6 @@ func PolygonWkb(g *geos.Geos, nodes []element.Node) (*element.Geometry, error) {
|
|||
if wkb == nil {
|
||||
return nil, errors.New("could not create wkb")
|
||||
}
|
||||
g.DestroyLater(geom)
|
||||
return &element.Geometry{
|
||||
Wkb: wkb,
|
||||
Geom: geom,
|
||||
|
@ -105,15 +104,18 @@ func Polygon(g *geos.Geos, nodes []element.Node) (*geos.Geom, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
geom, err := coordSeq.AsLinearRing(g)
|
||||
ring, err := coordSeq.AsLinearRing(g)
|
||||
if err != nil {
|
||||
g.DestroyCoordSeq(coordSeq)
|
||||
return nil, err
|
||||
}
|
||||
// geom inherited by Polygon, no destroy
|
||||
// ring inherited by Polygon, no destroy
|
||||
|
||||
geom = g.CreatePolygon(geom, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
geom := g.CreatePolygon(ring, nil)
|
||||
if geom == nil {
|
||||
g.Destroy(ring)
|
||||
return nil, errors.New("unable to create polygon")
|
||||
}
|
||||
g.DestroyLater(geom)
|
||||
return geom, nil
|
||||
}
|
||||
|
|
|
@ -55,6 +55,28 @@ func TestPolygonNotClosed(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPolygonIntersection(t *testing.T) {
|
||||
nodes := []element.Node{
|
||||
element.Node{Lat: 0, Long: 0},
|
||||
element.Node{Lat: 0, Long: 10},
|
||||
element.Node{Lat: 10, Long: 10},
|
||||
element.Node{Lat: 10, Long: 0},
|
||||
element.Node{Lat: 0, Long: 0},
|
||||
}
|
||||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
geom, err := Polygon(g, nodes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
result := g.Intersection(geom, g.FromWkt("LINESTRING(-10 5, 20 5)"))
|
||||
|
||||
if !g.Equals(result, g.FromWkt("LINESTRING(0 5, 10 5)")) {
|
||||
t.Fatal(g.AsWkt(result))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLineString(b *testing.B) {
|
||||
size := 16
|
||||
nodes := make([]element.Node, size)
|
||||
|
|
|
@ -367,13 +367,25 @@ func (this *Geos) AsWkb(geom *Geom) []byte {
|
|||
}
|
||||
|
||||
func (this *Geos) FromWkb(wkb []byte) *Geom {
|
||||
geom := C.GEOSGeomFromWKB_buf((*C.uchar)(&wkb[0]), C.size_t(len(wkb)))
|
||||
geom := C.GEOSGeomFromWKB_buf_r(this.v, (*C.uchar)(&wkb[0]), C.size_t(len(wkb)))
|
||||
if geom == nil {
|
||||
return nil
|
||||
}
|
||||
return &Geom{geom}
|
||||
}
|
||||
|
||||
func (this *Geos) Clone(geom *Geom) *Geom {
|
||||
if geom == nil || geom.v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := C.GEOSGeom_clone_r(this.v, geom.v)
|
||||
if result == nil {
|
||||
return nil
|
||||
}
|
||||
return &Geom{result}
|
||||
}
|
||||
|
||||
func (this *Geos) IsValid(geom *Geom) bool {
|
||||
if C.GEOSisValid_r(this.v, geom.v) == 1 {
|
||||
return true
|
||||
|
@ -415,6 +427,14 @@ func (this *Geom) Length() float64 {
|
|||
}
|
||||
}
|
||||
|
||||
func (this *Geos) Equals(a, b *Geom) bool {
|
||||
result := C.GEOSEquals_r(this.v, a.v, b.v)
|
||||
if result == 1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var NilBounds = Bounds{1e20, 1e20, -1e20, -1e20}
|
||||
|
||||
func (this *Geom) Bounds() Bounds {
|
||||
|
|
|
@ -119,14 +119,14 @@ func BuildRelGeometry(rel *element.Relation, rings []*Ring) (*geos.Geom, error)
|
|||
var interiors []*geos.Geom
|
||||
for hole, _ := range shell.holes {
|
||||
hole.MarkInserted(relTags)
|
||||
ring := g.ExteriorRing(hole.geom)
|
||||
ring := g.Clone(g.ExteriorRing(hole.geom))
|
||||
if ring == nil {
|
||||
return nil, errors.New("Error while getting exterior ring.")
|
||||
}
|
||||
interiors = append(interiors, ring)
|
||||
}
|
||||
shell.MarkInserted(relTags)
|
||||
exterior := g.ExteriorRing(shell.geom)
|
||||
exterior := g.Clone(g.ExteriorRing(shell.geom))
|
||||
if exterior == nil {
|
||||
return nil, errors.New("Error while getting exterior ring.")
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ func BuildRelGeometry(rel *element.Relation, rings []*Ring) (*geos.Geom, error)
|
|||
return nil, errors.New("Error while building multi-polygon.")
|
||||
}
|
||||
}
|
||||
g.DestroyLater(result)
|
||||
|
||||
insertedWays := make(map[int64]bool)
|
||||
for _, r := range rings {
|
||||
|
|
Loading…
Reference in New Issue