AstraBUS "қосымшасының API-ін немесе астаналық автобустар қаншалықты кеш екенін тексереміз

Astanahub оқырмандарына Қайырлы күн.

Мен студентпін, қаладағы көптеген студенттер сияқты, Мен негізінен автобуспен жүремін. Посттың идеясы бір керемет күнде аялдамада тұрып, сүйікті автобусыңызды күтіп, AstraBUS қосымшасында оның орналасқан жеріне мұқият қарау кезінде пайда болды (қосымша астананың автобустарының орналасқан жерін онлайн режимінде көрсетеді). Мен Астанамыздың қоғамдық көлігіне тәуелсіз шағын бағалауды неге жасамасқа деп ойладым. Барлық Графиктер мен карталармен. Айтылды-Жасалды.

Алдымен маған осы бастапқы деректерді жинау керек болды. PacketCapture (трафикті талдау қосымшасы) қолдана отырып, олардың API-де endpoint бар екенін байқады , ол автобус нөмірін біле отырып, барлық автобустардың координаттары мен солтүстікке қатысты бұрылу бұрышы (бағыт бұрышы) бар.

Bus coordinates / 40рис. 1. PacketCapture бар экран

Онда маған керек. Өкінішке орай , бұл қызмет кешегі немесе өткен жылғы деректерді көруге мүмкіндік бермейді, дегенмен мен үшін бұл құрал сарапшылар мен тасымалдаушылардың сұранысына ие болар еді. Ал, realtime сияқты realtime.

Тапсырма дәл деректерді талдау болғандықтан, алдымен деректерді қандай да бір жолмен алу керек. Деректерді жүктеу және сақтау үшін талдау жазамыз:

1. Біз кітапханаларды импорттаймыз және автобус нөмірлерімен тізім жасаймыз

2. Негізгі сценарий өте қарапайым; біз bus_numbers массивімен цикл жасаймыз және бәрін csv файлына сақтаймыз. Мен төменде барлық көздері бар github сілтемесін тіркеймін.
Жоғарыдағы сценарийдің нәтижесі-әр маршрут үшін бір минут аралықпен жазылған 50 csv файлы. 7-баған-бұл сценарий басталғаннан бері өткен уақытты көрсететін Итерация деректері (яғни әр минут сайын).

7 сәуірде ол сценарийді таңғы 9-дан кешке сағат 11-ге дейін өшірді. Нәтиже төмендегі суретте көрінеді

vscodeрис.2. Автобус деректері бар файлдардың мысалы

Деректер бар. Сонымен қатар, мен OpenStreetMap-тен бар аялдамалар туралы деректерді жүктедім.

Әр маршрут уақыт пен әр автобустың бірегей идентификаторы ретінде атрибутивті деректері бар бір көп сызықта орналасқан нүктелер жиынтығына ұқсайды (суретті қараңыз. 3).

макетрис. 3. №1 маршруттың мысалы

 

Жасаймыз ДБ PostgreSQL

Автобустың орташа кідіріс уақытын есептеу үшін оның аралығын есептеу керек . Яғни аялдама нүктелерін алыңыз аялдамалардың айналасында дөңгелек буфер құрыңыз және кіретін автобустарды санап, аялдаманың қай уақытта және қай уақытта өткенін есептеңіз.

Бұл кезеңде қол жетімді деректерді қандай да бір түрде дұрыс біріктіру қажеттілігі туындады және велосипед ойлап таппау үшін PostgreSQL реляциялық дерекқорының барлық деректерін кейінірек PostGIS арқылы кеңістіктік құралдарды қолдану үшін қайта сақтау туралы шешім қабылданды (мысалы, нүктелер айналасында буфер салу және оған кіретін автобустардың санын есептеу) күріш. 4).

 

сур. 4 . Аялдамалардың айналасындағы Буфер

Жалпы алғанда, мәліметтер базасының құрылымы өте қарапайым көрінеді,екі негізгі кесте және бір-біріне қатынасы бар кідіріс уақытын сақтауға көмекші.

 

 

сур. 5. ДБ схемасы

Төменде SQL мысалы bus кестесін құру туралы сұрау

CREATE TABLE IF NOT EXISTS bus
(id serial PRIMARY KEY,
bus_id varchar,
route_number varchar,
latest_bus_stop_id integer,
iteration integer,
time_at timestamp,
pt geometry);

geometry түрі бар pt өрісі-автобус пен аялдаманың кеңістіктік ақпаратын сақтайтын өріс. Кестелер құрылып , жазып қалды, олардың ДҚ-ға. Postgres-те csv - ден деректерді қайта сақтау үшін сценарий жазамыз:

def insert_row_to_db(row):
insert_query = """ INSERT INTO bus (bus_id,route_number,time_at, iteration, pt)
VALUES (%s, %s, %s, %s, ST_GeomFromText(%s, 4326))"""
date_time_obj = datetime.strptime(row[2],'%Y-%m-%d %H:%M:%S')
point = "POINT({} {})".format(row[4],row[3])
item_tuple = (row[0],row[1],date_time_obj,row[6],point)
cursor.execute(insert_query, item_tuple)
conn.commit()

