- Fix type mismatch in search_cache.go: SearchWithCache now returns *yandex.Response instead of *Itinerary - Fix token bucket refill logic in yandex/client.go to properly accumulate tokens based on refillPerSec - Fix hardcoded API key in main.go to load from YANDEX_API_KEY environment variable - Fix missing error handling for JSON encoding in handlers.go RouteGeoJSON function - Fix incorrect redis.Nil handling in cache/store.go CacheAside.Exists method - Fix incorrect error return type in station_status.go updateStationStatus to return newStatus instead of empty string
101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
package airports
|
|
|
|
import (
|
|
"sort"
|
|
)
|
|
|
|
// StationNeighbor represents a neighboring station that can be used as a fallback
|
|
// when the main station is closed. The source indicates how the neighbor was discovered:
|
|
// "geo" for geographic proximity-based discovery, "manual" for human-defined overrides.
|
|
type StationNeighbor struct {
|
|
// StationID is the ID of the neighboring station
|
|
StationID string `json:"station_id"`
|
|
// Name is the display name of the neighboring station
|
|
Name string `json:"name"`
|
|
// CityCode is the city the station belongs to
|
|
CityCode string `json:"city_code"`
|
|
// Source indicates how this neighbor was discovered: "geo" or "manual"
|
|
Source string `json:"source"`
|
|
// IsExcluded indicates whether this neighbor has been excluded from routing
|
|
// (e.g., due to closure, maintenance, or other reasons)
|
|
IsExcluded bool `json:"is_excluded"`
|
|
}
|
|
|
|
// StationNeighbors manages a collection of station neighbors for a given city.
|
|
// It supports both geo-discovered and manually-defined neighbors.
|
|
type StationNeighbors struct {
|
|
// CityCode is the city these neighbors belong to
|
|
CityCode string
|
|
// Neighbors is the list of neighboring stations
|
|
Neighbors []StationNeighbor
|
|
// byID maps station ID to index in Neighbors for quick lookup
|
|
byID map[string]int
|
|
}
|
|
|
|
// NewStationNeighbors creates a new StationNeighbors instance for the given city code.
|
|
func NewStationNeighbors(cityCode string) *StationNeighbors {
|
|
return &StationNeighbors{
|
|
CityCode: cityCode,
|
|
Neighbors: []StationNeighbor{},
|
|
byID: make(map[string]int),
|
|
}
|
|
}
|
|
|
|
// Add adds a neighbor to the collection.
|
|
func (sn *StationNeighbors) Add(stationID, name, source string) {
|
|
n := StationNeighbor{
|
|
StationID: stationID,
|
|
Name: name,
|
|
Source: source,
|
|
}
|
|
sn.Neighbors = append(sn.Neighbors, n)
|
|
sn.byID[stationID] = len(sn.Neighbors) - 1
|
|
}
|
|
|
|
// MarkExcluded marks a neighbor as excluded from routing.
|
|
func (sn *StationNeighbors) MarkExcluded(stationID string) {
|
|
if idx, ok := sn.byID[stationID]; ok {
|
|
sn.Neighbors[idx].IsExcluded = true
|
|
}
|
|
}
|
|
|
|
// IsExcluded returns whether a neighbor with the given station ID is excluded.
|
|
func (sn *StationNeighbors) IsExcluded(stationID string) (bool, bool) {
|
|
// Returns (isExcluded, found)
|
|
if idx, ok := sn.byID[stationID]; ok {
|
|
return sn.Neighbors[idx].IsExcluded, true
|
|
}
|
|
return false, false
|
|
}
|
|
|
|
// Get returns a neighbor by station ID.
|
|
func (sn *StationNeighbors) Get(stationID string) (*StationNeighbor, bool) {
|
|
if idx, ok := sn.byID[stationID]; ok {
|
|
return &sn.Neighbors[idx], true
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
// Len returns the number of neighbors.
|
|
func (sn *StationNeighbors) Len() int {
|
|
return len(sn.Neighbors)
|
|
}
|
|
|
|
// Sort sorts neighbors by name.
|
|
func (sn *StationNeighbors) Sort() {
|
|
sort.Slice(sn.Neighbors, func(i, j int) bool {
|
|
return sn.Neighbors[i].Name < sn.Neighbors[j].Name
|
|
})
|
|
}
|
|
|
|
// GetNonExcluded returns neighbors that are not excluded.
|
|
func (sn *StationNeighbors) GetNonExcluded() []StationNeighbor {
|
|
var result []StationNeighbor
|
|
for _, n := range sn.Neighbors {
|
|
if !n.IsExcluded {
|
|
result = append(result, n)
|
|
}
|
|
}
|
|
return result
|
|
}
|