2023-05-31 - Geocoding and Maps
main topics
- Geocoding
- Mapbox
Geocoding
Geocode: translates an address into coordinates.
checklist
install & config
bundle add geocoder
rails generate geocoder:config
- creates
config/initializers/geocoder.rb
- creates
- change the
geocoder.rb
initializer:units: :km
rails generate migration AddCoordinatesToFlats latitude:float longitude:float
- assuming the Flat model has the address
rails db:migrate
- update the Flat model:
geocoded_by :address
after_validation :geocode, if: :will_save_change_to_address?
map
- get mapbox API token and save in the
.env
file - be sure to gitignore the
.env
file - install Mapbox GL JS
- put a
<div id="map"></div>
in your Flat#index view (instructions here) rails generate stimulus map
- creates
app/javascript/controllers/map_controllers.js
- creates
- in the
connect()
method, put the mapboxgl code - connect your "map div" to the map controller
- pass the api key as
data-map-api-key-value="<%= ENV['MAPBOX_API_KEY'] %>"
rails server
and check if the map is being displayed
markers
- in the stimulus controller, create the
#addMarkersToMap()
method using the setLngLat() method from Mapbox GL JS. - test in the map to see if the marker is being displayed
- edit the Flats controller to get the markers for the geocoded addresses
def index
@flats = Flat.all
@markers = @flats.geocoded.map do |flat|
{
lat: flat.latitude,
lng: flat.longitude
}
end
end
- pass the
@markers
to the stimulus controller with: `data-map-markers-value="<%= @markers.to_json %>" - use fit map to markers
lecture
rails new \
-d postgresql \
-j webpack \
-m https://raw.githubusercontent.com/lewagon/rails-templates/master/minimal.rb \
rails-geocoding
cd rails-geocoding
# CRUD for a flat
# rails scaffold # To be done...
Ruby Gem for Geocoding:
https://github.com/alexreisner/geocoder
bundle add geocoder
rails generate geocoder:config
# creates 'config/initializers/geocoder.rb'
In the config/initializers/geocoder.rb
, change units:
to use :km
.
Change lookup
if you want to customize the service that will do the geocoding (default is nominatim).
We need coordinates in our DB Table/Model:
rails generate migration \
AddCoordinatesToFlats latitude:float longitude:float
rails db:migrate
Update the model
geocoded_by :address
after_validation :geocode, if: :will_save_change_to_address?
Use mapbox for displaying a map. Get your API token and save it in the .env
file (don't forget to put .env*
in your .gitignore
).
mapbox docs: https://docs.mapbox.com/mapbox-gl-js/guides/install/#quickstart
<!-- app/views/layouts/application.html.erb -->
<link href="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.css" rel="stylesheet">
<the-script src="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.js"></the-script>
<!-- rename the-script into script after copy-paste -->
13:30 - Edit Rails controller
16:00 - put a map in the view. Mapbox GL JS Installation Guide: https://docs.mapbox.com/mapbox-gl-js/guides/install/
17:30 - generate a stimulus controller
20:20 - pass the api key to the stimulus controller
22:00 - in the stimulus controller, customize the center
array according to the current browser location.
navigator.geolocation.getCurrentPosition((data) => {
console.log(data.coords.latitude, data.coords.longitude)
})
23:50 - how to create a marker
30:00 - sending @markers
from the controller to the view.
35:00 - fit map to markers
#fitMapToMarkers() {
const bounds = new mapboxgl.LngLatBounds();
this.markersValue.forEach(marker => bounds.extend([marker.lng, marker.lat ]))
this.map.fitBounds(bounds, { padding: 70, maxZoom: 15, duration: 0 })
}
41:10 - pass api key to heroku
heroku config:set MAPBOX_API_KEY=...
41:30 - pass more info to the view
- 47:40 - enrich the data in the @markers
being created in the Flat controller
- create a partial
49:30 - custom marker
56:20 - searching on the map - REALLY COOL
59:28 - styling your map
1:00:00 - address autocomplete