diff options
| -rw-r--r-- | fietsboek/alembic/versions/20251019_90b39fdf6e4b.py | 12 | ||||
| -rw-r--r-- | fietsboek/convert.py | 21 | ||||
| -rw-r--r-- | fietsboek/models/__init__.py | 2 | ||||
| -rw-r--r-- | fietsboek/models/track.py | 27 |
4 files changed, 60 insertions, 2 deletions
diff --git a/fietsboek/alembic/versions/20251019_90b39fdf6e4b.py b/fietsboek/alembic/versions/20251019_90b39fdf6e4b.py index abc43fe..1213ebf 100644 --- a/fietsboek/alembic/versions/20251019_90b39fdf6e4b.py +++ b/fietsboek/alembic/versions/20251019_90b39fdf6e4b.py @@ -27,9 +27,21 @@ def upgrade(): sa.ForeignKeyConstraint(['track_id'], ['tracks.id'], name=op.f('fk_track_points_track_id_tracks')), sa.PrimaryKeyConstraint('track_id', 'index', name=op.f('pk_track_points')) ) + op.create_table('waypoints', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('track_id', sa.Integer(), nullable=False), + sa.Column('longitude', sa.Float(), nullable=True), + sa.Column('latitude', sa.Float(), nullable=True), + sa.Column('elevation', sa.Float(), nullable=True), + sa.Column('name', sa.Text(), nullable=True), + sa.Column('description', sa.Text(), nullable=True), + sa.ForeignKeyConstraint(['track_id'], ['tracks.id'], name=op.f('fk_waypoints_track_id_tracks')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_waypoints')) + ) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### op.drop_table('track_points') + op.drop_table('waypoints') # ### end Alembic commands ### diff --git a/fietsboek/convert.py b/fietsboek/convert.py index 5115dd7..04c7e73 100644 --- a/fietsboek/convert.py +++ b/fietsboek/convert.py @@ -6,7 +6,7 @@ import fitparse import gpxpy from . import geo, util -from .models import Track +from .models import Track, Waypoint FIT_RECORD_FIELDS = ["position_lat", "position_long", "altitude", "timestamp"] @@ -103,6 +103,25 @@ def from_gpx(data: bytes) -> Track: track.title = track_name track.description = track_desc track.date = date + + for waypoint in gpx.waypoints: + desc = None + # GPX waypoints can have both description and comment. It seems like + # comment is what is usually used (GPXViewer only shows the comment), + # so we'll prioritize that. + if waypoint.comment: + desc = waypoint.comment + if not desc and waypoint.description: + desc = waypoint.description + wpt = Waypoint( + longitude=waypoint.longitude, + latitude=waypoint.latitude, + elevation=waypoint.elevation, + name=waypoint.name, + description=desc, + ) + track.waypoints.append(wpt) + return track diff --git a/fietsboek/models/__init__.py b/fietsboek/models/__init__.py index 6f91eae..c70fee1 100644 --- a/fietsboek/models/__init__.py +++ b/fietsboek/models/__init__.py @@ -11,7 +11,7 @@ from sqlalchemy.orm import configure_mappers, sessionmaker from .badge import Badge # flake8: noqa from .comment import Comment # flake8: noqa from .image import ImageMetadata # flake8: noqa -from .track import Tag, Track, TrackCache, Upload # flake8: noqa +from .track import Tag, Track, TrackCache, Upload, Waypoint # flake8: noqa # Import or define all models here to ensure they are attached to the # ``Base.metadata`` prior to any initialization routines. diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py index 7a7aff0..33bbe3e 100644 --- a/fietsboek/models/track.py +++ b/fietsboek/models/track.py @@ -152,6 +152,19 @@ track_favourite_assoc = Table( ) +class Waypoint(Base): + __tablename__ = "waypoints" + id = Column(Integer, primary_key=True) + track_id = Column(Integer, ForeignKey("tracks.id"), nullable=False) + longitude = Column(Float) + latitude = Column(Float) + elevation = Column(Float) + name = Column(Text) + description = Column(Text) + + track: Mapped["Track"] = relationship("Track", back_populates="waypoints") + + class TrackPoint(Base): __tablename__ = "track_points" track_id = Column(Integer, ForeignKey("tracks.id"), primary_key=True) @@ -259,6 +272,9 @@ class Track(Base): points: Mapped[list["TrackPoint"]] = relationship( "TrackPoint", back_populates="track", cascade="all, delete-orphan", ) + waypoints: Mapped[list["Waypoint"]] = relationship( + "Waypoint", back_populates="track", cascade="all, delete-orphan", + ) cache: Mapped[Optional["TrackCache"]] = relationship( "TrackCache", back_populates="track", uselist=False, cascade="all, delete-orphan" ) @@ -385,6 +401,17 @@ class Track(Base): track = gpxpy.gpx.GPXTrack() track.segments.append(segment) gpx.tracks.append(track) + for wpt in self.waypoints: + gpx.waypoints.append( + gpxpy.gpx.GPXWaypoint( + longitude=wpt.longitude, + latitude=wpt.latitude, + elevation=wpt.elevation, + name=wpt.name, + comment=wpt.description, + description=wpt.description, + ) + ) return gpx.to_xml(prettyprint=False).encode("utf-8") @property |
