imposm3/geom/geos/index.go

78 lines
1.8 KiB
Go
Raw Normal View History

2013-05-28 13:10:19 +04:00
package geos
/*
#cgo LDFLAGS: -lgeos_c
#include "geos_c.h"
#include <stdlib.h>
2013-08-09 12:08:30 +04:00
#include <stdint.h>
2013-05-28 13:10:19 +04:00
2013-08-09 12:08:30 +04:00
extern void IndexQueryCallback(void *, void *);
2013-05-28 13:10:19 +04:00
extern void goIndexSendQueryResult(size_t, void *);
2013-08-09 12:08:30 +04:00
extern uint32_t *IndexQuery(GEOSContextHandle_t, GEOSSTRtree *, const GEOSGeometry *, uint32_t *);
2013-05-28 13:10:19 +04:00
extern void IndexAdd(GEOSContextHandle_t, GEOSSTRtree *, const GEOSGeometry *, size_t);
*/
import "C"
import (
"sync"
"unsafe"
)
// IndexGeom is a struct for indexed geometries used by Index
// and returned by IndexQuery.
2013-05-28 13:10:19 +04:00
type IndexGeom struct {
Geom *Geom
2013-05-28 13:10:19 +04:00
}
type Index struct {
v *C.GEOSSTRtree
2013-08-09 16:29:33 +04:00
mu *sync.Mutex
2013-05-28 13:10:19 +04:00
geoms []IndexGeom
}
func (this *Geos) CreateIndex() *Index {
tree := C.GEOSSTRtree_create_r(this.v, 10)
if tree == nil {
panic("unable to create tree")
}
2013-08-09 16:29:33 +04:00
return &Index{tree, &sync.Mutex{}, []IndexGeom{}}
2013-05-28 13:10:19 +04:00
}
// IndexQuery adds a geom to the index with the id.
func (this *Geos) IndexAdd(index *Index, geom *Geom) {
2013-08-09 16:29:33 +04:00
index.mu.Lock()
defer index.mu.Unlock()
2013-05-28 13:10:19 +04:00
id := len(index.geoms)
C.IndexAdd(this.v, index.v, geom.v, C.size_t(id))
index.geoms = append(index.geoms, IndexGeom{geom})
2013-05-28 13:10:19 +04:00
}
2014-05-21 11:15:32 +04:00
// IndexQueryGeoms queries the index for intersections with geom.
func (this *Geos) IndexQueryGeoms(index *Index, geom *Geom) []IndexGeom {
hits := this.IndexQuery(index, geom)
var geoms []IndexGeom
for _, idx := range hits {
geoms = append(geoms, index.geoms[idx])
}
return geoms
}
2013-05-28 13:10:19 +04:00
// IndexQuery queries the index for intersections with geom.
2014-05-21 11:15:32 +04:00
func (this *Geos) IndexQuery(index *Index, geom *Geom) []int {
2013-08-09 16:29:33 +04:00
index.mu.Lock()
defer index.mu.Unlock()
2013-08-09 12:08:30 +04:00
var num C.uint32_t
r := C.IndexQuery(this.v, index.v, geom.v, &num)
if r == nil {
return nil
}
hits := (*[2 << 16]C.uint32_t)(unsafe.Pointer(r))[:num]
defer C.free(unsafe.Pointer(r))
2014-05-21 11:15:32 +04:00
indices := make([]int, len(hits))
for i := range hits {
indices[i] = int(hits[i])
2013-05-28 13:10:19 +04:00
}
2014-05-21 11:15:32 +04:00
return indices
2013-05-28 13:10:19 +04:00
}