Skip to content

Commit

Permalink
Merge pull request #628 from Freika/feature/geoapify-reverse-geocoding
Browse files Browse the repository at this point in the history
Implement support for Geoapify as reverse geocoding service
  • Loading branch information
Freika authored Jan 7, 2025
2 parents 10afb3f + 1229b41 commit 4eab6a4
Show file tree
Hide file tree
Showing 26 changed files with 186 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .app_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.21.4
0.21.5
3 changes: 0 additions & 3 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,10 @@ services:
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
MIN_MINUTES_SPENT_IN_CITY: 60
APPLICATION_HOST: localhost
APPLICATION_HOSTS: localhost
TIME_ZONE: Europe/London
APPLICATION_PROTOCOL: http
DISTANCE_UNIT: km
PHOTON_API_HOST: photon.komoot.io
PHOTON_API_USE_HTTPS: true
PROMETHEUS_EXPORTER_ENABLED: false
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
PROMETHEUS_EXPORTER_PORT: 9394
Expand Down
1 change: 0 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ DATABASE_PASSWORD=password
DATABASE_NAME=dawarich_development
DATABASE_PORT=5432
REDIS_URL=redis://localhost:6379/1
PHOTON_API_HOST='photon.komoot.io'
DISTANCE_UNIT='km'
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

# 0.21.5 - 2025-01-07

You may now use Geoapify API for reverse geocoding. To obtain an API key, sign up at https://myprojects.geoapify.com/ and create a new project. Make sure you have read and understood the [pricing policy](https://www.geoapify.com/pricing) and [Terms and Conditions](https://www.geoapify.com/terms-and-conditions/).

### Added

- Geoapify API support for reverse geocoding. Provide `GEOAPIFY_API_KEY` env var to use it.

### Removed

- Photon ENV vars from the `.env.development` and docker-compose.yml files.
- `APPLICATION_HOST` env var.
- `REVERSE_GEOCODING_ENABLED` env var.

# 0.21.4 - 2025-01-05

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions app/jobs/reverse_geocoding_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class ReverseGeocodingJob < ApplicationJob
queue_as :reverse_geocoding

def perform(klass, id)
return unless REVERSE_GEOCODING_ENABLED
return unless DawarichSettings.reverse_geocoding_enabled?

rate_limit_for_photon_api

Expand All @@ -18,8 +18,8 @@ def data_fetcher(klass, id)
end

def rate_limit_for_photon_api
return unless PHOTON_API_HOST == 'photon.komoot.io'
return unless DawarichSettings.photon_enabled?

sleep 1 if PHOTON_API_HOST == 'photon.komoot.io'
sleep 1 if DawarichSettings.photon_uses_komoot_io?
end
end
2 changes: 1 addition & 1 deletion app/models/place.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Place < ApplicationRecord
enum :source, { manual: 0, photon: 1 }

def async_reverse_geocode
return unless REVERSE_GEOCODING_ENABLED
return unless DawarichSettings.reverse_geocoding_enabled?

ReverseGeocodingJob.perform_later(self.class.to_s, id)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/point.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def recorded_at
end

def async_reverse_geocode
return unless REVERSE_GEOCODING_ENABLED
return unless DawarichSettings.reverse_geocoding_enabled?

ReverseGeocodingJob.perform_later(self.class.to_s, id)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/visit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def center
end

def async_reverse_geocode
return unless REVERSE_GEOCODING_ENABLED
return unless DawarichSettings.reverse_geocoding_enabled?
return if place.blank?

ReverseGeocodingJob.perform_later('place', place_id)
Expand Down
4 changes: 2 additions & 2 deletions app/services/reverse_geocoding/places/fetch_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def initialize(place_id)
end

def call
if ::PHOTON_API_HOST.blank?
Rails.logger.warn('PHOTON_API_HOST is not set')
unless DawarichSettings.reverse_geocoding_enabled?
Rails.logger.warn('Reverse geocoding is not enabled')
return
end

Expand Down
6 changes: 1 addition & 5 deletions app/services/visits/suggest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def call

create_visits_notification(user)

return nil unless reverse_geocoding_enabled?
return nil unless DawarichSettings.reverse_geocoding_enabled?

reverse_geocode(visits)
end
Expand Down Expand Up @@ -68,10 +68,6 @@ def reverse_geocode(visits)
visits.each(&:async_reverse_geocode)
end

def reverse_geocoding_enabled?
::REVERSE_GEOCODING_ENABLED && ::PHOTON_API_HOST.present?
end

def create_visits_notification(user)
content = <<~CONTENT
New visits have been suggested based on your location data from #{Time.zone.at(start_at)} to #{Time.zone.at(end_at)}. You can review them on the <a href="#{visits_path}" class="link">Visits</a> page.
Expand Down
2 changes: 1 addition & 1 deletion app/views/stats/_stat.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</div>
</div>
<p><%= stat.distance %><%= DISTANCE_UNIT %></p>
<% if REVERSE_GEOCODING_ENABLED %>
<% if DawarichSettings.reverse_geocoding_enabled? %>
<div class="card-actions justify-end">
<%= countries_and_cities_stat_for_month(stat) %>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/views/stats/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class="stat-title">Geopoints tracked</div>
</div>

