package api import ( "encoding/json" "io/ioutil" "log" "net/http" "os" "strings" "unicode" "github.com/gin-gonic/gin" "golang.org/x/text/transform" "golang.org/x/text/unicode/norm" ) type IDFMStation struct { DatasetID string `json:"datasetid"` RecordIDs string `json:"recordid"` Fields struct { Id string `json:"id"` PointGeo []float64 `json:"pointgeo"` StopId string `json:"stop_id"` StopName string `json:"stop_name"` OperatorName string `json:"operatorname"` NomCommune string `json:"nom_commune"` RouteLongName string `json:"route_long_name"` StopLat string `json:"stop_lat"` StopLon string `json:"stop_lon"` CodeINSEE string `json:"code_insee"` } `json:"fields"` Geometry struct { Type string `json:"type"` Coordinates []float64 `json:"coordinates"` } `json:"geometry"` } func (s *IDFMStation) ComputeSlug() string { isMn := func(r rune) bool { return unicode.Is(unicode.Mn, r) // Mn: nonspacing marks } t := transform.Chain(norm.NFD, transform.RemoveFunc(isMn), norm.NFC) r, _ := ioutil.ReadAll(transform.NewReader(strings.NewReader(s.Fields.StopName), t)) return strings.ToLower(strings.Replace(strings.Replace(strings.Replace(string(r), " ", "+", -1), "'", "+", -1), "-", "+", -1)) } type PGStation struct { Id string `json:"slug"` Name string `json:"name"` } var IDFMStations []IDFMStation func init() { fd, err := os.Open("arrets-lignes.json") if err != nil { log.Fatal("Unable to open `arrets-lignes.json`:", err.Error()) } defer fd.Close() dec := json.NewDecoder(fd) if err = dec.Decode(&IDFMStations); err != nil { log.Fatal("Unable to decode `arrets-lignes.json`:", err.Error()) } } func searchStation(code, station string) ([]string, error) { code = "IDFM:" + strings.TrimPrefix(code, "line:IDFM:") var res []string for _, st := range IDFMStations { if st.Fields.Id == code && st.ComputeSlug() == station { if strings.HasPrefix(st.Fields.StopId, "IDFM:monomodalStopPlace:") { res = append(res, "STIF:StopArea:SP:"+strings.TrimPrefix(strings.TrimPrefix(st.Fields.StopId, "IDFM:"), "monomodalStopPlace:")+":") } else { res = append(res, "STIF:StopPoint:Q:"+strings.TrimPrefix(st.Fields.StopId, "IDFM:")+":") } } } if len(res) == 0 { return []string{station}, nil } else { return res, nil } } func declareStationsRoutes(router *gin.RouterGroup) { router.GET("/stations/:type/:code", func(c *gin.Context) { code := convertLineCode(string(c.Param("code"))) var stations []PGStation for _, station := range IDFMStations { if station.Fields.Id == "IDFM:"+code { pgstation := PGStation{ Id: station.ComputeSlug(), Name: station.Fields.StopName, } stations = append(stations, pgstation) } } c.JSON(http.StatusOK, APIResult(c, map[string][]PGStation{ "stations": stations, })) }) }