# HG changeset patch # User Sascha L. Teichmann # Date 1625662650 -7200 # Node ID 31b0e865e7a0180f0bc355a0199d4522c6a0a878 # Parent 4ad68ab239b7cabdaa492a0bcfc2831f1a8ed919 Stored marking points in database. diff -r 4ad68ab239b7 -r 31b0e865e7a0 pkg/imports/sr.go --- 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) } diff -r 4ad68ab239b7 -r 31b0e865e7a0 pkg/mesh/vertex.go --- a/pkg/mesh/vertex.go Wed Jul 07 12:01:28 2021 +0200 +++ b/pkg/mesh/vertex.go Wed Jul 07 14:57:30 2021 +0200 @@ -1136,12 +1136,13 @@ // FilterRemoved returns an iterator that only delivers the vertices // which indices are not marked as removed. -func (mpz MultiPointZ) FilterRemoved(removed map[int]struct{}) func() (Vertex, bool) { - var idx int - return func() (Vertex, bool) { +func (mpz MultiPointZ) FilterRemoved(removed map[int32]struct{}) func() (Vertex, bool) { + var idx int32 + return func() (v Vertex, ok bool) { for { - if idx >= len(mpz) { - return Vertex{}, false + if idx >= int32(len(mpz)) { + ok = false + return } if _, rm := removed[idx]; rm { idx++ @@ -1149,7 +1150,9 @@ } break } - return mpz[idx], true + v, ok = mpz[idx], true + idx++ + return } }