first ogr geom reader
parent
5b66ef9866
commit
ba083239f8
|
@ -212,6 +212,14 @@ func (this *GEOS) AsWKB(geom *Geom) []byte {
|
|||
return result
|
||||
}
|
||||
|
||||
func (this *GEOS) FromWkb(wkb []byte) *Geom {
|
||||
geom := C.GEOSGeomFromWKB_buf((*C.uchar)(&wkb[0]), C.size_t(len(wkb)))
|
||||
if geom == nil {
|
||||
return nil
|
||||
}
|
||||
return &Geom{geom}
|
||||
}
|
||||
|
||||
func (this *GEOS) IsValid(geom *Geom) bool {
|
||||
if C.GEOSisValid_r(this.v, geom.v) == 1 {
|
||||
return true
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -lgdal
|
||||
#include "ogr_api.h"
|
||||
#include "cpl_error.h"
|
||||
#include "cpl_conv.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"goposm/geom/geos"
|
||||
"log"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func init() {
|
||||
C.OGRRegisterAll()
|
||||
}
|
||||
|
||||
type DataSource struct {
|
||||
v C.OGRDataSourceH
|
||||
}
|
||||
|
||||
type Layer struct {
|
||||
v C.OGRLayerH
|
||||
}
|
||||
type OgrError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e *OgrError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func lastOgrError(fallback string) error {
|
||||
msg := C.CPLGetLastErrorMsg()
|
||||
if msg == nil {
|
||||
return &OgrError{fallback}
|
||||
}
|
||||
str := C.GoString(msg)
|
||||
if str == "" {
|
||||
return &OgrError{fallback}
|
||||
}
|
||||
return &OgrError{str}
|
||||
}
|
||||
|
||||
func Open(name string) (*DataSource, error) {
|
||||
namec := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(namec))
|
||||
ds := C.OGROpen(namec, 0, nil)
|
||||
if ds == nil {
|
||||
return nil, lastOgrError("failed to open")
|
||||
}
|
||||
return &DataSource{ds}, nil
|
||||
}
|
||||
|
||||
func (ds *DataSource) Layer() (*Layer, error) {
|
||||
layer := C.OGR_DS_GetLayer(ds.v, 0)
|
||||
if layer == nil {
|
||||
return nil, lastOgrError("failed to get layer 0")
|
||||
}
|
||||
return &Layer{layer}, nil
|
||||
}
|
||||
|
||||
func (ds *DataSource) Query(query string) (*Layer, error) {
|
||||
// create select query if it is only a where statement
|
||||
if !strings.HasPrefix(strings.ToLower(query), "select") {
|
||||
layer, err := ds.Layer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layerDef := C.OGR_L_GetLayerDefn(layer.v)
|
||||
name := C.OGR_FD_GetName(layerDef)
|
||||
query = fmt.Sprintf("SELECT * FROM %s WHERE %s", C.GoString(name), query)
|
||||
}
|
||||
queryc := C.CString(query)
|
||||
defer C.free(unsafe.Pointer(queryc))
|
||||
layer := C.OGR_DS_ExecuteSQL(ds.v, queryc, nil, nil)
|
||||
if layer == nil {
|
||||
return nil, lastOgrError("unable to execute query '" + query + "'")
|
||||
}
|
||||
return &Layer{layer}, nil
|
||||
}
|
||||
|
||||
func (layer *Layer) Wkts() chan string {
|
||||
wkts := make(chan string)
|
||||
|
||||
go func() {
|
||||
defer close(wkts)
|
||||
|
||||
C.OGR_L_ResetReading(layer.v)
|
||||
for {
|
||||
feature := C.OGR_L_GetNextFeature(layer.v)
|
||||
if feature == nil {
|
||||
break
|
||||
}
|
||||
geom := C.OGR_F_GetGeometryRef(feature)
|
||||
var res *C.char
|
||||
C.OGR_G_ExportToWkt(geom, &res)
|
||||
wkts <- C.GoString(res)
|
||||
C.CPLFree(unsafe.Pointer(res))
|
||||
C.OGR_F_Destroy(feature)
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
return wkts
|
||||
}
|
||||
|
||||
func (layer *Layer) Wkbs() chan []byte {
|
||||
wkbs := make(chan []byte)
|
||||
|
||||
go func() {
|
||||
defer close(wkbs)
|
||||
|
||||
C.OGR_L_ResetReading(layer.v)
|
||||
for {
|
||||
feature := C.OGR_L_GetNextFeature(layer.v)
|
||||
if feature == nil {
|
||||
break
|
||||
}
|
||||
geom := C.OGR_F_GetGeometryRef(feature)
|
||||
size := C.OGR_G_WkbSize(geom)
|
||||
buf := make([]byte, size)
|
||||
C.OGR_G_ExportToWkb(geom, C.wkbNDR, (*C.uchar)(&buf[0]))
|
||||
wkbs <- buf
|
||||
C.OGR_F_Destroy(feature)
|
||||
}
|
||||
}()
|
||||
return wkbs
|
||||
}
|
||||
|
||||
func (layer *Layer) Geoms() chan *geos.Geom {
|
||||
geoms := make(chan *geos.Geom)
|
||||
|
||||
go func() {
|
||||
defer close(geoms)
|
||||
g := geos.NewGEOS()
|
||||
defer g.Finish()
|
||||
|
||||
wkbs := layer.Wkbs()
|
||||
for wkb := range wkbs {
|
||||
geom := g.FromWkb(wkb)
|
||||
geoms <- geom
|
||||
}
|
||||
}()
|
||||
return geoms
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
ds, err := Open(flag.Arg(0))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
layer, err := ds.Query(flag.Arg(1))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
g := geos.NewGEOS()
|
||||
defer g.Finish()
|
||||
for geom := range layer.Geoms() {
|
||||
fmt.Println(g.AsWKT(geom))
|
||||
}
|
||||
|
||||
fmt.Println(layer)
|
||||
}
|
Loading…
Reference in New Issue