diff pkg/imports/sr.go @ 5416:31b0e865e7a0 marking-single-beam

Stored marking points in database.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 07 Jul 2021 14:57:30 +0200
parents 4ad68ab239b7
children 2d294ad81241
line wrap: on
line diff
--- a/pkg/imports/sr.go	Wed Jul 07 12:01:28 2021 +0200
+++ b/pkg/imports/sr.go	Wed Jul 07 14:57:30 2021 +0200
@@ -24,6 +24,7 @@
 	"errors"
 	"fmt"
 	"io"
+	"log"
 	"math"
 	"os"
 	"path"
@@ -198,6 +199,19 @@
 FROM waterway.sounding_results sr
 WHERE id = $1
 `
+	insertMarkingPointsSQL = `
+INSERT INTO waterway.sounding_results_marking_points (
+  sounding_result_id,
+  height,
+  points
+)
+SELECT
+  $1,
+  $2,
+  ST_Transform(ST_Force2D(ST_GeomFromWKB($4, $3::integer)), 4326)
+FROM waterway.sounding_results sr
+WHERE id = $1
+`
 
 	selectGaugeLDCSQL = `
 SELECT
@@ -431,14 +445,13 @@
 
 	start := time.Now()
 
-	xyzWKB := xyz.AsWKB()
 	var reproj []byte
 	var epsg uint32
 
 	if err := tx.QueryRowContext(
 		ctx,
 		reprojectPointsSingleBeamSQL,
-		xyzWKB,
+		xyz.AsWKB(),
 		m.EPSG,
 	).Scan(&reproj, &epsg); err != nil {
 		return nil, err
@@ -683,12 +696,17 @@
 			return nil, err
 		}
 		feedback.Info("Storing mesh index took %s.", time.Since(start))
-		err = generateIsos(ctx, tx, feedback, &final, id)
-		if err != nil {
+		if err := generateIsos(ctx, tx, feedback, &final, id); err != nil {
 			return nil, err
 		}
 	} else { // SurveyTypeMarking
-		return nil, errors.New("not implemented, yet")
+		if err := generateMarkingPoints(
+			ctx, tx, feedback,
+			xyz, removed, epsg,
+			id,
+		); err != nil {
+			return nil, err
+		}
 	}
 
 	// Store for potential later removal.
@@ -908,20 +926,16 @@
 	return heights
 }
 
-func generateIsos(
+func loadClassBreaks(
 	ctx context.Context,
 	tx *sql.Tx,
 	feedback Feedback,
-	tree *mesh.STRTree,
-	id int64,
-) error {
+	minZ, maxZ float64,
+) mesh.ClassBreaks {
 
 	heights, err := mesh.LoadClassBreaks(
 		ctx, tx,
-		"morphology_classbreaks",
-	)
-
-	minZ, maxZ := tree.Min().Z, tree.Max().Z
+		"morphology_classbreaks")
 
 	if err != nil {
 		feedback.Warn("Loading class breaks failed: %v", err)
@@ -931,14 +945,68 @@
 		heights = heights.ExtrapolateClassBreaks(minZ, maxZ)
 	}
 
-	/*
-		for i, v := range heights {
-			fmt.Printf("%d %.2f\n", i, v)
+	return heights.Dedup()
+}
+
+func generateMarkingPoints(
+	ctx context.Context,
+	tx *sql.Tx,
+	feedback Feedback,
+	xyz mesh.MultiPointZ,
+	removed map[int32]struct{},
+	epsg uint32,
+	id int64,
+) error {
+	log.Printf("debug: generateMarkingPoints")
+
+	min, max := mesh.MinMaxVertex(xyz.FilterRemoved(removed))
+
+	log.Printf("debug: min/max %.2f/%.2f\n", min.Z, max.Z)
+
+	heights := loadClassBreaks(ctx, tx, feedback, min.Z, max.Z)
+
+	classes := heights.Classify(xyz.FilterRemoved(removed))
+
+	log.Printf("debug: removed %d\n", len(removed))
+
+	// Should not happen ... Z values over the top.
+	if n := len(classes) - 1; n > 1 && len(classes[n]) > 0 {
+		// Place the over the top values to the class below.
+		classes[n-1] = append(classes[n-1], classes[n]...)
+		classes[n] = nil
+		classes = classes[:n]
+	}
+
+	stmt, err := tx.PrepareContext(ctx, insertMarkingPointsSQL)
+	if err != nil {
+		return err
+	}
+	defer stmt.Close()
+
+	for i, class := range classes {
+		// Ignore empty classes
+		if len(class) == 0 {
+			continue
 		}
-		log.Printf("%.2f - %.2f\n", tree.Min.Z, tree.Max.Z)
-	*/
+		log.Printf("debug: class %d: %d\n", i, len(class))
+		_, err := stmt.ExecContext(ctx, id, heights[i], epsg, class.AsWKB())
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
 
-	heights = heights.Dedup()
+func generateIsos(
+	ctx context.Context,
+	tx *sql.Tx,
+	feedback Feedback,
+	tree *mesh.STRTree,
+	id int64,
+) error {
+
+	heights := loadClassBreaks(ctx, tx, feedback, tree.Min().Z, tree.Max().Z)
 
 	return generateIsoAreas(ctx, tx, feedback, tree, heights, id)
 }