SofiaRide · Методология
Transit Score
Как изчисляваме достъпността на обществения транспорт за всеки адрес в София (версия на конфигурацията в кода: 1.3.3).
Въведение
Какво измерва Transit Score
Transit Score отговаря на въпроса: колко добре е свързан даден адрес с обществения транспорт в София? Числото от 0 до 100 отчита разстояние пеша до спирки, брой и вид линии, честота на отпътуванията в фиксирани прозорци и структурна надеждност на вида транспорт. Скорът е фиксиран стандарт (не се настройва от потребителя), за да са сравними обяви, квартали и API отговори.
Важно: Описваме достъпността на локацията, не „качеството“ на една конкретна линия. Две съседни точки могат да се различават, ако едната е по-близо до спирка с метро и повече линии.
Стъпка 1
Спирки в обхват
Търсят се спирки от графа (public/route-stops.json) в радиус 800 m (Haversine, права линия). Референтната скорост на ходене е 1,3 m/s; при същата скорост ефективният радиус съвпада с 800 m. От най-близките кандидати се вземат най-много 12 спирки за агрегата. OSRM се ползва в планиращия маршрути, не в този скоринг.
RADIUS = 800 // метра
MAX_STOPS = 12
Стъпка 2
Разходен коефициент (walk decay)
По-близката спирка тежи повече. Използваме степен 1,4 върху нормализираното разстояние до границата на обхвата:
walkDecay(d, r) = (1 − d / r) ^ 1.4 // d ≤ r, иначе 0
Примери за r = 800: 50 m → 91%, 200 m → 67%, 500 m → 25%, 750 m → 2%.
Стъпка 3
Честота
За всяка линия на спирката се броят отпътувания в избрания часови прозорец (календар GTFS + serviceRunsToday). Нормализация с таван при 6 отпътувания на час. Ако в GTFS няма отпътуване точно на този stop_id, но линията минава през друга спирка на същия маршрут до 200 m, ползваме максималния dph сред тези съседни спирки (наследяване по маршрут при несъответствие граф/GTFS).
freqScore(dph) = min(1, dph / 6)
Стъпка 4
Тегло по вид транспорт (GTFS route_type)
Стъпка 5
Времеви прозорци и множители
Четири прозореца (часове по разписание, Europe/Sofia). Уикенд прозорецът ползва съботен референтен ден от календара.
| Прозорец | Часове (начало–край) | Множител |
|---|---|---|
| Пик (работен ден) | 07:00 – 09:00 | 1,00 |
| Междинен (работен ден) | 11:00 – 13:00 | 0,82 |
| Вечер (работен ден) | 20:00 – 22:00 | 0,68 |
| Уикенд | 10:00 – 12:00 | 0,72 |
Каноничната стойност за обяви и API е прозорецът peak (пик).
Стъпка 6
Пресмятане по спирка и агрегат за адрес
За всяка спирка (предварително от GTFS): за всеки маршрут на спирката се смята принос freqScore × typeWeight × timeMult × 100, после се взима средно аритметично само по маршрутите с поне едно отчетено отпътуване в този прозорец (след евентуално наследяване на честота от близка спирка по същия маршрут). Маршрути без услуга в прозореца не влизат в знаменателя — така нощни линии на стълб с дневни автобуси не свалят оценката. Краен резултат по спирка, ограничен до 100.
За адрес (точка): сред най-много 12-те най-близки спирки в обхвата се смята средно тегловно по walk decay само за спирки с положителен скор за съответния прозорец: Σ(decay × score_спирка) / Σ(decay). Това средно се умножава по min(1, брой_такива_спирки / 6) (TRANSIT_COVERAGE_FULL_STOP_COUNT) — малко отделни полюса в 800 m не се оценяват като гъста мрежа при сходно качество на спирките. Спирки без услуга в прозореца не влизат в броенето.
meanPeak = Σ(decay×peak_спирка) / Σ(decay) // peak_спирка > 0
internalPeak = meanPeak × min(1, n_спирки / 6)
published = min(100, round(100 × internalPeak / publishedScaleRawMax))
// publishedScaleRawMax в public/transit-scores.json (build):
// internalPeakMaxSampled × 0.88 // TRANSIT_PUBLISHED_INTERNAL_PEAK_FRACTION
Калибрацията на TRANSIT_PUBLISHED_INTERNAL_PEAK_FRACTION определя колко често се достига таванът 100: по-висока стойност увеличава знаменателя и намалява „надуването“ при силни, но не-централни квартали. Виж lib/transit/SCORE_CHANGELOG.md.
Стъпка 7
Интерпретация на скалата 0–100
След публикуваното мащабиране ползваме същите текстови ленти като в калкулатора на средата:
Ранг
Приблизителен ранг спрямо ГЕ (в калкулатора на средата)
В страницата „Индекс на средата“ рангът не е част от Transit Score сам по себе си, а ориентир за композитния индекс: rank ≈ round(N × (1 − composite/100)^1.2), където N е броят полигони в атласния ГЕ слой за текущата изграждане (не фиксирани 564).
Версии
Константи и промени
Пълен списък: lib/transit-score-config.js, история: lib/transit/SCORE_CHANGELOG.md. API връща configVersion и publishedScaleRawMax при заявка към /api/transit-score.
