Use postgis to find existing places

This commit is contained in:
Eugene Burmakin 2025-03-03 21:34:06 +01:00
parent c2f6224421
commit d769861e69
8 changed files with 28 additions and 19 deletions

View file

@ -17,8 +17,7 @@ class Overland::BatchCreatingJob < ApplicationJob
def point_exists?(params, user_id)
Point.exists?(
latitude: params[:latitude],
longitude: params[:longitude],
lonlat: "POINT(#{params[:longitude]} #{params[:latitude]})",
timestamp: params[:timestamp],
user_id:
)

View file

@ -13,8 +13,7 @@ class Owntracks::PointCreatingJob < ApplicationJob
def point_exists?(params, user_id)
Point.exists?(
latitude: params[:latitude],
longitude: params[:longitude],
lonlat: "POINT(#{params[:longitude]} #{params[:latitude]})",
timestamp: params[:timestamp],
user_id:
)

View file

@ -9,8 +9,8 @@ class Api::PlaceSerializer
{
id: place.id,
name: place.name,
longitude: place.longitude,
latitude: place.latitude,
longitude: place.lon,
latitude: place.lat,
city: place.city,
country: place.country,
source: place.source,

View file

@ -16,8 +16,8 @@ class Api::VisitSerializer
name: name,
status: status,
place: {
latitude: visit.place&.latitude || visit.area&.latitude,
longitude: visit.place&.longitude || visit.area&.longitude,
latitude: visit.place&.lat || visit.area&.latitude,
longitude: visit.place&.lon || visit.area&.longitude,
id: visit.place&.id
}
}

View file

@ -14,8 +14,7 @@ class Points::Params
next unless params_valid?(point)
{
latitude: point[:geometry][:coordinates][1],
longitude: point[:geometry][:coordinates][0],
lonlat: "POINT(#{point[:geometry][:coordinates][0]} #{point[:geometry][:coordinates][1]})",
battery_status: point[:properties][:battery_state],
battery: battery_level(point[:properties][:battery_level]),
timestamp: DateTime.parse(point[:properties][:timestamp]),

View file

@ -32,8 +32,7 @@ class ReverseGeocoding::Places::FetchData
place.update!(
name: place_name(data),
latitude: data['geometry']['coordinates'][1],
longitude: data['geometry']['coordinates'][0],
lonlat: "POINT(#{data['geometry']['coordinates'][0]} #{data['geometry']['coordinates'][1]})",
city: data['properties']['city'],
country: data['properties']['country'],
geodata: data,
@ -79,7 +78,9 @@ class ReverseGeocoding::Places::FetchData
return found_place if found_place.present?
Place.find_or_initialize_by(
lonlat: "POINT(#{place_data['geometry']['coordinates'][0].to_f.round(5)} #{place_data['geometry']['coordinates'][1].to_f.round(5)})"
lonlat: "POINT(#{place_data['geometry']['coordinates'][0].to_f.round(5)} #{place_data['geometry']['coordinates'][1].to_f.round(5)})",
latitude: place_data['geometry']['coordinates'][1].to_f.round(5),
longitude: place_data['geometry']['coordinates'][0].to_f.round(5)
)
end

View file

@ -67,8 +67,7 @@ class Visits::Prepare
center_point = group.first
{
latitude: center_point.lat,
longitude: center_point.lon,
lonlat: "POINT(#{center_point.lon} #{center_point.lat})",
radius: calculate_radius(center_point, group),
points: group,
duration: (group.last.timestamp - group.first.timestamp).to_i / 60,

View file

@ -297,7 +297,7 @@ class Visits::SmartDetect
status: :suggested
)
visit_data[:points].each { |point| point.update!(visit_id: visit.id) }
Point.where(id: visit_data[:points].map(&:id)).update_all(visit_id: visit.id)
visit
end
@ -311,16 +311,28 @@ class Visits::SmartDetect
end
def find_or_create_place(visit_data)
# Round coordinates to reduce duplicate places
lat = visit_data[:center_lat].round(5)
lon = visit_data[:center_lon].round(5)
name = visit_data[:suggested_name]
# Define the search radius in meters
search_radius = 100 # Adjust this value as needed
# Use the Nearable module to find existing places within the search radius
existing_place = Place.near([lat, lon], search_radius, :m).where(name: name).first
return existing_place if existing_place
# If no existing place is found, create a new one
place = Place.find_or_initialize_by(
latitude: lat,
longitude: lon
lonlat: "POINT(#{lon} #{lat})"
)
unless place.persisted?
# Set latitude and longitude if needed
place.latitude = lat
place.longitude = lon
# Get reverse geocoding data
geocoded_data = Geocoder.search([lat, lon])