changeset 762:01ba06da8f46

Factored repojection of coordinates to own logic as we need it to reproject the results of the cross sections back to WGS84.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 25 Sep 2018 10:35:17 +0200
parents 033975d49c90
children d05bc3e34338
files pkg/controllers/octreecross.go pkg/models/reproject.go
diffstat 2 files changed, 63 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/octreecross.go	Tue Sep 25 10:09:33 2018 +0200
+++ b/pkg/controllers/octreecross.go	Tue Sep 25 10:35:17 2018 +0200
@@ -11,32 +11,18 @@
 	"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,
+	rp *models.Reprojector,
+	src models.GeoJSONLineCoordinates,
 	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 {
-		if err := stmt.QueryRowContext(
-			ctx,
-			s.Lat, s.Lon,
-			fromEPSG, toEPSG,
-		).Scan(&dst[i].Lat, &dst[i].Lon); err != nil {
+		var err error
+		if dst[i].Lat, dst[i].Lon, err = rp.Reproject(
+			s.Lat, s.Lon, ctx,
+		); err != nil {
 			return nil, err
 		}
 	}
@@ -68,10 +54,16 @@
 
 	start = time.Now()
 
-	coords, err := reproject(
+	var rp *models.Reprojector
+	if rp, err = models.NewReprojector(
 		conn, req.Context(),
-		csi.Geometry.Coordinates,
-		4326, tree.EPSG)
+		4326, tree.EPSG,
+	); err != nil {
+		return
+	}
+	defer rp.Close()
+
+	coords, err := reproject(rp, csi.Geometry.Coordinates, req.Context())
 
 	log.Printf("transforming input coords took: %s\n", time.Since(start))
 	if err != nil {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/models/reproject.go	Tue Sep 25 10:35:17 2018 +0200
@@ -0,0 +1,48 @@
+package models
+
+import (
+	"context"
+	"database/sql"
+)
+
+const reprojectSQL = `
+SELECT ST_X(p), ST_Y(p)
+FROM ST_Transform(ST_SetSRID(ST_MakePoint($1, $2), $3::integer), $4::integer) AS p`
+
+type Reprojector struct {
+	stmt     *sql.Stmt
+	FromEPSG uint32
+	ToEPSG   uint32
+}
+
+func NewReprojector(
+	conn *sql.Conn,
+	ctx context.Context,
+	fromEPSG, toEPSG uint32,
+) (*Reprojector, error) {
+	stmt, err := conn.PrepareContext(ctx, reprojectSQL)
+	if err != nil {
+		return nil, err
+	}
+	return &Reprojector{
+		stmt:     stmt,
+		FromEPSG: fromEPSG,
+		ToEPSG:   toEPSG,
+	}, nil
+}
+
+func (r *Reprojector) Close() error {
+	if s := r.stmt; s != nil {
+		r.stmt = nil
+		return s.Close()
+	}
+	return nil
+}
+
+func (r *Reprojector) Reproject(
+	x, y float64,
+	ctx context.Context,
+) (v, w float64, err error) {
+	err = r.stmt.QueryRowContext(ctx, x, y, r.FromEPSG, r.ToEPSG).Scan(&v, &w)
+	return
+}