diff --git a/Gemfile b/Gemfile index 92c6d14f..592c2fd3 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ gem 'activerecord-postgis-adapter', github: 'StoneGod/activerecord-postgis-adapt gem 'puma' gem 'pundit' gem 'rails', '~> 8.0' +gem 'rgeo' gem 'rswag-api' gem 'rswag-ui' gem 'shrine', '~> 3.6' diff --git a/Gemfile.lock b/Gemfile.lock index 5460cf07..8407dd3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -484,6 +484,7 @@ DEPENDENCIES pundit rails (~> 8.0) redis + rgeo rspec-rails rswag-api rswag-specs diff --git a/app/javascript/controllers/trips_controller.js b/app/javascript/controllers/trips_controller.js index 602c04be..f512a208 100644 --- a/app/javascript/controllers/trips_controller.js +++ b/app/javascript/controllers/trips_controller.js @@ -1,17 +1,21 @@ import { Controller } from "@hotwired/stimulus" import L from "leaflet" -import { osmMapLayer } from "../maps/layers" +import { + osmMapLayer, + osmHotMapLayer, + OPNVMapLayer, + openTopoMapLayer, + cyclOsmMapLayer, + esriWorldStreetMapLayer, + esriWorldTopoMapLayer, + esriWorldImageryMapLayer, + esriWorldGrayCanvasMapLayer +} from "../maps/layers" import { createPopupContent } from "../maps/popups" -import { osmHotMapLayer } from "../maps/layers" -import { OPNVMapLayer } from "../maps/layers" -import { openTopoMapLayer } from "../maps/layers" -import { cyclOsmMapLayer } from "../maps/layers" -import { esriWorldStreetMapLayer } from "../maps/layers" -import { esriWorldTopoMapLayer } from "../maps/layers" -import { esriWorldImageryMapLayer } from "../maps/layers" -import { esriWorldGrayCanvasMapLayer } from "../maps/layers" -import { fetchAndDisplayPhotos } from '../maps/helpers'; -import { showFlashMessage } from "../maps/helpers"; +import { + fetchAndDisplayPhotos, + showFlashMessage +} from '../maps/helpers'; export default class extends Controller { static targets = ["container", "startedAt", "endedAt"] diff --git a/app/jobs/trips/create_path_job.rb b/app/jobs/trips/create_path_job.rb new file mode 100644 index 00000000..f36fa7cd --- /dev/null +++ b/app/jobs/trips/create_path_job.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class Trips::CreatePathJob < ApplicationJob + queue_as :default + + def perform(trip_id) + trip = Trip.find(trip_id) + trip.create_path! + end +end diff --git a/app/models/trip.rb b/app/models/trip.rb index 4a2b0302..00c2774a 100644 --- a/app/models/trip.rb +++ b/app/models/trip.rb @@ -9,6 +9,12 @@ class Trip < ApplicationRecord before_save :calculate_distance + def create_path! + self.path = Tracks::BuildPath.new(points.pluck(:latitude, :longitude)).call + + save! + end + def points user.tracked_points.where(timestamp: started_at.to_i..ended_at.to_i).order(:timestamp) end diff --git a/app/services/tracks/build_path.rb b/app/services/tracks/build_path.rb new file mode 100644 index 00000000..4feaf49c --- /dev/null +++ b/app/services/tracks/build_path.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class Tracks::BuildPath + def initialize(coordinates) + @coordinates = coordinates + end + + def call + factory.line_string( + coordinates.map { |point| factory.point(point[1].to_f.round(5), point[0].to_f.round(5)) } + ) + end + + private + + attr_reader :coordinates + + def factory + @factory ||= RGeo::Geographic.spherical_factory(srid: 3857) + end +end diff --git a/app/views/trips/show.html.erb b/app/views/trips/show.html.erb index f399eb3f..9d6dc4ee 100644 --- a/app/views/trips/show.html.erb +++ b/app/views/trips/show.html.erb @@ -25,6 +25,7 @@ data-api_key="<%= current_user.api_key %>" data-user_settings="<%= current_user.settings.to_json %>" data-coordinates="<%= @coordinates.to_json %>" + data-path="<%= @trip.path.to_json %>" data-timezone="<%= Rails.configuration.time_zone %>">
diff --git a/config/initializers/03_dawarich_settings.rb b/config/initializers/03_dawarich_settings.rb index 87cf4817..451ed716 100644 --- a/config/initializers/03_dawarich_settings.rb +++ b/config/initializers/03_dawarich_settings.rb @@ -17,5 +17,13 @@ class DawarichSettings def geoapify_enabled? @geoapify_enabled ||= GEOAPIFY_API_KEY.present? end + + def meters_between_tracks + @meters_between_tracks ||= 300 + end + + def minutes_between_tracks + @minutes_between_tracks ||= 20 + end end end diff --git a/db/data/20250123151849_create_paths_for_trips.rb b/db/data/20250123151849_create_paths_for_trips.rb new file mode 100644 index 00000000..6abcfff4 --- /dev/null +++ b/db/data/20250123151849_create_paths_for_trips.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class CreatePathsForTrips < ActiveRecord::Migration[8.0] + def up + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20250123145954_create_tracks.rb b/db/migrate/20250123145954_create_tracks.rb index 168d2c12..35c6afa1 100644 --- a/db/migrate/20250123145954_create_tracks.rb +++ b/db/migrate/20250123145954_create_tracks.rb @@ -6,7 +6,7 @@ class CreateTracks < ActiveRecord::Migration[8.0] t.datetime :started_at, null: false t.datetime :ended_at, null: false t.references :user, null: false, foreign_key: true - t.line_string :path, srid: 3785, null: false + t.line_string :path, srid: 3857, null: false t.timestamps end diff --git a/db/migrate/20250123151657_add_path_to_trips.rb b/db/migrate/20250123151657_add_path_to_trips.rb new file mode 100644 index 00000000..a5f121e7 --- /dev/null +++ b/db/migrate/20250123151657_add_path_to_trips.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddPathToTrips < ActiveRecord::Migration[8.0] + def change + add_column :trips, :path, :line_string, srid: 3857 + end +end diff --git a/db/schema.rb b/db/schema.rb index a85c60bd..7e9cca52 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_01_23_145954) do +ActiveRecord::Schema[8.0].define(version: 2025_01_23_151657) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" enable_extension "postgis" @@ -197,7 +197,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_23_145954) do t.datetime "started_at", null: false t.datetime "ended_at", null: false t.bigint "user_id", null: false - t.geometry "path", limit: {:srid=>3785, :type=>"line_string"}, null: false + t.geometry "path", limit: {:srid=>3857, :type=>"line_string"}, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["user_id"], name: "index_tracks_on_user_id" @@ -211,6 +211,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_23_145954) do t.bigint "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.geometry "path", limit: {:srid=>3857, :type=>"line_string"} t.index ["user_id"], name: "index_trips_on_user_id" end diff --git a/spec/jobs/trips/create_path_job_spec.rb b/spec/jobs/trips/create_path_job_spec.rb new file mode 100644 index 00000000..1dd711ef --- /dev/null +++ b/spec/jobs/trips/create_path_job_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Trips::CreatePathJob, type: :job do + pending "add some examples to (or delete) #{__FILE__}" +end