#csv contain 7 columns
def insert_bus_to_db(path):
with open(path) as file:
file = csv.reader(file,delimiter = ',')
for row in file:
insert_row_to_db(row)

def save_bus_to_db():
for bus in bus_numbers:
path = bus_data_path + str(bus)+".csv"
insert_bus_to_db(path)

def insert_bus_stop_row_to_db(row):
insert_query = """ INSERT INTO bus_stop (pt)
VALUES (ST_GeomFromText(%s, 4326))"""
point = "POINT({} {})".format(row[1],row[2])
item_tuple = (point,)
cursor.execute(insert_query, item_tuple)
conn.commit()

def insert_bus_stop_to_db():
with open("./bus/bus_stops/bus_stops.csv") as file:
file = csv.reader(file,delimiter = ',')
for row in file:
insert_bus_stop_row_to_db(row)
Жалпы алғанда, шамамен 320 мың жазба пайда болды, бұл тек 7 сәуірдегі деректер. Барлық кестелері бар мәліметтер базасының салмағы 66 МБ.

сур. 6 . PostgreSQL Басқару тақтасы

SQL сұрауларын жазу

PostgreSQL/PostGIS сұраныстарын есептеуге және жазуға көшіңіз.

C Postgis бізге тек екі функция қажет - ST_Buffer және ST_Contains (буфер құру және элементтердің буферге кіруін тексеру үшін).

Біз кідірістерді bus_stop_delay_history кестесіне жазамыз . Псевдокодтағы Алгоритм келесідей:

Әр Итерация үшін :

автобус аялдаманың буферлік аймағына кіргенін тексеріңіз, егер кірсе:

bus_stop_delay_history-ге кіру уақытын жазыңыз және delay өрісіне алдыңғы уақыттан ағымдағы уақыт мәнін алыңыз

басқаша:

пропусти

SQL мысалы буфер құру және автобустың бірінші итерацияға буферге кіруін тексеру туралы сұрау:

select bus.*,bus_stop.* from bus, bus_stop
where ST_contains(ST_Buffer(bus_stop.pt,0.0008,'quad_segs=8'),bus.pt) and
(bus.iteration = 1) and
(bus.latest_bus_stop_id is null or
bus.latest_bus_stop_id != bus_stop.id);

Қызықты факт: елордада барлығы 539 бірегей автобус бар (ең болмағанда GPS қосылған). Қарапайым SQL сұранысы таңғы 9:30 - да жүретін барлық ерекше автобустарды көрсетеді

сур. 7. Елордадағы барлық автобустар сағат 9:30-да

Көрнекілік және қорытынды

Мен Matplotlib кітапханасы арқылы нәтижелерді елестетемін. Мысал коды төменде.

from matplotlib.dates import DateFormatter
import matplotlib.dates as dates
import numpy as np


fig, ax = plt.subplots()
ax.plot_date(x, y,"b-", label="№2")
ax.xaxis.set_major_formatter(dates.DateFormatter('%H:%M'))
y_mean = [np.mean(y)]*len(x)
ax.plot_date (x, y_mean,"b--", label="№2 орташа")
plt.title ('"Жабаев саябағы" аялдамасындағы автобустардың кідіріс уақытының хронологиясы')
plt.ylabel ('кідіріс уақыты минутпен')
plt.xlabel ('уақыт (сағат)')
plt.legend()
plt.show()
Жалпы, сіз жеке аудит жасай аласыз - әр аялдама мен әр маршрут үшін тексеру

сур. 8

Менің бағалауымда бір үлкен қателік бар. Бұл автобустардың Қос жазбасы болып жатыр. Яғни, автобус А нүктесінен С нүктесіне өткенде, ортасында тұрған в аялдамасы автобустың келіп, жолаушыларды алып кеткен уақытты жазады. бірақ басқа автобус маршруттың қарама-қарсы сызығында с нүктесінен А нүктесіне өтіп, Б аялдамасына келгенде тағы бір жазба пайда болады. Егер сіз автобустың ағымдағы бағыт бұрышын білсеңіз және оны кешіктіруді жазу кезінде ескерсеңіз, бұл қатені түзетуге болады , бірақ бұл посттың мақсаты дәл бағалау емес болғандықтан, мен осы сәтті жіберіп алдым және жай ғана орташа мәнді қолдандым.

сур. 9. № 10 автобустың өте қысқа аралығы бар

Елордада автобустар орташа есеппен 22 минут аралықпен жүреді. Қала орталығында жиі кездеседі, бірақ шетінде 40 минутқа кешіктірілген автобустар бар.

Менің ойымша, бұл хабарлама ақпараттық және пайдалы болды. Жолдарда проблемалық бағыттарды көрсететін және кешіктірудің ықтимал себептерін анықтайтын интерактивті карта жасау жоспарлануда.

Оқығаныңыз үшін рахмет. Сіз сондай-ақ менің GitHub репозиторийімді жүктеп, жоғарыдағы әрекеттерді қайталай отырып, аялдамада өтіп бара жатқан автобустармен жағдайды бағалауға тырысуға болады.

Пікірлер 2

Кіру пікір қалдыру үшін

Очень полезная Информация

Жауап беру

Круто!

Жауап беру