feat: add location to organisations

This commit is contained in:
James Graham
2021-01-15 13:44:20 +00:00
parent 95fda6a3d5
commit 2d85ab4370
5 changed files with 59 additions and 50 deletions

View File

@@ -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),
),
]

View File

@@ -69,6 +69,12 @@ class Organisation(models.Model):
""" """
name = models.CharField(max_length=255, blank=False, null=False) 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: def __str__(self) -> str:
return self.name return self.name
@@ -177,10 +183,10 @@ class PersonAnswerSet(AnswerSet):
#: Project themes within this person works #: Project themes within this person works
themes = models.ManyToManyField(Theme, related_name='people', blank=True) 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) 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) longitude = models.FloatField(blank=True, null=True)
def get_absolute_url(self): def get_absolute_url(self):

View File

@@ -15,7 +15,16 @@ let selected_marker_info = null;
function createMarker(map, marker_data) { function createMarker(map, marker_data) {
// Get the lat-long position from the 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({ const marker = new google.maps.Marker({
position: lat_lng, position: lat_lng,
@@ -52,36 +61,6 @@ function createMarker(map, marker_data) {
return marker; 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 // The function called when Google Maps starts up
function initMap() { function initMap() {
map = new google.maps.Map( map = new google.maps.Map(
@@ -91,12 +70,16 @@ function initMap() {
const bounds = new google.maps.LatLngBounds() const bounds = new google.maps.LatLngBounds()
const markers_data = JSON.parse( const markers_data = JSON.parse(
document.getElementById('map-markers').textContent) document.getElementById('map-markers').textContent)
search_missing_locations(map, markers_data);
// For each data entry in the json... // For each data entry in the json...
for (const marker_data of markers_data) { for (const marker_data of markers_data) {
try {
const marker = createMarker(map, marker_data); const marker = createMarker(map, marker_data);
bounds.extend(marker.position) bounds.extend(marker.position);
} catch (exc) {
// Just skip and move on to next
}
} }
map.fitBounds(bounds) map.fitBounds(bounds)

View File

@@ -7,7 +7,7 @@
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>
<script async defer <script async defer
src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&libraries=places&callback=initMap" src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap"
type="text/javascript"></script> type="text/javascript"></script>
{% endblock %} {% endblock %}

View File

@@ -102,33 +102,30 @@ class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView):
def get_map_data(person: models.Person) -> typing.Dict[str, typing.Any]: 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 answer_set = person.current_answers
organisation = getattr(answer_set, 'organisation', None)
try: try:
latitude = answer_set.latitude or None country = answer_set.country_of_residence.name
longitude = answer_set.longitude or None
organisation = answer_set.organisation.name or None
country = answer_set.country_of_residence.name or None
except AttributeError: except AttributeError:
latitude = None
longitude = None
organisation = None
country = None country = None
return { return {
'name': person.name, 'name': person.name,
'lat': latitude, 'lat': getattr(answer_set, 'latitude', None),
'lng': longitude, 'lng': getattr(answer_set, 'longitude', None),
'organisation': organisation, 'organisation': getattr(organisation, 'name', None),
'org_lat': getattr(organisation, 'latitude', None),
'org_lng': getattr(organisation, 'longitude', None),
'country': country, 'country': country,
'url': reverse('people:person.detail', kwargs={'pk': person.pk}) 'url': reverse('people:person.detail', kwargs={'pk': person.pk})
} }
class PersonMapView(LoginRequiredMixin, ListView): class PersonMapView(LoginRequiredMixin, ListView):
""" """View displaying a map of :class:`Person` locations."""
View displaying a map of :class:`Person` locations.
"""
model = models.Person model = models.Person
template_name = 'people/person/map.html' template_name = 'people/person/map.html'