I have a geodjango queryset containing several fields but want to use only user_name
and location
(a point field) which I want to use as a marker in google maps API 3.
Bear with me as I don’t know Javascript and I have a series of questions.
Take this as conceptual brainstorming for a novice:
My SO search suggests that I need to serialize the queryset objects
to JSON. I use the built-in serializer module to convert to JSON.
I think the JSON objects are converted in views.py
(let’s
call it json_data
). Are these JSON objects stored in the PostGIS database? Wouldn’t that be redundant?
Furthermore, how do I reference them in the map.js
(google maps
API 3) javascript file?
I want to (import?link?) JSON objects to display them as location markers.
I want to know how to declare and iterate the javascript variable
locations
.
For var(i=0;i< locations.length;i++){[
[json_data.user_name, json_data.point],
]
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(49.279504, -123.1162),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
icon: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
Guide me if I went unnecessarily convoluted way to do a simple task.
TL;DR
getJSON()
or similar call to your API's endpoint to access the data.What you are thinking is pretty much correct but there is room for improvement (thus the long answer below).
Answer:
Some time ago I read a very good initiation tutorial on building a GIS application with geodjango and google maps. Read it and it should give you a great jump start.
After you read that we will follow a somewhat different way which leaves more room to play around with your front-end (use react for example or whatever comes to mind).
The back-end:
Create a view to retrieve the information you want (user_name
, location
) as JSON, using the values()
queryset method which returns a list of dictionaries.
Since we have to JSONify a list, we will use JsonResponse
and we will mark it as unsafe:
from django.http import JsonResponse
def my_view(request):
resp = MyModel.objects.all().values('user_name', 'location')
return JsonResponse(list(resp), safe=False)
Add an endpoint to access that view on urls.py
:
urlpatterns = [
...
url(r'^my_endpoint/$', my_view, name='my_endpoint'),
...
]
Now whenever we access the my_endpoint/
we will get a JSON representation of every object's user_name
and location
in our database which will look like this:
[
{user_name: a_user, location: [lat, lng]},
{user_name: another_user, location: [lat, lng]},
...
]
Moving to the front-end now:
Make a getJSON()
or an ajax()
or any other type of call to the API and in the same time create a marker list (close to what @MoshFeu suggests):
let map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(49.279504, -123.1162),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
let markers = [];
$.getJSON( "my_base_url/my_endpoint", function(data) {
$.each(data, function() {
markers.push(
new google.maps.Marker({
position: {
lat: data['location'][0],
lng: data['location'][1]
},
map: map,
icon: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'
})
);
});
});
...
And we are pretty much done!
You don't need to make any special serialization to your data.
You can query the data from any type of front-end you can imagine which gives you designing freedom.