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 %>">