changeset 753:e6f8d58434f4

Added stub for octree based cross sections.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 24 Sep 2018 17:10:18 +0200
parents f09cbe80a864
children 105c421f99b1
files pkg/controllers/octreecross.go pkg/controllers/routes.go
diffstat 2 files changed, 92 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/octreecross.go	Mon Sep 24 17:10:18 2018 +0200
@@ -0,0 +1,87 @@
+package controllers
+
+import (
+	"context"
+	"database/sql"
+	"log"
+	"net/http"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/models"
+	"gemma.intevation.de/gemma/pkg/octree"
+)
+
+const (
+	reprojectSQL = `
+SELECT ST_X(p), ST_Y(p)
+FROM ST_Transform(ST_SetSRID(ST_MakePoint($1, $2), $3::integer), $4::integer) AS p`
+)
+
+func reproject(
+	conn *sql.Conn,
+	ctx context.Context,
+	src models.GeoJSONLineCoordinates,
+	fromEPSG, toEPSG uint32,
+) (models.GeoJSONLineCoordinates, error) {
+
+	stmt, err := conn.PrepareContext(ctx, reprojectSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer stmt.Close()
+
+	dst := make(models.GeoJSONLineCoordinates, len(src))
+	for i, s := range src {
+		d := &dst[i]
+		if err := stmt.QueryRowContext(
+			ctx,
+			s.Lat, s.Lon,
+			fromEPSG, toEPSG,
+		).Scan(&d.Lat, &d.Lon); err != nil {
+			return nil, err
+		}
+	}
+	return dst, nil
+}
+
+func octreeCrossSection(
+	input interface{},
+	req *http.Request,
+	conn *sql.Conn,
+) (jr JSONResult, err error) {
+
+	csi := input.(*models.CrossSectionInput)
+
+	start := time.Now()
+
+	tree, err := octree.Cache.Get(
+		csi.Properties.Bottleneck, csi.Properties.Date.Time,
+		conn, req.Context())
+
+	log.Printf("loading octree took: %s\n", time.Since(start))
+	if err != nil {
+		return
+	}
+
+	// The coordinate system of the octree is an UTM projection.
+	// The input coordinates are in WGS84.
+	// So we need to reproject them.
+
+	start = time.Now()
+
+	coords, err := reproject(
+		conn, req.Context(),
+		csi.Geometry.Coordinates,
+		4326, tree.EPSG)
+
+	log.Printf("transforming input coords took: %s\n", time.Since(start))
+	if err != nil {
+		return
+	}
+
+	for i := 0; i < len(coords)-1; i++ {
+		// TODO: Query segmentwise (i, i+1).
+	}
+
+	return
+}
--- a/pkg/controllers/routes.go	Mon Sep 24 16:40:54 2018 +0200
+++ b/pkg/controllers/routes.go	Mon Sep 24 17:10:18 2018 +0200
@@ -105,6 +105,11 @@
 
 	// Cross sections
 
+	api.Handle("/octcross", any(&JSONHandler{
+		Input:  func() interface{} { return new(models.CrossSectionInput) },
+		Handle: octreeCrossSection,
+	})).Methods(http.MethodPost)
+
 	api.Handle("/cross", any(&JSONHandler{
 		Input:  func() interface{} { return new(models.CrossSectionInput) },
 		Handle: crossSection,