160 lines
3.5 KiB
Go
160 lines
3.5 KiB
Go
package kmb
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"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,
|
|
}
|
|
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() (*map[string]*BusStop, error) {
|
|
busStopsData := BusStopsJson{}
|
|
|
|
QUERY_FUNC := func() (io.ReadCloser, error) {
|
|
return utils.HttpGet("https://data.etabus.gov.hk/v1/transport/kmb/stop")
|
|
}
|
|
|
|
PARSE_FUNC := func(buff *bytes.Buffer) error {
|
|
err := json.Unmarshal(buff.Bytes(), &busStopsData)
|
|
return err
|
|
}
|
|
|
|
cs, err := utils.CacheStreamEx(JSON_BUSSTOPS, QUERY_FUNC)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = cs.Try(PARSE_FUNC, 7*24*3600, 3)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
busStopMap := map[string]*BusStop{}
|
|
for _, entry := range busStopsData.BusStops {
|
|
|
|
b := BusStop{
|
|
BusStopId: entry.BusStopId,
|
|
}
|
|
|
|
b.Latitude = entry.Latitude
|
|
b.Longitude = entry.Longitude
|
|
|
|
n := map[string]string{
|
|
"en": entry.Name_en,
|
|
"zh-Hant": entry.Name_tc,
|
|
"zh-Hans": entry.Name_sc,
|
|
}
|
|
|
|
b.Name = &n
|
|
|
|
b.Reload()
|
|
|
|
if _, ok := busStopMap[b.BusStopId]; ok {
|
|
return nil, fmt.Errorf("Duplicated BusStop: %s", b.BusStopId)
|
|
}
|
|
|
|
busStopMap[b.BusStopId] = &b
|
|
}
|
|
return &busStopMap, nil
|
|
}
|
|
|
|
func getRouteStops(busStopMap *map[string]*BusStop) (*[]query.ISearchable, error) {
|
|
var routeStops *[]*RouteStop
|
|
|
|
QUERY_FUNC := func() (io.ReadCloser, error) {
|
|
return utils.HttpGet("https://data.etabus.gov.hk/v1/transport/kmb/route-stop")
|
|
}
|
|
|
|
PARSE_FUNC := func(buff *bytes.Buffer) error {
|
|
var err error
|
|
routeStops, err = readRouteStopsData(busStopMap, buff)
|
|
return err
|
|
}
|
|
|
|
cs, err := utils.CacheStreamEx(JSON_ROUTESTOPS, QUERY_FUNC)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = cs.Try(PARSE_FUNC, 7*24*3600, 3)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
searchables := []query.ISearchable{}
|
|
for _, routeStop := range *routeStops {
|
|
searchables = append(searchables, routeStop)
|
|
routeStop.Reload()
|
|
}
|
|
|
|
return &searchables, nil
|
|
}
|