<% if REVERSE_GEOCODING_ENABLED %>
<% if DawarichSettings.reverse_geocoding_enabled? %>
<%= render 'stats/reverse_geocoding_stats' %>
<% end %>
</div>
Expand All @@ -39,7 +39,7 @@
<%= number_with_delimiter year_distance_stat(year, current_user) %><%= DISTANCE_UNIT %>
<% end %>
</p>
<% if REVERSE_GEOCODING_ENABLED %>
<% if DawarichSettings.reverse_geocoding_enabled? %>
<div class="card-actions justify-end">
<%= countries_and_cities_stat_for_year(year, stats) %>
</div>
Expand Down
8 changes: 4 additions & 4 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@

# Raise error when a before_action's only/except options reference missing actions
config.action_controller.raise_on_missing_callback_actions = true
config.action_mailer.default_url_options = { host: ENV.fetch('APPLICATION_HOST', 'localhost'), port: 3000 }
config.hosts << ENV.fetch('APPLICATION_HOST', 'localhost')

hosts = ENV.fetch('APPLICATION_HOSTS', 'localhost')
config.hosts.concat(hosts.split(',')) if hosts.present?
hosts = ENV.fetch('APPLICATION_HOSTS', 'localhost').split(',')

config.action_mailer.default_url_options = { host: hosts.first, port: 3000 }
config.hosts.concat(hosts) if hosts.present?

config.force_ssl = ENV.fetch('APPLICATION_PROTOCOL', 'http').downcase == 'https'

Expand Down
14 changes: 10 additions & 4 deletions config/initializers/01_constants.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# frozen_string_literal: true

MIN_MINUTES_SPENT_IN_CITY = ENV.fetch('MIN_MINUTES_SPENT_IN_CITY', 60).to_i
REVERSE_GEOCODING_ENABLED = ENV.fetch('REVERSE_GEOCODING_ENABLED', 'true') == 'true'
PHOTON_API_HOST = ENV.fetch('PHOTON_API_HOST', nil)
PHOTON_API_KEY = ENV.fetch('PHOTON_API_KEY', nil)
PHOTON_API_USE_HTTPS = ENV.fetch('PHOTON_API_USE_HTTPS', 'true') == 'true'
DISTANCE_UNIT = ENV.fetch('DISTANCE_UNIT', 'km').to_sym

APP_VERSION = File.read('.app_version').strip

TELEMETRY_STRING = Base64.encode64('IjVFvb8j3P9-ArqhSGav9j8YcJaQiuNIzkfOPKQDk2lvKXqb8t1NSRv50oBkaKtlrB_ZRzO9NdurpMtncV_HYQ==')
TELEMETRY_URL = 'https://influxdb2.frey.today/api/v2/write'

# Reverse geocoding settings
PHOTON_API_HOST = ENV.fetch('PHOTON_API_HOST', nil)
PHOTON_API_KEY = ENV.fetch('PHOTON_API_KEY', nil)
PHOTON_API_USE_HTTPS = ENV.fetch('PHOTON_API_USE_HTTPS', 'true') == 'true'

GEOAPIFY_API_KEY = ENV.fetch('GEOAPIFY_API_KEY', nil)
# /Reverse geocoding settings
21 changes: 21 additions & 0 deletions config/initializers/03_dawarich_settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

class DawarichSettings
class << self
def reverse_geocoding_enabled?
@reverse_geocoding_enabled ||= photon_enabled? || geoapify_enabled?
end

def photon_enabled?
@photon_enabled ||= PHOTON_API_HOST.present?
end

def photon_uses_komoot_io?
@photon_uses_komoot_io ||= PHOTON_API_HOST == 'photon.komoot.io'
end

def geoapify_enabled?
@geoapify_enabled ||= GEOAPIFY_API_KEY.present?
end
end
end
8 changes: 5 additions & 3 deletions config/initializers/geocoder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
}
}

if defined?(PHOTON_API_HOST)
if PHOTON_API_HOST.present?
settings[:lookup] = :photon
settings[:photon] = { use_https: PHOTON_API_USE_HTTPS, host: PHOTON_API_HOST }
settings[:http_headers] = { 'X-Api-Key' => PHOTON_API_KEY } if defined?(PHOTON_API_KEY)
elsif GEOAPIFY_API_KEY.present?
settings[:lookup] = :geoapify
settings[:api_key] = GEOAPIFY_API_KEY
end

settings[:http_headers] = { 'X-Api-Key' => PHOTON_API_KEY } if defined?(PHOTON_API_KEY)

Geocoder.configure(settings)
2 changes: 1 addition & 1 deletion config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
config.redis = { url: ENV['REDIS_URL'] }
end

