Implement GeoJSON import

This commit is contained in:
Eugene Burmakin 2024-09-02 22:33:54 +02:00
parent 3238fb64e6
commit 8bb6a9afb5
5 changed files with 81 additions and 1 deletions

View file

@ -32,6 +32,7 @@ class ImportJob < ApplicationJob
when 'owntracks' then OwnTracks::ExportParser
when 'gpx' then Gpx::TrackParser
when 'immich_api' then Immich::ImportParser
when 'geojson' then Geojson::ImportParser
end
end

View file

@ -10,6 +10,6 @@ class Import < ApplicationRecord
enum source: {
google_semantic_history: 0, owntracks: 1, google_records: 2,
google_phone_takeout: 3, gpx: 4, immich_api: 5
google_phone_takeout: 3, gpx: 4, immich_api: 5, geojson: 6
}
end

View file

@ -0,0 +1,32 @@
# frozen_string_literal: true
class Geojson::ImportParser
attr_reader :import, :json, :user_id
def initialize(import, user_id)
@import = import
@json = import.raw_data
@user_id = user_id
end
def call
data = Geojson::Params.new(json).call
data.each do |point|
next if point_exists?(point, user_id)
Point.create!(point.merge(user_id:, import_id: import.id))
end
end
private
def point_exists?(params, user_id)
Point.exists?(
latitude: params[:latitude],
longitude: params[:longitude],
timestamp: params[:timestamp],
user_id:
)
end
end

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
class Geojson::Params
attr_reader :json
def initialize(json)
@json = json.with_indifferent_access
end
def call
json['features'].map do |point|
next if point[:geometry].nil? || point.dig(:properties, :timestamp).nil?
{
latitude: point[:geometry][:coordinates][1],
longitude: point[:geometry][:coordinates][0],
battery_status: point[:properties][:battery_state],
battery: battery_level(point[:properties][:battery_level]),
timestamp: Time.zone.at(point[:properties][:timestamp]),
altitude: point[:properties][:altitude],
velocity: point[:properties][:speed],
tracker_id: point[:properties][:device_id],
ssid: point[:properties][:wifi],
accuracy: point[:properties][:horizontal_accuracy],
vertical_accuracy: point[:properties][:vertical_accuracy],
raw_data: point
}
end.compact
end
private
def battery_level(level)
value = (level.to_f * 100).to_i
value.positive? ? value : nil
end
end

View file

@ -22,6 +22,15 @@
<p class="text-sm mt-2">A JSON file you exported by pressing Download button in top right corner of OwnTracks web interface</p>
</div>
</div>
<div class="card bordered shadow-lg p-3 hover:shadow-blue-500/50">
<div class="form-control">
<label class="label cursor-pointer space-x-3">
<%= form.radio_button :source, :geojson, class: "radio radio-primary" %>
<span class="label-text">GeoJSON</span>
</label>
<p class="text-sm mt-2">A valid GeoJSON file. For example, a file, exported from a Dawarich instance</p>
</div>
</div>
<div class="card bordered shadow-lg p-3 hover:shadow-blue-500/50">
<div class="form-control">
<label class="label cursor-pointer space-x-3">