diff pkg/octree/tin.go @ 971:f9fb6c399f3f

Moved generating of tins to octree package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 18 Oct 2018 11:52:13 +0200
parents a4fe07a21ba7
children a244b18cb916
line wrap: on
line diff
--- a/pkg/octree/tin.go	Thu Oct 18 10:14:46 2018 +0200
+++ b/pkg/octree/tin.go	Thu Oct 18 11:52:13 2018 +0200
@@ -2,12 +2,15 @@
 
 import (
 	"bytes"
+	"context"
+	"database/sql"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"io"
 	"log"
 	"math"
+	"time"
 )
 
 var (
@@ -165,8 +168,69 @@
 	return nil
 }
 
+const (
+	tinSQLPrefix = `WITH trans AS (
+  SELECT
+	ST_Buffer(ST_Transform(area::geometry, $1::int), 0.001) AS area,
+	ST_Transform(point_cloud::geometry, $1::int) AS point_cloud
+  FROM waterway.sounding_results
+`
+	tinSQLSuffix = `
+),
+triangles AS (
+  SELECT t.geom AS geom, ST_MakePolygon(ST_ExteriorRing(t.geom)) AS poly FROM (
+    SELECT (ST_Dump(
+      ST_DelaunayTriangles(point_cloud, 0, 2))).geom
+    FROM trans) t
+)
+SELECT ST_AsBinary(ST_Collect(triangles.geom)) FROM triangles, trans
+WHERE ST_Covers(trans.area, triangles.poly)`
+
+	loadTinSQL     = tinSQLPrefix + `WHERE bottleneck_id = $2 AND date_info = $3` + tinSQLSuffix
+	loadTinByIDSQL = tinSQLPrefix + `WHERE id = $2` + tinSQLSuffix
+)
+
+func GenerateTin(
+	conn *sql.Conn,
+	ctx context.Context,
+	bottleneck string,
+	date time.Time,
+	epsg uint32,
+) (*Tin, error) {
+	var tin Tin
+	err := conn.QueryRowContext(ctx, loadTinSQL, epsg, bottleneck, date).Scan(&tin)
+	switch {
+	case err == sql.ErrNoRows:
+		return nil, nil
+	case err != nil:
+		return nil, err
+	}
+	tin.EPSG = epsg
+	return &tin, nil
+}
+
+func GenerateTinByID(
+	conn *sql.Conn,
+	ctx context.Context,
+	id int64,
+	epsg uint32,
+) (*Tin, error) {
+	var tin Tin
+	err := conn.QueryRowContext(ctx, loadTinByIDSQL, epsg, id).Scan(&tin)
+	switch {
+	case err == sql.ErrNoRows:
+		return nil, nil
+	case err != nil:
+		return nil, err
+	}
+	tin.EPSG = epsg
+	return &tin, nil
+}
+
 func (t *Tin) Scan(raw interface{}) error {
-
+	if raw == nil {
+		return nil
+	}
 	data, ok := raw.([]byte)
 	if !ok {
 		return errNoByteSlice