feat: implemented api

This commit is contained in:
2025-01-05 20:34:15 +01:00
parent c4de1d11ec
commit 695eaf576e
5 changed files with 189 additions and 25 deletions

View File

@ -2,28 +2,45 @@ from sqlalchemy.orm import Session
from geoObjects import Driver from geoObjects import Driver
class DriverHandler: class DriverHandler:
__dbSession: Session __dbSession: Session
def __init__(self, session:Session): def __init__(self, session: Session):
self.__dbSession = session self.__dbSession = session
pass pass
# handles creating a driver in the database # handles creating a driver in the database
def createDriver(self, name:str): def createDriver(self, name: str):
# makes sure that a name always is provided # makes sure that a name always is provided
if not name: if not name:
raise ValueError("name is empty") raise ValueError("name is empty")
self.__dbSession.add(Driver(name=name)) self.__dbSession.add(Driver(name=name))
self.__dbSession.commit() self.__dbSession.commit()
pass pass
# handles getting a driver by its id from the database # handles getting a driver by its id from the database
def getDriver(self, id:int): def getDriver(self, driverID: int):
pass driver = self.__dbSession.query(Driver).filter_by(id=driverID).first()
return {
"id": driver.id,
"name": driver.name
}
# handles getting all drivers from the database # handles getting all drivers from the database
def getDrivers(self): def getDrivers(self):
pass drivers = self.__dbSession.query(Driver).all()
driverList = [
{
"id": driver.id,
"name": driver.name
}
# iterates all drivers and appends them to the list
for driver in drivers
]
return driverList

View File

@ -0,0 +1,7 @@
class NotFoundError(Exception):
def __init__(self, message, errors):
# Call the base class constructor with the parameters it needs
super().__init__(message)
# Now for your custom code...
self.errors = errors

View File

@ -1,6 +1,12 @@
import datetime
import gpxpy import gpxpy
import gpxpy.gpx import gpxpy.gpx
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from geojson import Feature, LineString
from geopy.distance import geodesic
from errors.NotFoundException import NotFoundError
from geoObjects import Track, Waypoint
class GPXHandler: class GPXHandler:
__dbSession: Session __dbSession: Session
@ -10,14 +16,128 @@ class GPXHandler:
pass pass
# handles converting a gpx file into usable data # handles converting a gpx file into usable data
def parse(self, file): def parse(self, file, driver, vehicle):
self.gpx = gpxpy.parse(file) self.__gpx = gpxpy.parse(file)
pass
if not driver:
raise ValueError("no driver found")
if not vehicle:
raise ValueError("no vehicle found")
if not file:
raise ValueError("no file found")
for track in self.__gpx.tracks:
# sets track name
# if no name is found at a track default to using date
trackName = track.name or f"Track-{datetime.now().isoformat()}" # todo using time.now might end up being misleading and to be reworked
# initializes track values
self.__startTime,
self.__endTime,
self.__trackDistance,
self.__waypoints = None, None, 0, []
# grab all waypoints from a track
for segment in track.segments:
for point in segment.points:
self.__waypoints.append(point)
if start_time is None or point.time < start_time:
start_time = point.time
if end_time is None or point.time > end_time:
end_time = point.time
# calculate distance between 2 waypoints
for i in range(1, len(self.__waypoints)):
total_distance += self.__waypoints[i - 1].distance_3d(self.__waypoints[i])
# push values to the database
track = Track(
trackName=trackName,
vehicle=vehicle.id,
driver=driver.id,
date=start_time.date() if start_time else None,
distance=total_distance,
speed=0,
start=start_time,
end=end_time
)
self.__dbSession.add(track)
self.__dbSession.commit()
for point in self.__waypoints:
waypoint = Waypoint(
lat=point.latitude,
lon=point.longitude,
ele=point.elevation,
speed=None,
time=point.time,
track=track.id
)
self.__dbSession.add(waypoint)
self.__dbSession.commit()
# handles a route from db and converting it into geoJSON # handles a route from db and converting it into geoJSON
def getRoute(self, route): def getTrack(self, trackID):
pass track = self.__dbSession.query(Track).filter_by(id=trackID).first()
if not track:
raise NotFoundError(f"track with id {trackID} not found")
# fetches waypoints for a given track and converts them into geoJSON
waypoints = self.__dbSession.query(Waypoint).filter_by(track=track.id).all()
coordinates = [(wp.lon, wp.lat) for wp in waypoints]
feature = Feature(geometry=LineString(coordinates))
return feature
# handles calculating the distance between two points # grabs only the tracks from the database and returns them as json object
def calcDist(self, p1, p2): def getTracks(self):
pass tracks = self.__dbSession.query(Track).all()
track_list = [
{
"id": track.id,
"name": track.trackName,
"driver": {
"id": track.driver.id,
"name": track.driver.name
} if track.driver else None,
"vehicle": {
"id": track.vehicle.id,
"name": track.vehicle.name
} if track.vehicle else None,
"distance": track.distance,
"start_time": track.start.isoformat() if track.start else None,
"end_time": track.end.isoformat() if track.end else None,
}
for track in tracks # iterates all tracks and appends them to the list
]
return track_list
def getTracksInTime(self, start, end):
tracks = self.__dbSession.query(Track).filter(Track.start.between(start, end)).all()
track_list = [
{
"id": track.id,
"name": track.trackName,
"driver": {
"id": track.driver.id,
"name": track.driver.name
} if track.driver else None,
"vehicle": {
"id": track.vehicle.id,
"name": track.vehicle.name
} if track.vehicle else None,
"distance": track.distance,
"start_time": track.start.isoformat() if track.start else None,
"end_time": track.end.isoformat() if track.end else None,
}
for track in tracks # iterates all tracks and appends them to the list
]
return track_list

View File

@ -12,6 +12,10 @@ def getBase():
def createTables(engine): def createTables(engine):
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
engine.add(Driver(name="default"))
engine.add(Vehicle(name="default"))
engine.commit()
class Track(Base): class Track(Base):
__tablename__ = 'track' __tablename__ = 'track'
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
@ -25,8 +29,8 @@ class Track(Base):
end = Column(DateTime, nullable=False) end = Column(DateTime, nullable=False)
waypoints = relationship('Waypoint', backref='track', lazy=True) waypoints = relationship('Waypoint', backref='track', lazy=True)
driver = relationship('Driver', back_populates='track') driver = relationship('Driver', backref='track')
vehicle = relationship('Vehicle', back_populates='track') vehicle = relationship('Vehicle', backref='track')
pass pass

View File

@ -22,9 +22,25 @@ class VehicleHandler:
pass pass
# handles getting a vehicle identified with its id from the database # handles getting a vehicle identified with its id from the database
def getVehicle(self, id:int): def getVehicle(self, vehicleID:int):
pass vehicle = self.__dbSession.query(Vehicle).filter_by(id=vehicleID).first()
return {
"id": vehicle.id,
"name": vehicle.name
}
# handles getting all vehicles from database # handles getting all vehicles from database
def getVehicles(self): def getVehicles(self):
pass vehicles = self.__dbSession.query(Vehicle).all()
driverList = [
{
"id": vehicle.id,
"name": vehicle.name
}
# iterates all drivers and appends them to the list
for vehicle in vehicles
]
return driverList