Mercurial > gemma
diff cmd/octree2contour/store.go @ 694:a9783d8f74ed octree
octree: Store contour lines into postgres/postgis.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 20 Sep 2018 15:50:07 +0200 |
parents | |
children | c0bba602b60e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd/octree2contour/store.go Thu Sep 20 15:50:07 2018 +0200 @@ -0,0 +1,75 @@ +package main + +import ( + "bytes" + "database/sql" + "encoding/binary" + "math" +) + +type multiLineStringZ [][]vertex + +const ( + wkbNDR byte = 1 + wkbPointZ uint32 = 1000 + 1 + wkbLineStringZ uint32 = 1000 + 2 + wkbMultiLineStringZ uint32 = 1000 + 5 +) + +type result struct { + h float64 + lines multiLineStringZ +} + +const insertSQL = ` +INSERT INTO waterway.contour_lines (height, geom) +VALUES ($1, ST_Transform( + ST_SetSRID(ST_GeomFromWKB($2), $3), 4326)::geography) +` + +func store(all []result, epsg uint32) error { + + return run(func(db *sql.DB) error { + + tx, err := db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + stmt, err := tx.Prepare(insertSQL) + if err != nil { + return err + } + + for _, r := range all { + if _, err := stmt.Exec(r.h, r.lines.asWKB(), epsg); err != nil { + return err + } + } + + return tx.Commit() + }) +} + +func (mls multiLineStringZ) asWKB() []byte { + + var buf bytes.Buffer + + binary.Write(&buf, binary.LittleEndian, wkbNDR) + binary.Write(&buf, binary.LittleEndian, wkbMultiLineStringZ) + binary.Write(&buf, binary.LittleEndian, uint32(len(mls))) + + for _, ml := range mls { + binary.Write(&buf, binary.LittleEndian, wkbNDR) + binary.Write(&buf, binary.LittleEndian, wkbLineStringZ) + binary.Write(&buf, binary.LittleEndian, uint32(len(ml))) + for _, p := range ml { + binary.Write(&buf, binary.LittleEndian, math.Float64bits(p.x)) + binary.Write(&buf, binary.LittleEndian, math.Float64bits(p.y)) + binary.Write(&buf, binary.LittleEndian, math.Float64bits(p.z)) + } + } + + return buf.Bytes() +}