view cmd/octree2contour/store.go @ 726:5af9ab39e715

Renamed a few types to uppercase names to prepare the move to the octree package.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sat, 22 Sep 2018 21:34:12 +0200
parents c0bba602b60e
children 41c8dc61f38f
line wrap: on
line source

package main

import (
	"bytes"
	"database/sql"
	"encoding/binary"
	"math"
)

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