changeset 973:b6fec8f85599

Generate TINs and octrees in sounding result importer.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 18 Oct 2018 13:09:49 +0200
parents 17a03a84b0e8
children 7a89313f0ead
files pkg/imports/sr.go pkg/octree/builder.go
diffstat 2 files changed, 70 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/imports/sr.go	Thu Oct 18 12:22:08 2018 +0200
+++ b/pkg/imports/sr.go	Thu Oct 18 13:09:49 2018 +0200
@@ -4,7 +4,9 @@
 	"archive/zip"
 	"bufio"
 	"context"
+	"crypto/sha1"
 	"database/sql"
+	"encoding/hex"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -67,6 +69,17 @@
   ELSE
     32700
   END + floor((ST_X(ST_Centroid(point_cloud::geometry))+180)/6)::int + 1`
+
+	insertOctreeSQL = `
+INSERT INTO waterway.octrees (
+  sounding_result_id,
+  checksum,
+  octree_index
+) VALUES (
+  $1,
+  $2,
+  $3
+)`
 )
 
 func (srd *SoundingResultDate) UnmarshalJSON(data []byte) error {
@@ -269,7 +282,9 @@
 		return err
 	}
 
-	tx, err := conn.BeginTx(context.Background(), nil)
+	ctx := context.Background()
+
+	tx, err := conn.BeginTx(ctx, nil)
 	if err != nil {
 		return err
 	}
@@ -277,22 +292,64 @@
 
 	var id int64
 	var epsg uint32
+	start := time.Now()
 
-	if err := tx.QueryRow(insertPointsSQL,
+	err = tx.QueryRow(insertPointsSQL,
 		m.Bottleneck,
 		m.Date.Time,
 		m.DepthReference,
 		xyz.AsWKB(),
 		polygon.AsWBK(),
 		m.EPSG,
-	).Scan(&id, &epsg); err != nil {
+	).Scan(&id, &epsg)
+	xyz, polygon = nil, nil // not need from now on.
+	log.Printf("storing points took %s\n", time.Since(start))
+	if err != nil {
 		return err
 	}
 
 	log.Printf("EPSG: %d\n", epsg)
 
-	// TODO: Build octree
+	start = time.Now()
+	tin, err := octree.GenerateTinByID(conn, ctx, id, epsg)
+	log.Printf("triangulation took %s\n", time.Since(start))
+	if err != nil {
+		return err
+	}
+
+	if tin == nil {
+		return errors.New("cannot load TIN from database")
+	}
+
+	builder := octree.NewBuilder(tin)
+	start = time.Now()
+	builder.Build()
+	octreeIndex, err := builder.Bytes()
+	builder, tin = nil, nil // not needed from now on
+	log.Printf("building octree took %s\n", time.Since(start))
+	if err != nil {
+		return err
+	}
+
+	h := sha1.New()
+	h.Write(octreeIndex)
+	checksum := hex.EncodeToString(h.Sum(nil))
+
+	start = time.Now()
+	_, err = tx.Exec(insertOctreeSQL, id, checksum, octreeIndex)
+	log.Printf("storing octree index took %s\n", time.Since(start))
+	if err != nil {
+		return err
+	}
+
+	index, err := octree.Deserialize(octreeIndex)
+	if err != nil {
+		return err
+	}
+
 	// TODO: Generate iso-lines
 
+	_ = index
+
 	return tx.Commit()
 }
--- a/pkg/octree/builder.go	Thu Oct 18 12:22:08 2018 +0200
+++ b/pkg/octree/builder.go	Thu Oct 18 13:09:49 2018 +0200
@@ -1,6 +1,7 @@
 package octree
 
 import (
+	"bytes"
 	"encoding/binary"
 	"io"
 	"log"
@@ -169,3 +170,11 @@
 	}
 	return out.Flush()
 }
+
+func (tb *Builder) Bytes() ([]byte, error) {
+	var buf bytes.Buffer
+	if err := tb.WriteTo(&buf); err != nil {
+		return nil, err
+	}
+	return buf.Bytes(), nil
+}