mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
feat: add location to organisations
This commit is contained in:
23
people/migrations/0029_organisation_location_fields.py
Normal file
23
people/migrations/0029_organisation_location_fields.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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):
|
||||||
|
|||||||
@@ -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) {
|
||||||
const marker = createMarker(map, marker_data);
|
try {
|
||||||
bounds.extend(marker.position)
|
const marker = createMarker(map, marker_data);
|
||||||
|
bounds.extend(marker.position);
|
||||||
|
|
||||||
|
} catch (exc) {
|
||||||
|
// Just skip and move on to next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map.fitBounds(bounds)
|
map.fitBounds(bounds)
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user