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()
+}