From 1a2777417734528ad279d2a22a4929a025f95b11 Mon Sep 17 00:00:00 2001 From: James Graham Date: Wed, 16 Dec 2020 12:09:10 +0000 Subject: [PATCH] feat: add location search to picker Requires API key with Google Places API access Currently untested --- people/static/js/location_picker.js | 62 ++++++++++++++++++++-- people/templates/people/person/update.html | 5 +- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/people/static/js/location_picker.js b/people/static/js/location_picker.js index 0488204..8b9ffa2 100644 --- a/people/static/js/location_picker.js +++ b/people/static/js/location_picker.js @@ -12,6 +12,10 @@ const marker_edge_width = 1.0; let marker = null; +/** + * Position a map marker at the clicked location and update lat/long form fields. + * @param {Event} event - Click event from a Google Map. + */ function selectLocation(event) { if (marker === null) { // Generate a new marker @@ -34,16 +38,66 @@ function selectLocation(event) { } const pos = marker.getPosition(); - console.log(pos.lat(), pos.lng()); document.getElementById('id_latitude').value = pos.lat(); document.getElementById('id_longitude').value = pos.lng(); } -// The function called when Google Maps starts up +/** + * Initialise Google Maps element after library is loaded. + */ function initMap() { - const centre_latlng = new google.maps.LatLng(settings.centre_lat, settings.centre_lng); + const centre_latlng = new google.maps.LatLng(settings.centre_lat | 0, settings.centre_lng | 0); const map = new google.maps.Map( document.getElementById('map'), { zoom: settings.zoom, center: centre_latlng }); - google.maps.event.addListener(map, 'click', selectLocation) + const search_input = document.getElementById('location-search') + const search_box = new google.maps.places.SearchBox(search_input) + map.controls[google.maps.ControlPosition.TOP_LEFT].push(search_input) + + map.addListener('bounds_changed', () => { + search_box.setBounds(map.getBounds()) + }) + + let markers = [] + + search_box.addListener('places_changed', () => { + const places = search_box.getPlaces() + + if (places.length === 0) return + + for (const marker of markers) marker.setMap(null) + markers = [] + + const bounds = new google.maps.LatLngBounds() + for (const place of places) { + if (!place.geometry) { + console.error('Place contains no geometry') + continue + } + + const icon = { + size: new google.maps.Size(71, 71), + origin: new google.maps.Point(0, 0), + anchor: new google.maps.Point(17, 34), + scaledSize: new google.maps.Size(25, 25), + } + + markers.push( + new google.maps.Marker({ + map, icon, title: place.name, position: place.geometry.location + }) + ) + + if (place.geometry.viewport) { + bounds.union(place.geometry.viewport) + } else { + bounds.extend(place.geometry.location) + } + + } + + map.fitBounds(bounds) + }) + + map.addListener('click', selectLocation) } diff --git a/people/templates/people/person/update.html b/people/templates/people/person/update.html index 6bc0e5e..2e22b07 100644 --- a/people/templates/people/person/update.html +++ b/people/templates/people/person/update.html @@ -12,7 +12,7 @@ ] const settings = { - zoom: 8, + zoom: 2, centre_lat: '{{ answer_set.latitude }}', centre_lng: '{{ answer_set.longitude }}', } @@ -20,7 +20,7 @@ - {% endblock %} @@ -58,6 +58,7 @@
+