changeset 743:fdff2de616ad

Added search function for river kilometer. This is the first iteration of the search back end. For now only the distance marks are searched.
author Sascha Wilde <wilde@intevation.de>
date Mon, 24 Sep 2018 13:26:57 +0200
parents fb9faf2c4f60
children 6fe6839f5ce6
files pkg/controllers/routes.go pkg/controllers/search.go pkg/models/search.go
diffstat 3 files changed, 99 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/routes.go	Mon Sep 24 13:14:49 2018 +0200
+++ b/pkg/controllers/routes.go	Mon Sep 24 13:26:57 2018 +0200
@@ -110,6 +110,12 @@
 		Handle: crossSection,
 	})).Methods(http.MethodPost)
 
+	// Feature search
+	api.Handle("/search", any(&JSONHandler{
+		Input:  func() interface{} { return new(models.SearchRequest) },
+		Handle: searchFeature,
+	})).Methods(http.MethodPost)
+
 	// Token handling: Login/Logout.
 	api.HandleFunc("/login", login).
 		Methods(http.MethodPost)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/search.go	Mon Sep 24 13:26:57 2018 +0200
@@ -0,0 +1,86 @@
+package controllers
+
+import (
+	"database/sql"
+	"fmt"
+	"net/http"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"gemma.intevation.de/gemma/pkg/models"
+)
+
+const (
+	searchHectometreSQL = `SELECT ST_AsGeoJSON(geom) FROM waterway.distance_marks
+WHERE (location_code).hectometre = $1`
+)
+
+var rkmRegex = regexp.MustCompile(
+	"^[[:space:]]*([0-9]+)([,.]([0-9]))?[[:space:]]*$",
+)
+
+func searchFeature(
+	input interface{},
+	req *http.Request,
+	db *sql.Conn,
+) (jr JSONResult, err error) {
+
+	s := input.(*models.SearchRequest)
+
+	if len(s.SearchString) == 0 {
+		err = JSONError{http.StatusBadRequest,
+			"error: empty search string"}
+		return
+	}
+
+	// Handle search for river kilometre:
+
+	m := rkmRegex.FindStringSubmatch(s.SearchString)
+	if len(m) != 0 {
+		var hectometre int
+		if hectometre, err = strconv.Atoi(m[1]); err != nil {
+			return
+		}
+
+		hectometre *= 10
+		if len(m) == 4 {
+			var h int
+			if h, err = strconv.Atoi(m[3]); err != nil {
+				return
+			}
+			hectometre += h
+		}
+
+		var result string
+
+		err = db.QueryRowContext(
+			req.Context(),
+			searchHectometreSQL,
+			hectometre,
+		).Scan(&result)
+
+		switch {
+		case err == sql.ErrNoRows:
+			err = JSONError{
+				Code: http.StatusNotFound,
+				Message: fmt.Sprintf("Cannot find river hectometre %d.",
+					hectometre),
+			}
+			return
+		case err != nil:
+			return
+		}
+
+		jr.Result = strings.NewReader(result)
+	} else {
+		err = JSONError{
+			Code: http.StatusNotFound,
+			Message: fmt.Sprintf("No Results for %s.",
+				s.SearchString),
+		}
+
+	}
+
+	return
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/models/search.go	Mon Sep 24 13:26:57 2018 +0200
@@ -0,0 +1,7 @@
+package models
+
+type (
+	SearchRequest struct {
+		SearchString string `json:"string"`
+	}
+)