view pkg/controllers/octreecross.go @ 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
children 1a1a8b5f2d02
line wrap: on
line source

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
}