Files
golifehk/datasources/kmb/routestops.go

140 lines
3.2 KiB
Go

package kmb
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"path/filepath"
query "github.com/tgckpg/golifehk/query"
"github.com/tgckpg/golifehk/utils"
)
var JSON_ROUTESTOPS string = filepath.Join(utils.WORKDIR, "kmb-routestops.json")
var JSON_BUSSTOPS string = filepath.Join(utils.WORKDIR, "kmb-busstops.json")
func readRouteStopsData(busStops *map[string]*BusStop, buff *bytes.Buffer) (*[]*RouteStop, error) {
routeStopsData := RouteStops{}
err := json.Unmarshal(buff.Bytes(), &routeStopsData)
if err != nil {
return nil, err
}
// routeStops[ Route ][ ServiceType ][ Direction ][ Seq ] = RouteStop
routeStops := map[string]*map[string]*map[string]*map[int]*RouteStop{}
allRouteStops := []*RouteStop{}
for _, entry := range routeStopsData.RouteStops {
busStop := (*busStops)[entry.StationId]
if busStop == nil {
busStop = &BusStop{
BusStopId: entry.StationId,
Name_en: "???", Name_tc: "???", Name_sc: "???",
}
busStop.Reload()
(*busStops)[entry.StationId] = busStop
}
if busStop.Routes == nil {
busStopRoutes := []*RouteStop{}
busStop.Routes = &busStopRoutes
}
(*busStop.Routes) = append((*busStop.Routes), entry)
entry.BusStop = busStop
route := routeStops[entry.RouteId]
if route == nil {
route = &map[string]*map[string]*map[int]*RouteStop{}
routeStops[entry.RouteId] = route
}
service := (*route)[entry.ServiceType]
if service == nil {
service = &map[string]*map[int]*RouteStop{}
(*route)[entry.ServiceType] = service
}
direction := (*service)[entry.Direction]
if direction == nil {
direction = &map[int]*RouteStop{}
(*service)[entry.Direction] = direction
}
entry.RouteStops = direction
seq := (*direction)[entry.StationSeq]
if seq == nil {
(*direction)[entry.StationSeq] = entry
}
allRouteStops = append(allRouteStops, entry)
}
return &allRouteStops, nil
}
func readBusStopsData(buff *bytes.Buffer) (*map[string]*BusStop, error) {
busStopsData := BusStops{}
err := json.Unmarshal(buff.Bytes(), &busStopsData)
if err != nil {
return nil, err
}
busStopMap := map[string]*BusStop{}
for _, entry := range busStopsData.BusStops {
entry.Reload()
if _, ok := busStopMap[entry.BusStopId]; ok {
return nil, fmt.Errorf("Duplicated BusStop: %s", entry.BusStopId)
}
busStopMap[entry.BusStopId] = entry
}
return &busStopMap, nil
}
func getRouteStops() (*[]query.ISearchable, error) {
QUERY_FUNC := func() (io.ReadCloser, error) {
return utils.HttpGet("https://data.etabus.gov.hk/v1/transport/kmb/stop")
}
buff, err := utils.CacheStream(JSON_BUSSTOPS, QUERY_FUNC, 7*24*3600)
if err != nil {
return nil, err
}
busStopMap, err := readBusStopsData(buff)
if err != nil {
return nil, err
}
QUERY_FUNC = func() (io.ReadCloser, error) {
return utils.HttpGet("https://data.etabus.gov.hk/v1/transport/kmb/route-stop")
}
buff, err = utils.CacheStream(JSON_ROUTESTOPS, QUERY_FUNC, 7*24*3600)
if err != nil {
return nil, err
}
routeStops, err := readRouteStopsData(busStopMap, buff)
if err != nil {
log.Printf("Unable to parse RouteStopsData: %s", err)
return nil, err
}
searchables := []query.ISearchable{}
for _, routeStop := range *routeStops {
searchables = append(searchables, routeStop)
routeStop.Reload()
}
return &searchables, nil
}