view cmd/octree2contour/store.go @ 925:15bf101e1522

Send 2D X/Y vertices to the database directly instead of sending 3D data and dropping the Z value afterwards.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sat, 06 Oct 2018 13:34:51 +0200
parents 52cb0b82b490
children
line wrap: on
line source

package main

import (
	"database/sql"
	"time"

	"gemma.intevation.de/gemma/pkg/octree"
)

type result struct {
	h     float64
	lines octree.MultiLineStringZ
}

const (
	deleteSQL = `
DELETE FROM waterway.sounding_results_contour_lines
WHERE sounding_result_id IN (SELECT id
FROM waterway.sounding_results
WHERE bottleneck_id = $1 AND date_info = $2)
`
	insertSQL = `
INSERT INTO waterway.sounding_results_contour_lines
  (sounding_result_id, height, lines)
SELECT
  sr.id,
  $1,
  ST_Transform(
    ST_Multi(
      ST_CollectionExtract(
        ST_Intersection(
          ST_Transform(sr.area::geometry, $3::integer),
          ST_SimplifyPreserveTopology(
            ST_LineMerge(ST_GeomFromWKB($2, $3::integer)),
            $6
          )
        ),
        2
      )
    ),
    4326
  )
FROM waterway.sounding_results sr
WHERE bottleneck_id = $4 AND date_info = $5
`
)

func store(
	all []result, epsg uint32,
	bottleneck string, date time.Time,
	tol float64,
) error {

	return run(func(db *sql.DB) error {

		tx, err := db.Begin()
		if err != nil {
			return err
		}
		defer tx.Rollback()

		if _, err := tx.Exec(deleteSQL, bottleneck, date); err != nil {
			return err
		}

		stmt, err := tx.Prepare(insertSQL)
		if err != nil {
			return err
		}

		for _, r := range all {
			if _, err := stmt.Exec(
				r.h, r.lines.AsWKB2D(), epsg,
				bottleneck, date,
				tol,
			); err != nil {
				return err
			}
		}

		return tx.Commit()
	})
}