From ff6403e5a66b59d68806c028492a39da16fd995b Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 9 May 2019 11:17:24 +0200
Subject: [PATCH] Improve search functionality

---
 autocomplete.go | 26 ++++++++++++++++++++++----
 main.go         | 16 +++++++++-------
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/autocomplete.go b/autocomplete.go
index 39ce532..036c8df 100644
--- a/autocomplete.go
+++ b/autocomplete.go
@@ -9,8 +9,10 @@ import (
 )
 
 type AutocompleteStation struct {
-	Id       int64   `json:"stop_id"`
-	Name     string  `json:"stop_name"`
+	Id                int64  `json:"stop_id"`
+	Name              string `json:"stop_name"`
+	CanonicalizedName string `json:"-"`
+	FindableName      string `json:"-"`
 	*Position
 	Distance float64 `json:"stop_distance,omitempty"`
 }
@@ -25,18 +27,34 @@ func loadAutocompleteStations() []AutocompleteStation {
 	if err = json.NewDecoder(file).Decode(&autocompleteStations); err != nil {
 		log.Fatal(err)
 	}
+	for i := range autocompleteStations {
+		autocompleteStations[i].CanonicalizedName = canonicalizeName(autocompleteStations[i].Name)
+		autocompleteStations[i].FindableName = findableName(autocompleteStations[i].Name)
+	}
 	if err = file.Close(); err != nil {
 		log.Fatal(err)
 	}
 	return autocompleteStations
 }
 
-func canonicalizeName(stationName string) string {
+func findableName(stationName string) string {
 	additionalRegex := regexp.MustCompile("\\([^(]*\\)")
 	spaceRegex := regexp.MustCompile("  +")
+
+	stationName = canonicalizeName(stationName)
 	stationName = additionalRegex.ReplaceAllString(stationName, "")
 	stationName = spaceRegex.ReplaceAllString(stationName, " ")
 	stationName = strings.TrimSpace(stationName)
-	stationName = strings.TrimSuffix(stationName, " Hbf")
+	stationName = strings.TrimSuffix(stationName, " hbf")
+	return stationName
+}
+
+func canonicalizeName(stationName string) string {
+	stationName = strings.ToLower(stationName)
+	stationName = strings.TrimSpace(stationName)
+	stationName = strings.ReplaceAll(stationName, "ü", "ue")
+	stationName = strings.ReplaceAll(stationName, "ä", "ae")
+	stationName = strings.ReplaceAll(stationName, "ö", "oe")
+	stationName = strings.ReplaceAll(stationName, "ß", "ss")
 	return stationName
 }
diff --git a/main.go b/main.go
index 9c9e2ac..a9245dc 100644
--- a/main.go
+++ b/main.go
@@ -79,20 +79,22 @@ func main() {
 	}
 
 	http.HandleFunc("/autocomplete/", func(w http.ResponseWriter, r *http.Request) {
-		if stationName := strings.TrimSpace(r.FormValue("name")); stationName != "" {
+		if query := canonicalizeName(r.FormValue("name")); query != "" {
 			var perfectMatch []AutocompleteStation
 			var prefix []AutocompleteStation
 			var contains []AutocompleteStation
 
+			findableQuery := findableName(query)
+
 			for _, station := range autocompleteStations {
-				findableName := canonicalizeName(station.Name)
-				if strings.EqualFold(station.Name, stationName) {
-					perfectMatch = append(perfectMatch, station)
-				} else if strings.EqualFold(findableName, stationName) {
+				if strings.EqualFold(station.CanonicalizedName, query) ||
+					strings.EqualFold(station.FindableName, query) {
 					perfectMatch = append(perfectMatch, station)
-				} else if strings.HasPrefix(station.Name, stationName) {
+				} else if strings.HasPrefix(station.CanonicalizedName, query) ||
+					strings.HasPrefix(station.FindableName, findableQuery) {
 					prefix = append(prefix, station)
-				} else if strings.Contains(station.Name, stationName) {
+				} else if strings.Contains(station.CanonicalizedName, query) ||
+					strings.Contains(station.FindableName, findableQuery) {
 					contains = append(contains, station)
 				}
 
-- 
GitLab