From 2d85ab4370f59db89e06bdae92119f5be0d834dc Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 15 Jan 2021 13:44:20 +0000 Subject: [PATCH] feat: add location to organisations --- .../0029_organisation_location_fields.py | 23 +++++++++ people/models/person.py | 10 +++- people/static/js/map.js | 51 +++++++------------ people/templates/people/person/map.html | 2 +- people/views/person.py | 23 ++++----- 5 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 people/migrations/0029_organisation_location_fields.py diff --git a/people/migrations/0029_organisation_location_fields.py b/people/migrations/0029_organisation_location_fields.py new file mode 100644 index 0000000..7788b41 --- /dev/null +++ b/people/migrations/0029_organisation_location_fields.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.10 on 2021-01-15 13:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('people', '0028_person_location_fields'), + ] + + operations = [ + migrations.AddField( + model_name='organisation', + name='latitude', + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name='organisation', + name='longitude', + field=models.FloatField(blank=True, null=True), + ), + ] diff --git a/people/models/person.py b/people/models/person.py index 3009a29..c397281 100644 --- a/people/models/person.py +++ b/people/models/person.py @@ -69,6 +69,12 @@ class Organisation(models.Model): """ name = models.CharField(max_length=255, blank=False, null=False) + #: Latitude for displaying location on a map + latitude = models.FloatField(blank=True, null=True) + + #: Longitude for displaying location on a map + longitude = models.FloatField(blank=True, null=True) + def __str__(self) -> str: return self.name @@ -177,10 +183,10 @@ class PersonAnswerSet(AnswerSet): #: Project themes within this person works themes = models.ManyToManyField(Theme, related_name='people', blank=True) - #: Latitude for displaying locaiton on a map + #: Latitude for displaying location on a map latitude = models.FloatField(blank=True, null=True) - #: Longitude for displaying locaiton on a map + #: Longitude for displaying location on a map longitude = models.FloatField(blank=True, null=True) def get_absolute_url(self): diff --git a/people/static/js/map.js b/people/static/js/map.js index 0727969..b1e2978 100644 --- a/people/static/js/map.js +++ b/people/static/js/map.js @@ -15,7 +15,16 @@ let selected_marker_info = null; function createMarker(map, marker_data) { // Get the lat-long position from the data - const lat_lng = new google.maps.LatLng(marker_data.lat, marker_data.lng); + let lat_lng; + if (marker_data.lat != null && marker_data.lng != null) { + lat_lng = new google.maps.LatLng(marker_data.lat, marker_data.lng); + + } else if (marker_data.org_lat != null && marker_data.org_lng != null) { + lat_lng = new google.maps.LatLng(marker_data.org_lat, marker_data.org_lng); + + } else { + throw new Error(`No lat/lng set for marker '${marker_data.name}'`) + } const marker = new google.maps.Marker({ position: lat_lng, @@ -52,36 +61,6 @@ function createMarker(map, marker_data) { return marker; } -function search_missing_locations(map, markers_data) { - service = new google.maps.places.PlacesService(map) - - for (let data of markers_data) { - if (data.organisation !== null && (data.lat === null || data.lng === null)) { - let query = data.organisation; - if (data.country !== null) { - query += ' ' + data.country; - } - - const request = { - query: query, - fields: ['name', 'geometry'], - }; - - service.findPlaceFromQuery(request, (results, status) => { - if (status === google.maps.places.PlacesServiceStatus.OK) { - for (let i = 0; i < results.length; i++) { - // createMarker(results[i]); - console.log(results[i]) - } - map.setCenter(results[0].geometry.location); - } - }); - - break; - } - } -} - // The function called when Google Maps starts up function initMap() { map = new google.maps.Map( @@ -91,12 +70,16 @@ function initMap() { const bounds = new google.maps.LatLngBounds() const markers_data = JSON.parse( document.getElementById('map-markers').textContent) - search_missing_locations(map, markers_data); // For each data entry in the json... for (const marker_data of markers_data) { - const marker = createMarker(map, marker_data); - bounds.extend(marker.position) + try { + const marker = createMarker(map, marker_data); + bounds.extend(marker.position); + + } catch (exc) { + // Just skip and move on to next + } } map.fitBounds(bounds) diff --git a/people/templates/people/person/map.html b/people/templates/people/person/map.html index 45b4d5a..78c7803 100644 --- a/people/templates/people/person/map.html +++ b/people/templates/people/person/map.html @@ -7,7 +7,7 @@ {% endblock %} diff --git a/people/views/person.py b/people/views/person.py index 34615bd..3ecbb4b 100644 --- a/people/views/person.py +++ b/people/views/person.py @@ -102,33 +102,30 @@ class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView): def get_map_data(person: models.Person) -> typing.Dict[str, typing.Any]: + """Prepare data to mark people on a map.""" answer_set = person.current_answers + organisation = getattr(answer_set, 'organisation', None) + try: - latitude = answer_set.latitude or None - longitude = answer_set.longitude or None - organisation = answer_set.organisation.name or None - country = answer_set.country_of_residence.name or None + country = answer_set.country_of_residence.name except AttributeError: - latitude = None - longitude = None - organisation = None country = None return { 'name': person.name, - 'lat': latitude, - 'lng': longitude, - 'organisation': organisation, + 'lat': getattr(answer_set, 'latitude', None), + 'lng': getattr(answer_set, 'longitude', None), + 'organisation': getattr(organisation, 'name', None), + 'org_lat': getattr(organisation, 'latitude', None), + 'org_lng': getattr(organisation, 'longitude', None), 'country': country, 'url': reverse('people:person.detail', kwargs={'pk': person.pk}) } class PersonMapView(LoginRequiredMixin, ListView): - """ - View displaying a map of :class:`Person` locations. - """ + """View displaying a map of :class:`Person` locations.""" model = models.Person template_name = 'people/person/map.html'