Spaces:
Build error
Build error
elli-teu
commited on
Commit
·
8769306
1
Parent(s):
5184bfe
Test av borttagning av dubbletter, tillägg av hållplatser samt start på sortering
Browse files- app.py +115 -38
- test.py +44 -0
- test_data.csv +17 -0
app.py
CHANGED
|
@@ -74,50 +74,70 @@ def get_buses():
|
|
| 74 |
short_bus_list = list(pd.unique(bus_df["route_short_name"]))
|
| 75 |
return bus_df, bus_list, short_bus_list
|
| 76 |
|
| 77 |
-
|
| 78 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
"""
|
| 80 |
-
Removes duplicate trips based on route_id
|
| 81 |
|
| 82 |
Parameters:
|
| 83 |
df (pd.DataFrame): Input DataFrame containing trip data.
|
| 84 |
route_id_col (str): Column name for route IDs.
|
| 85 |
trip_id_col (str): Column name for trip IDs.
|
| 86 |
-
stop_id_col (str): Column name for stop IDs.
|
| 87 |
datetime_col (str): Column name for departure times.
|
| 88 |
time_window (str): Time window for considering trips as duplicates (e.g., '3min').
|
| 89 |
|
| 90 |
Returns:
|
| 91 |
pd.DataFrame: Filtered DataFrame with duplicates removed.
|
| 92 |
"""
|
|
|
|
|
|
|
| 93 |
# Ensure the datetime column is of datetime type
|
| 94 |
df[datetime_col] = pd.to_datetime(df[datetime_col])
|
| 95 |
-
|
| 96 |
-
# Sort by route_id
|
| 97 |
-
df = df.sort_values(by=[route_id_col,
|
| 98 |
-
|
| 99 |
-
#
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
#
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
# Filter the original DataFrame to retain only the non-duplicate trips
|
| 114 |
-
unique_trip_ids = filtered_first_stops[trip_id_col].unique()
|
| 115 |
-
result = df[df[trip_id_col].isin(unique_trip_ids)]
|
| 116 |
-
|
| 117 |
return result
|
| 118 |
|
| 119 |
def plot_graph(plot_df):
|
| 120 |
#Nu vill vi plotta!
|
|
|
|
| 121 |
categories = {0 : 'Empty',
|
| 122 |
1: 'Many seats available',
|
| 123 |
2:'Few seats available',
|
|
@@ -125,7 +145,7 @@ def plot_graph(plot_df):
|
|
| 125 |
4:'Crushed standing room',
|
| 126 |
5: 'Full'}
|
| 127 |
|
| 128 |
-
plot_df = plot_df[["datetime", "vehicle_occupancystatus", "stop_name"]]
|
| 129 |
plot_df = plot_df.sort_values("datetime")
|
| 130 |
st.write(plot_df.head())
|
| 131 |
st.write(plot_df.tail())
|
|
@@ -146,6 +166,36 @@ def plot_graph(plot_df):
|
|
| 146 |
)
|
| 147 |
st.altair_chart(chart, use_container_width=True)
|
| 148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
def visualize(filtered_data):
|
| 150 |
import folium
|
| 151 |
from streamlit_folium import st_folium
|
|
@@ -198,7 +248,7 @@ def main():
|
|
| 198 |
st.session_state.data = load_local_data("data.csv")
|
| 199 |
if "first" not in st.session_state:
|
| 200 |
st.session_state.first = True
|
| 201 |
-
st.session_state.data =
|
| 202 |
else:
|
| 203 |
# Fetch data if local data is invalid
|
| 204 |
if st.session_state.hopsworks_project is None:
|
|
@@ -252,7 +302,18 @@ def main():
|
|
| 252 |
st.session_state.direction = not st.session_state.direction
|
| 253 |
print(st.session_state.direction)
|
| 254 |
|
| 255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
#direction = st.sidebar.checkbox('Direction of bus', value=True)
|
| 257 |
|
| 258 |
today = datetime.now()
|
|
@@ -271,17 +332,16 @@ def main():
|
|
| 271 |
start_time = st.sidebar.time_input("Select a start time", value=None)
|
| 272 |
end_time = st.sidebar.time_input("Select an end time", value=None)
|
| 273 |
|
| 274 |
-
|
| 275 |
-
trips = buses_df[buses_df["route_long_name"]==bus]
|
| 276 |
-
bus_trips = st.session_state.data[st.session_state.data["route_long_name"]==bus]
|
| 277 |
-
bus_trips["datetime"] = pd.to_datetime(bus_trips["datetime"])
|
| 278 |
-
bus_trips["datetime"] = bus_trips["datetime"].dt.tz_convert(None)
|
| 279 |
|
| 280 |
#TODO remove
|
| 281 |
-
trip_ids = list(trips["trip_id"])
|
| 282 |
-
plot_df = st.session_state.data[st.session_state.data["trip_id"]==trip_ids[0]]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
|
| 284 |
-
#TODO direction
|
| 285 |
|
| 286 |
print(f"start time {type(start_time)}")
|
| 287 |
print(f"end time {type(end_time)}")
|
|
@@ -290,10 +350,27 @@ def main():
|
|
| 290 |
if start_time != None and end_time != None:
|
| 291 |
#TODO hur filtrera på tid?
|
| 292 |
st.write(f"Displaying buses between {start_time.strftime('%H:%M')} and {end_time.strftime('%H:%M')} the {day_choice}")
|
|
|
|
|
|
|
|
|
|
| 293 |
selected_trips = bus_trips[(bus_trips["datetime"] >= datetime.combine(date_options[day_choice], start_time))
|
| 294 |
& (bus_trips["datetime"] <= datetime.combine(date_options[day_choice], end_time))
|
| 295 |
-
& (bus_trips["direction_id"] == st.session_state.direction )
|
|
|
|
| 296 |
trip_ids = list(pd.unique(selected_trips["trip_id"]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 297 |
st.write(f"Length {len(trip_ids)}")
|
| 298 |
for id in trip_ids:
|
| 299 |
plot_graph(st.session_state.data[st.session_state.data["trip_id"]==id])
|
|
|
|
| 74 |
short_bus_list = list(pd.unique(bus_df["route_short_name"]))
|
| 75 |
return bus_df, bus_list, short_bus_list
|
| 76 |
|
| 77 |
+
# Function to remove duplicates
|
| 78 |
+
def remove_near_duplicates(data):
|
| 79 |
+
print(data["trip_id"].nunique())
|
| 80 |
+
result = []
|
| 81 |
+
data["datetime"] = pd.to_datetime(data["datetime"])
|
| 82 |
+
for _, group in data.groupby(['route_id', 'stop_name']):
|
| 83 |
+
# Initialize a list to store rows that are not duplicates
|
| 84 |
+
filtered_rows = []
|
| 85 |
+
last_row = None
|
| 86 |
+
|
| 87 |
+
for idx, row in group.iterrows():
|
| 88 |
+
if last_row is None or (row['datetime'] - last_row['datetime'] > pd.Timedelta(minutes = 3)):
|
| 89 |
+
# Keep the row if it's the first or sufficiently far apart in time
|
| 90 |
+
filtered_rows.append(row)
|
| 91 |
+
last_row = row
|
| 92 |
+
|
| 93 |
+
# Add filtered rows to the result
|
| 94 |
+
result.extend(filtered_rows)
|
| 95 |
+
filtered_df = pd.DataFrame(result)
|
| 96 |
+
# Return the filtered dataframe
|
| 97 |
+
print(filtered_df["trip_id"].nunique())
|
| 98 |
+
return filtered_df
|
| 99 |
+
|
| 100 |
+
def remove_duplicate_trips(df, route_id_col="route_id", trip_id_col="trip_id", datetime_col="datetime", time_window='3min'):
|
| 101 |
"""
|
| 102 |
+
Removes duplicate trips based on route_id and starting time proximity within a time window.
|
| 103 |
|
| 104 |
Parameters:
|
| 105 |
df (pd.DataFrame): Input DataFrame containing trip data.
|
| 106 |
route_id_col (str): Column name for route IDs.
|
| 107 |
trip_id_col (str): Column name for trip IDs.
|
|
|
|
| 108 |
datetime_col (str): Column name for departure times.
|
| 109 |
time_window (str): Time window for considering trips as duplicates (e.g., '3min').
|
| 110 |
|
| 111 |
Returns:
|
| 112 |
pd.DataFrame: Filtered DataFrame with duplicates removed.
|
| 113 |
"""
|
| 114 |
+
print(df["trip_id"].nunique())
|
| 115 |
+
|
| 116 |
# Ensure the datetime column is of datetime type
|
| 117 |
df[datetime_col] = pd.to_datetime(df[datetime_col])
|
| 118 |
+
|
| 119 |
+
# Sort by route_id and datetime for correct chronological order within each route
|
| 120 |
+
df = df.sort_values(by=[route_id_col, datetime_col])
|
| 121 |
+
|
| 122 |
+
# Calculate time differences between consecutive rows within each route_id group
|
| 123 |
+
df['time_diff'] = df.groupby(route_id_col)[datetime_col].diff().fillna(pd.Timedelta('0s'))
|
| 124 |
+
|
| 125 |
+
# Mark rows as duplicates if the time difference is within the time window
|
| 126 |
+
time_window_timedelta = pd.to_timedelta(time_window)
|
| 127 |
+
df['is_duplicate'] = df['time_diff'] <= time_window_timedelta
|
| 128 |
+
|
| 129 |
+
# Keep only the first row within each group of duplicates (based on time window)
|
| 130 |
+
df['keep'] = ~df.groupby(route_id_col)['is_duplicate'].transform('any')
|
| 131 |
+
|
| 132 |
+
# Filter rows: Keep only those that are marked as 'keep'
|
| 133 |
+
result = df[df['keep']].drop(columns=['time_diff', 'is_duplicate', 'keep'])
|
| 134 |
+
|
| 135 |
+
print(result["trip_id"].nunique())
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
return result
|
| 137 |
|
| 138 |
def plot_graph(plot_df):
|
| 139 |
#Nu vill vi plotta!
|
| 140 |
+
#TODO ska den bara visa de stopp man vill eller alla?
|
| 141 |
categories = {0 : 'Empty',
|
| 142 |
1: 'Many seats available',
|
| 143 |
2:'Few seats available',
|
|
|
|
| 145 |
4:'Crushed standing room',
|
| 146 |
5: 'Full'}
|
| 147 |
|
| 148 |
+
plot_df = plot_df[["datetime", "vehicle_occupancystatus", "stop_name", "route_id"]]
|
| 149 |
plot_df = plot_df.sort_values("datetime")
|
| 150 |
st.write(plot_df.head())
|
| 151 |
st.write(plot_df.tail())
|
|
|
|
| 166 |
)
|
| 167 |
st.altair_chart(chart, use_container_width=True)
|
| 168 |
|
| 169 |
+
def plot_graph_title(plot_df, stop, time):
|
| 170 |
+
#Nu vill vi plotta!
|
| 171 |
+
#TODO ska den bara visa de stopp man vill eller alla?
|
| 172 |
+
categories = {0 : 'Empty',
|
| 173 |
+
1: 'Many seats available',
|
| 174 |
+
2:'Few seats available',
|
| 175 |
+
3:'Standing room only',
|
| 176 |
+
4:'Crushed standing room',
|
| 177 |
+
5: 'Full'}
|
| 178 |
+
|
| 179 |
+
plot_df = plot_df[["datetime", "vehicle_occupancystatus", "stop_name", "route_id"]]
|
| 180 |
+
plot_df = plot_df.sort_values("datetime")
|
| 181 |
+
#plot_df = plot_df.set_index("datetime")
|
| 182 |
+
plot_df["Occupancy"] = plot_df["vehicle_occupancystatus"].map(categories)
|
| 183 |
+
# Explicitly set the order for Y_category
|
| 184 |
+
category_order = list(categories.values()) # ['Empty', 'Many seats available', ..., 'Full']
|
| 185 |
+
category_order.reverse()
|
| 186 |
+
|
| 187 |
+
#st.line_chart(plot_df)
|
| 188 |
+
# Create the Altair chart
|
| 189 |
+
chart = alt.Chart(plot_df).mark_line(point=True, interpolate="step-after").encode(
|
| 190 |
+
x=alt.X('stop_name:N', title="Stop name"), # Use column name as string
|
| 191 |
+
y=alt.Y('Occupancy:N', title="Vehicle Occupancy Status (Categories)", sort=category_order, scale=alt.Scale(domain=category_order)), # Treat Y as categorical
|
| 192 |
+
tooltip=["datetime", 'stop_name', 'Occupancy'] # Add tooltips for interactivity
|
| 193 |
+
).properties(
|
| 194 |
+
title=f"Vehicle Occupancy For Bus arriving at {stop} at {time}"
|
| 195 |
+
)
|
| 196 |
+
st.altair_chart(chart, use_container_width=True)
|
| 197 |
+
|
| 198 |
+
|
| 199 |
def visualize(filtered_data):
|
| 200 |
import folium
|
| 201 |
from streamlit_folium import st_folium
|
|
|
|
| 248 |
st.session_state.data = load_local_data("data.csv")
|
| 249 |
if "first" not in st.session_state:
|
| 250 |
st.session_state.first = True
|
| 251 |
+
#st.session_state.data = remove_near_duplicates(st.session_state.data)
|
| 252 |
else:
|
| 253 |
# Fetch data if local data is invalid
|
| 254 |
if st.session_state.hopsworks_project is None:
|
|
|
|
| 302 |
st.session_state.direction = not st.session_state.direction
|
| 303 |
print(st.session_state.direction)
|
| 304 |
|
| 305 |
+
#Plocka alla aktuella trip_ids från buses
|
| 306 |
+
trips = buses_df[buses_df["route_long_name"]==bus]
|
| 307 |
+
bus_trips = st.session_state.data[st.session_state.data["route_long_name"]==bus]
|
| 308 |
+
bus_trips["datetime"] = pd.to_datetime(bus_trips["datetime"])
|
| 309 |
+
bus_trips["datetime"] = bus_trips["datetime"].dt.tz_convert(None)
|
| 310 |
+
|
| 311 |
+
stops = list(pd.unique(bus_trips["stop_name"]))
|
| 312 |
+
stop_choice = st.sidebar.selectbox(
|
| 313 |
+
"Select your bus stop:",
|
| 314 |
+
options=stops,
|
| 315 |
+
help="Select one bus stop to se occupancy."
|
| 316 |
+
)
|
| 317 |
#direction = st.sidebar.checkbox('Direction of bus', value=True)
|
| 318 |
|
| 319 |
today = datetime.now()
|
|
|
|
| 332 |
start_time = st.sidebar.time_input("Select a start time", value=None)
|
| 333 |
end_time = st.sidebar.time_input("Select an end time", value=None)
|
| 334 |
|
| 335 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
|
| 337 |
#TODO remove
|
| 338 |
+
#trip_ids = list(trips["trip_id"])
|
| 339 |
+
#plot_df = st.session_state.data[st.session_state.data["trip_id"]==trip_ids[0]]
|
| 340 |
+
|
| 341 |
+
#TODO hållsplats
|
| 342 |
+
#Kolla på route_id för att plocka alla hållplatser
|
| 343 |
+
|
| 344 |
|
|
|
|
| 345 |
|
| 346 |
print(f"start time {type(start_time)}")
|
| 347 |
print(f"end time {type(end_time)}")
|
|
|
|
| 350 |
if start_time != None and end_time != None:
|
| 351 |
#TODO hur filtrera på tid?
|
| 352 |
st.write(f"Displaying buses between {start_time.strftime('%H:%M')} and {end_time.strftime('%H:%M')} the {day_choice}")
|
| 353 |
+
"""selected_trips = bus_trips[(bus_trips["datetime"] >= datetime.combine(date_options[day_choice], start_time))
|
| 354 |
+
& (bus_trips["datetime"] <= datetime.combine(date_options[day_choice], end_time))
|
| 355 |
+
& (bus_trips["direction_id"] == st.session_state.direction )]"""
|
| 356 |
selected_trips = bus_trips[(bus_trips["datetime"] >= datetime.combine(date_options[day_choice], start_time))
|
| 357 |
& (bus_trips["datetime"] <= datetime.combine(date_options[day_choice], end_time))
|
| 358 |
+
& (bus_trips["direction_id"] == st.session_state.direction )
|
| 359 |
+
& (bus_trips["stop_name"] == stop_choice)]
|
| 360 |
trip_ids = list(pd.unique(selected_trips["trip_id"]))
|
| 361 |
+
|
| 362 |
+
chioce = selected_trips[selected_trips["stop_name"]==stop_choice]
|
| 363 |
+
chioce.head()
|
| 364 |
+
chioce = chioce[["trip_id", "stop_name", "datetime"]]
|
| 365 |
+
#Ev lägga stop_chioce i session_state
|
| 366 |
+
|
| 367 |
+
chioce = chioce.sort_values(by=["datetime"])
|
| 368 |
+
chioce = chioce.drop_duplicates("datetime")
|
| 369 |
+
|
| 370 |
+
for idx, row in chioce.iterrows():
|
| 371 |
+
st.write(f"The bus arrives at {row['stop_name']} at {row['datetime'].strftime('%H:%M')}")
|
| 372 |
+
plot_graph_title(st.session_state.data[st.session_state.data["trip_id"]==row["trip_id"]], row["stop_name"], row['datetime'].strftime('%H:%M'))
|
| 373 |
+
|
| 374 |
st.write(f"Length {len(trip_ids)}")
|
| 375 |
for id in trip_ids:
|
| 376 |
plot_graph(st.session_state.data[st.session_state.data["trip_id"]==id])
|
test.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import pandas as pd
|
| 3 |
+
|
| 4 |
+
# Load local data
|
| 5 |
+
def load_local_data():
|
| 6 |
+
|
| 7 |
+
#filepath = os.path.join(current_dir, "test_data.csv")
|
| 8 |
+
filepath = "WheelyFunTimes/test_data.csv"
|
| 9 |
+
return pd.read_csv(filepath)
|
| 10 |
+
"""if os.path.exists(filepath):
|
| 11 |
+
return pd.read_csv(filepath)
|
| 12 |
+
else:
|
| 13 |
+
return None"""
|
| 14 |
+
|
| 15 |
+
def remove_near_duplicates(data):
|
| 16 |
+
print(data["trip_id"].nunique())
|
| 17 |
+
result = []
|
| 18 |
+
data["datetime"] = pd.to_datetime(data["datetime"])
|
| 19 |
+
for _, group in data.groupby(['route_id', 'stop_name']):
|
| 20 |
+
# Initialize a list to store rows that are not duplicates
|
| 21 |
+
filtered_rows = []
|
| 22 |
+
last_row = None
|
| 23 |
+
|
| 24 |
+
for idx, row in group.iterrows():
|
| 25 |
+
if last_row is None or (row['datetime'] - last_row['datetime'] > pd.Timedelta(minutes = 3)):
|
| 26 |
+
# Keep the row if it's the first or sufficiently far apart in time
|
| 27 |
+
filtered_rows.append(row)
|
| 28 |
+
last_row = row
|
| 29 |
+
|
| 30 |
+
# Add filtered rows to the result
|
| 31 |
+
result.extend(filtered_rows)
|
| 32 |
+
filtered_df = pd.DataFrame(result)
|
| 33 |
+
# Return the filtered dataframe
|
| 34 |
+
print(filtered_df["trip_id"].nunique())
|
| 35 |
+
return filtered_df
|
| 36 |
+
|
| 37 |
+
df = load_local_data()
|
| 38 |
+
print(df.head(12))
|
| 39 |
+
df = remove_near_duplicates(df)
|
| 40 |
+
print(df.head(12))
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
test_data.csv
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
direction_id,route_short_name,route_long_name,route_id,datetime,stop_lat,stop_lon,trip_id,temperature_2m,precipitation,wind_speed_10m,hourly_cloud_cover,dag_i_vecka,arbetsfri_dag,holiday,helgdag,squeeze_day,helgdagsafton,day_before_holiday,hour,minute,vehicle_occupancystatus,stop_name
|
| 2 |
+
FALSE,NO4,Kristianstad - Simrishamn,1,2025-01-05 13:04:37+00:01,9986.36.00,167.37.00,2,1.6,0.0,9935.39.00,87.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,13,15,1,Malmö Spångatan
|
| 3 |
+
TRUE,8,Lindängen - Västra hamnen,2,2025-01-05 15:50:14+00:00,9586.03.00,410.28.00,3,01.25,0.0,1623.03.00,83.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,15,50,0,Malmö Nydala
|
| 4 |
+
FALSE,3,Lindängen - Västra hamnen,2,2025-01-05 07:45:42+00:00,363.43.00,3756.51.00,3,1.9,0.0,4126.46.00,100.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,7,45,0,Viby Kvarnnäsvägen
|
| 5 |
+
FALSE,4,Lindängen - Västra hamnen,2,2025-01-05 14:27:33+00:00,11973.42.00,3358.39.00,3,01.35,0.0,10456.25.00,84.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,14,27,0,Lund Smörlyckan
|
| 6 |
+
FALSE,502,Lindängen - Västra hamnen,2,2025-01-05 14:45:15+00:00,7171.11.00,14479.54.00,3,01.35,0.0,10456.25.00,84.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,14,45,0,Båstad Kalkvägen
|
| 7 |
+
TRUE,511,Lund C - ESS (spårvagn),3,2025-01-05 12:44:36+00:00,12025.35.00,3912.03.00,5,01.25,0.0,1623.03.00,83.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,15,48,0,Lund Solbjer
|
| 8 |
+
TRUE,150,Lund C - ESS (spårvagn),3,2025-01-05 10:08:00+00:00,10014.42.00,4345.02.00,4,1.8,0.0,16011.59.00,97.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,10,8,1,Klågerup busstation
|
| 9 |
+
FALSE,5,Lund C - ESS (spårvagn),3,2025-01-05 10:09:00+00:00,10015.42.00,4346.02.00,6,01.25,0.0,1623.03.00,83.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,15,55,0,Klågerup busstation
|
| 10 |
+
TRUE,511,Lund C - ESS (spårvagn),3,2025-01-05 12:44:36+00:00,12025.35.00,3912.03.00,7,01.25,0.0,1623.03.00,83.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,15,48,0,Lund Solbjer
|
| 11 |
+
TRUE,150,Lund C - ESS (spårvagn),3,2025-01-05 10:08:00+00:00,10014.42.00,4345.02.00,7,1.8,0.0,16011.59.00,97.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,10,8,1,Klågerup busstation
|
| 12 |
+
TRUE,1,Lund C - ESS (spårvagn),3,2025-01-05 12:43:36+00:00,12024.35.00,3911.03.00,6,02.15,0.0,11580.39.00,90.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,12,43,0,Lund Solbjer
|
| 13 |
+
FALSE,817,Kristianstad - Simrishamn,1,2025-01-05 21:49:00+00:01,14016.02.00,1519.11.00,2,01.35,0.0,10456.25.00,84.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,14,20,1,Degeberga Skaddevägen
|
| 14 |
+
TRUE,174,Kristianstad - Simrishamn,1,2025-01-05 13:04:37+00:00,9985.36.00,166.37.00,1,1.6,0.0,9935.39.00,87.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,13,4,0,Malmö Spångatan
|
| 15 |
+
TRUE,1,Lund C - ESS (spårvagn),3,2025-01-05 12:43:36+00:00,12024.35.00,3911.03.00,4,02.15,0.0,11580.39.00,90.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,12,43,0,Lund Solbjer
|
| 16 |
+
FALSE,3,Kristianstad - Simrishamn,1,2025-01-05 21:49:00+00:00,14015.02.00,1518.11.00,1,1.4,0.2,1678.34.00,100.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,21,49,0,Degeberga Skaddevägen
|
| 17 |
+
FALSE,5,Lund C - ESS (spårvagn),3,2025-01-05 10:09:00+00:00,10015.42.00,4346.02.00,5,01.25,0.0,1623.03.00,83.0,7,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,15,55,0,Klågerup busstation
|