SofiaRide · Методология

Transit Score

Как изчисляваме достъпността на обществения транспорт за всеки адрес в София (версия на конфигурацията в кода: 1.3.3).

GTFSСкала 0–1004 вида транспорт4 времеви прозорецаДо 12 спирки

Въведение

Какво измерва Transit Score

Transit Score отговаря на въпроса: колко добре е свързан даден адрес с обществения транспорт в София? Числото от 0 до 100 отчита разстояние пеша до спирки, брой и вид линии, честота на отпътуванията в фиксирани прозорци и структурна надеждност на вида транспорт. Скорът е фиксиран стандарт (не се настройва от потребителя), за да са сравними обяви, квартали и API отговори.

!

Важно: Описваме достъпността на локацията, не „качеството“ на една конкретна линия. Две съседни точки могат да се различават, ако едната е по-близо до спирка с метро и повече линии.

Стъпка 1

Спирки в обхват

Търсят се спирки от графа (public/route-stops.json) в радиус 800 m (Haversine, права линия). Референтната скорост на ходене е 1,3 m/s; при същата скорост ефективният радиус съвпада с 800 m. От най-близките кандидати се вземат най-много 12 спирки за агрегата. OSRM се ползва в планиращия маршрути, не в този скоринг.

// Haversine — distanceMeters(lat1, lon1, lat2, lon2) → m
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)
1 dph
17%
2 dph
33%
3 dph
50%
4 dph
67%
5 dph
83%
6 dph
100%
8 dph
100%
10 dph
100%
12 dph
100%
15 dph
100%

Стъпка 4

Тегло по вид транспорт (GTFS route_type)

Метро1,00
Трамвай0,88
Тролейбус0,78
Автобус0,60

Стъпка 5

Времеви прозорци и множители

Четири прозореца (часове по разписание, Europe/Sofia). Уикенд прозорецът ползва съботен референтен ден от календара.

ПрозорецЧасове (начало–край)Множител
Пик (работен ден)07:00 – 09:001,00
Междинен (работен ден)11:00 – 13:000,82
Вечер (работен ден)20:00 – 22:000,68
Уикенд10:00 – 12:000,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 не се оценяват като гъста мрежа при сходно качество на спирките. Спирки без услуга в прозореца не влизат в броенето.

// Публикуван Transit score (peak)
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

След публикуваното мащабиране ползваме същите текстови ленти като в калкулатора на средата:

90–100
Изключителен
80–89
Отличен
70–79
Много добър
60–69
Добър
50–59
Задоволителен
40–49
Под средното
0–39
Слаб

Ранг

Приблизителен ранг спрямо ГЕ (в калкулатора на средата)

В страницата „Индекс на средата“ рангът не е част от 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.