From 90bfd13f9511c2be41980603e93b06faf6e90229 Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Thu, 5 Sep 2024 23:12:21 +0200 Subject: [PATCH] Improve GeoJSON import service to work with FeatureCollection --- app/services/geojson/params.rb | 61 ++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/app/services/geojson/params.rb b/app/services/geojson/params.rb index c87ad072..8f5b728e 100644 --- a/app/services/geojson/params.rb +++ b/app/services/geojson/params.rb @@ -8,31 +8,56 @@ class Geojson::Params 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 + case json['type'] + when 'Feature' then process_feature(json) + when 'FeatureCollection' then process_feature_collection(json) + end end private + def process_feature(json) + json['features'].map do |point| + next if point[:geometry].nil? || point.dig(:properties, :timestamp).nil? + + build_point(point) + end.compact + end + + def process_feature_collection(json) + json['features'].map { |feature| process_feature(feature) } + end + + def build_point(point) + { + latitude: point[:geometry][:coordinates][1], + longitude: point[:geometry][:coordinates][0], + battery_status: point[:properties][:battery_state], + battery: battery_level(point[:properties][:battery_level]), + timestamp: timestamp(point), + altitude: altitude(point), + 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 + def battery_level(level) value = (level.to_f * 100).to_i value.positive? ? value : nil end + + def altitude(point) + point.dig(:properties, :altitude) || point.dig(:geometry, :coordinates, 2) + end + + def timestamp(point) + value = point.dig(:properties, :timestamp) || point.dig(:geometry, :coordinates, 3) + + Time.zone.at(value) + end end