BG
WebPython

Stara Zagora Transit

An interactive city transport map with routes, stops, timetables and journey planning. Shows real GPS vehicle positions when the data feed is available.

README

Транспорт Стара Загора — версия 2.1

Лека интерактивна карта със спирки, автобусни и тролейбусни линии, маршрути, разписания и само реално получени GPS позиции. Страницата е пригодена за /transport/ под Apache на Debian 13. Python процесът за GPS данните използва стандартната библиотека; не са нужни Docker, база данни или npm на VPS-а.

Функции

  • 30 линии, 510 спирки, 123 варианта на маршрутите и 961 курса в включения GTFS файл от 28.09.2026 г.
  • Търсене по име на спирка, код и номер на линия; филтри за автобуси и тролейбуси.
  • Избор на посока/вариант и подреден списък на спирките по конкретния маршрут.
  • Следващи заминавания и разписание за цял ден с избор на дата, час и линия.
  • Подробности за отделен курс: всички спирки, часове, продължителност и печат.
  • Търсене на пътуване между две спирки: директно или с едно прекачване. Вариантите са подредени по най-ранно пристигане.
  • По желание прекачване между спирки до 200 м една от друга. Предвидени са минимум 3 минути плюс приблизително време за ходене.
  • GPS позиции с номера на линиите, посока на движение, време на последната позиция и скорост, когато е предоставена.
  • Вид и модел на превозното средство при съвпадение в справочника, с регистрационен/служебен номер и източник.
  • Проследяване на избран автобус/тролейбус с центриране на картата при нова позиция.
  • Списък на превозните средства на живо и филтър по линия.
  • Близки спирки чрез геолокация или точка, избрана на картата.
  • Любими линии и спирки, запазени в браузъра без регистрация.
  • Линкове към избрана линия, вариант, спирка, курс или превозно средство.
  • Светла, тъмна и автоматична тема; класически или приглушени цветове на картата.
  • Слоеве за спирки, превозни средства и цялата маршрутна мрежа; цял екран.
  • Изглед за телефон с прибиране на справочника; клавиш / за търсене.
  • Автоматично GPS обновяване на около 10 секунди, ръчно обновяване и спиране на автоматичното.
  • Ежедневно обновяване на разписанията чрез системен таймер; поддръжка на календарни изключения и часове след полунощ.

Какво означават данните

Часовете и планирането са по разписание, не са GPS прогнози. Няма потвърдени данни за закъснения, отменени курсове, временни отклонения, билети или заетост. Картата не симулира движещи се автобуси.

Наличният календар публикува само делнични дни. При липса на курсове за събота/неделя интерфейсът обяснява, че няма данни — това не е твърдение, че няма транспорт. Включеното разписание е валидно до 31.12.2026 г.; таймерът трябва да го поддържа актуално.

Планирането търси тръгване през следващите 3 часа, допуска максимум едно прекачване и до 1 час изчакване на връзката. Разстоянията за ходене са по права линия, без проверка на пресичания, бариери и достъпност. На картата пътуването се показва като схема между спирките с пунктир; тя не е пешеходна навигация. Изгледът за отделна линия използва публикуваната маршрутна геометрия.

GPS данните идват от националния каталог. Показват се само позиции с времеви печат до три минути от текущия час. Ако потокът прекъсне, живите маркери се изчистват. Скоростта се преобразува от m/s в km/h; липсващата стойност остава празна. В предоставения файл бяха проверени 37 позиции, от които 23 съдържат скорост.

Браузърът проверява за GPS данни на всеки 10 секунди, докато страницата е видима и автоматичното обновяване е включено. Застъпващи се заявки не се изпращат. Това не гарантира нова позиция на всеки 10 секунди: честотата на действителните GPS записи зависи от източника.

Модели на превозните средства

GPS потокът съдържа идентификатор, бордов и регистрационен/служебен номер, но не и модел. Справочникът data/vehicle_models.json свързва 77 номера с модели по списък на превозвача от 2016 г., приложение 2, стр. 21–23: Solaris Urbino 12, SOR NB 18, Škoda 26Tr Solaris и Solaris Trollino 12. Документът е исторически; годината и връзката към източника са видими в подробностите за машината. Съвпадението по номер не представлява проверка на актуалното техническо състояние или на евентуално прехвърляне на регистрацията.

В предоставения GPS файл от 28.09.2026 г. има съвпадение за 25 от 37 превозни средства. За останалите пише „Моделът не е установен“. Категорията „Автобусна линия“/„Тролейбусна линия“ при липсващ модел описва линията, а не доказва вида на конкретната машина. Електробуси не се определят само по номера на линията.

За добавяне или корекция на потвърден модел създай /opt/stara-zagora-transit/data/vehicle_models.local.json. Файлът се запазва при обновяване. Съдържанието следва структурата на основния справочник:

{"by_plate": {}, "by_id": {}, "by_label": {}}

Под by_plate ключът е регистрационният/служебният номер с латински букви, без интервали. Стойността съдържа model, type, source (URL) и note (произход/дата). Допустими видове: bus, articulated_bus, electric_bus, trolley. Използвай by_id само за проверени устойчиви GPS идентификатори; той има предимство пред регистрационния номер, а by_label е последният резервен вариант. След редакция изпълни sudo systemctl restart stara-zagora-transit.

Натоварване

Търсенето, разписанията и картата се обработват в браузъра на посетителя. VPS-ът подава статични файлове и кешира общата заявка към GPS източника за 8 секунди. network.json е около 1.9 MB без компресия и около 345 KB с gzip; deploy.sh включва Apache DEFLATE. Не е необходим картен сървър на VPS-а: плочките идват от OpenStreetMap.