Sidekiq::Queue['reverse_geocoding'].limit = 1 if Sidekiq.server? && PHOTON_API_HOST == 'photon.komoot.io'
Sidekiq::Queue['reverse_geocoding'].limit = 1 if Sidekiq.server? && DawarichSettings.photon_uses_komoot_io?
6 changes: 0 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,10 @@ services:
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
MIN_MINUTES_SPENT_IN_CITY: 60
APPLICATION_HOST: localhost
APPLICATION_HOSTS: localhost
TIME_ZONE: Europe/London
APPLICATION_PROTOCOL: http
DISTANCE_UNIT: km
PHOTON_API_HOST: photon.komoot.io
PHOTON_API_USE_HTTPS: true
PROMETHEUS_EXPORTER_ENABLED: false
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
PROMETHEUS_EXPORTER_PORT: 9394
Expand Down Expand Up @@ -117,13 +114,10 @@ services:
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
APPLICATION_HOST: localhost
APPLICATION_HOSTS: localhost
BACKGROUND_PROCESSING_CONCURRENCY: 10
APPLICATION_PROTOCOL: http
DISTANCE_UNIT: km
PHOTON_API_HOST: photon.komoot.io
PHOTON_API_USE_HTTPS: true
PROMETHEUS_EXPORTER_ENABLED: false
PROMETHEUS_EXPORTER_HOST: dawarich_app
PROMETHEUS_EXPORTER_PORT: 9394
Expand Down
6 changes: 0 additions & 6 deletions docker-compose_mounted_volumes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,9 @@ services:
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
MIN_MINUTES_SPENT_IN_CITY: 60
APPLICATION_HOST: localhost
APPLICATION_HOSTS: localhost
APPLICATION_PROTOCOL: http
DISTANCE_UNIT: km
PHOTON_API_HOST: photon.komoot.io
PHOTON_API_USE_HTTPS: true
stdin_open: true
tty: true
entrypoint: dev-entrypoint.sh
Expand Down Expand Up @@ -96,13 +93,10 @@ services:
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
APPLICATION_HOST: localhost
APPLICATION_HOSTS: localhost
BACKGROUND_PROCESSING_CONCURRENCY: 10
APPLICATION_PROTOCOL: http
DISTANCE_UNIT: km
PHOTON_API_HOST: photon.komoot.io
PHOTON_API_USE_HTTPS: true
stdin_open: true
tty: true
entrypoint: dev-entrypoint.sh
Expand Down
14 changes: 6 additions & 8 deletions docs/how_to_setup_reverse_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dawarich_app:
...
environment:
...
APPLICATION_HOST: "yourhost.com" <------------------------------ Edit this
APPLICATION_HOSTS: "yourhost.com,www.yourhost.com,127.0.0.1" <-- Edit this
```
Expand All @@ -25,7 +24,6 @@ dawarich_sidekiq:
...
environment:
...
APPLICATION_HOST: "yourhost.com" <------------------------------ Edit this
APPLICATION_HOSTS: "yourhost.com,www.yourhost.com,127.0.0.1" <-- Edit this
...
```
Expand All @@ -48,7 +46,7 @@ server {
brotli on;
brotli_comp_level 6;
brotli_types
brotli_types
text/css
text/plain
text/xml
Expand Down Expand Up @@ -106,24 +104,24 @@ With the above commands entered, the configuration below should work properly.
```apache
<VirtualHost *:80>
ServerName example.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
Header always set X-Real-IP %{REMOTE_ADDR}s
Header always set X-Forwarded-For %{REMOTE_ADDR}s
Header always set X-Forwarded-Proto https
Header always set X-Forwarded-Server %{SERVER_NAME}s
Header always set Host %{HTTP_HOST}s
SetOutputFilter BROTLI
AddOutputFilterByType BROTLI_COMPRESS text/css text/plain text/xml text/javascript application/javascript application/json application/manifest+json application/vnd.api+json application/xml application/xhtml+xml application/rss+xml application/atom+xml application/vnd.ms-fontobject application/x-font-ttf application/x-font-opentype application/x-font-truetype image/svg+xml image/x-icon image/vnd.microsoft.icon font/ttf font/eot font/otf font/opentype
BrotliCompressionQuality 6
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
Expand Down
8 changes: 4 additions & 4 deletions spec/jobs/reverse_geocoding_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
allow(Geocoder).to receive(:search).and_return([double(city: 'City', country: 'Country')])
end

context 'when REVERSE_GEOCODING_ENABLED is false' do
before { stub_const('REVERSE_GEOCODING_ENABLED', false) }
context 'when reverse geocoding is disabled' do
before { allow(DawarichSettings).to receive(:reverse_geocoding_enabled?).and_return(false) }

it 'does not update point' do
expect { perform }.not_to(change { point.reload.city })
Expand All @@ -28,8 +28,8 @@
end
end

context 'when REVERSE_GEOCODING_ENABLED is true' do
before { stub_const('REVERSE_GEOCODING_ENABLED', true) }
context 'when reverse geocoding is enabled' do
before { allow(DawarichSettings).to receive(:reverse_geocoding_enabled?).and_return(true) }

let(:stubbed_geocoder) { OpenStruct.new(data: { city: 'City', country: 'Country' }) }

Expand Down
Loading

0 comments on commit 4eab6a4

Please sign in to comment.