Инсталиране на VPS-а с текущия HTTPS сайт

Текущият Apache VirtualHost на порт 443 използва DocumentRoot /var/www/html и вече съдържа:

ProxyPass        /transport/api/ http://127.0.0.1:8765/api/
ProxyPassReverse /transport/api/ http://127.0.0.1:8765/api/

Това е съвместимо с приложението. Apache подава файловете от /var/www/html/transport/ и приема HTTPS заявките към API-то, след което ги препраща по локален HTTP към Python процеса. JavaScript използва относителни адреси; в браузъра няма заявка към HTTP порт 8765. Плочките на OpenStreetMap също се зареждат през HTTPS.

Качи новия stara-zagora-transit.zip в /home/krum, като замени стария архив, и изпълни:

cd /home/krum
python3 -m zipfile -e stara-zagora-transit.zip .
cd stara-zagora-transit
sudo bash deploy.sh --existing-apache

Отвори https://92.204.41.78/transport/ и натисни Ctrl+F5. Режимът --existing-apache:

  • запазва VirtualHost-а, сертификатите и правилата за другите приложения;
  • заменя стария глобален transport конфигурационен фрагмент с настройки само за компресия; проксито остава във VirtualHost-а;
  • запомня този режим в /opt/stara-zagora-transit/apache-mode, така че бъдещи обновявания без флаг продължават да го използват;
  • изпълнява apache2ctl configtest преди презареждането на Apache.

Проверка след инсталиране:

curl -fsS https://92.204.41.78/transport/api/health
curl -fsS https://92.204.41.78/transport/api/vehicles

Първият адрес трябва да върне {"ok":true}. При грешка в сертификата тя трябва да бъде отстранена в HTTPS настройките. Геолокацията работи при доверен HTTPS сертификат и разрешение от посетителя.

Инсталаторът проверява нужните файлове и при обновяване запазва предишната уеб папка и бекенд в /var/backups/stara-zagora-transit/; точният път се изписва в терминала. Настройките в /etc/default/stara-zagora-transit се запазват.

За друга инсталация, която няма собствено /transport/api/ прокси във VirtualHost, е наличен sudo bash deploy.sh --managed-apache. Тогава прокси правилата се управляват чрез глобалния apache.conf от пакета. При първа инсталация без флаг този режим е подразбиращият се.

Поток с действителни GPS позиции

Публичният адрес е включен по подразбиране. След инсталиране провери връзката от самия VPS:

curl -s http://127.0.0.1:8765/api/vehicles

Отговор "status":"live" и непразен vehicles показват, че картата ще рисува автобусите. empty означава, че няма скорошни позиции, а error — че източникът временно не отговаря. Картата не рисува стари данни като текущи. Порт 8765 слуша само на 127.0.0.1; посетителите отварят HTTPS сайта на Apache на порт 443.

Ако по-късно източникът промени адреса си, редактирай:

sudo nano /etc/default/stara-zagora-transit
sudo systemctl restart stara-zagora-transit

В този файл може да се зададе нов GTFS_RT_URL. Запази GTFS_RT_SOURCE=official за потока на държавния портал. Ако друг източник изисква Authorization: Bearer ..., попълни и закоментираните GTFS_RT_HEADER и GTFS_RT_TOKEN; файлът има права 0600 и токенът не бива да се поставя в JavaScript. За поток с идентификаторите на LiveTransport задай GTFS_RT_SOURCE=livetransport.

Поддръжка

sudo systemctl status stara-zagora-transit
sudo systemctl status stara-zagora-transit-refresh.timer
sudo systemctl start stara-zagora-transit-refresh.service

Последната команда обновява статичните разписания веднага; таймерът го прави всеки ден в 05:30 българско време. При неуспешно изтегляне последният успешно публикуван файл остава на място. Старият включен архив е ограничен до 31.12.2026 г. и трябва да се обновява за следващи дати.

Източници и права

Разписанията и картата използват livetransport.eu, включен в Transitous Sources под CC BY 4.0. Официалният GTFS архив в data/ е свален от националния каталог и се използва само за съпоставяне на номерата на линиите; оригиналният файл запазва собствените си условия. Картните плочки идват от OpenStreetMap с показана атрибуция; при широк обществен трафик осигури специализиран доставчик според правилата за плочки. Интерфейсът използва Leaflet 1.9.4, включен локално в static/vendor/leaflet/ с неговия BSD 2-Clause лиценз. Кодът на приложението в този пакет е предоставен под MIT лиценз; данните и картните плочки запазват собствените си условия.

Местен преглед

Изпълни python3 server.py и отвори http://127.0.0.1:8765/transport/. Без промени по настройките приложението използва публичния GPS поток.

Проверки за разработка

Не са нужни за инсталиране на VPS-а. Деветте теста за разписанията и планирането се пускат с Node.js:

node --test tests/core.test.js
python3 -m unittest discover -s tests -p '*_test.py'

Проверката на взаимодействията в интерфейса използва jsdom само за разработка:

npm install --prefix /tmp/transit-dom-test --no-audit --no-fund jsdom
TRANSIT_JSDOM=/tmp/transit-dom-test/node_modules/jsdom node tests/ui.test.cjs

Тя проверява разделите, посоките, спирките, любимите, курса, споделянето, близките спирки, планирането, проследяването, темата и търсенето. Leaflet е заменен с тестов обект в този тест; той не представлява визуална проверка на картните плочки. Графичен преглед на локалния проект не беше възможен в средата за изработка. Не е извършено отдалечено инсталиране на твоя VPS.