Skip to content Skip to sidebar Skip to footer

How To Integrate Geodjango With Google Maps API 3?

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

Solution 1:

TL;DR

  1. No, what you are doing is not redundant and nothing get's written to the database from those answers.
  2. You need to make a getJSON() or similar call to your API's endpoint to access the data.
  3. You can do it on the 2nd step's call and declare it as a list.

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:

  1. 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)
    
  2. 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:

  1. 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.


Solution 2:

My use-case. I used django.contrib.gis (django.contrib.gis.db.models.PolygonField) and needed to replace default map with Google maps + change default map coordinates, zoom, etc.

TL;DR

  • I created a new app called gis_addons with custom template and widget to use.
  • I instructed my model admin (using formfield_overrides) to use my own map widget.

Make sure to add the gis_addons to INSTALLED_APPS.

File: gis_addons/templates/gis_addons/openlayers_googlemaps.html

{% extends "gis/openlayers.html" %}

{% load i18n l10n %}

{% block base_layer %}
var base_layer = new ol.layer.Tile({
    source: new ol.source.XYZ({
        attributions: [new ol.Attribution({ html: '<a href=""></a>' })],
        maxZoom: 25,
        url: "http://mt0.google.com/vt/lyrs=r&hl=en&x={x}&y={y}&z={z}&s=Ga"
    })
});
{% endblock %}

{% block options %}var options = {
  base_layer: base_layer,
  geom_name: '{{ geom_type }}',
  id: '{{ id }}',
  map_id: '{{ id }}_map',
  map_options: map_options,
  map_srid: {{ map_srid|unlocalize }},
  name: '{{ name }}',
  default_lat: 53.2193835,
  default_lon: 6.5665018,
  default_zoom: 15
};
{% endblock %}

File: gis_addons/widgets.py

from django.contrib.gis.forms.widgets import OpenLayersWidget

class GoogleMapsOpenLayersWidget(OpenLayersWidget):
    """Google Maps OpenLayer widget."""

    template_name = 'gis_addons/openlayers_googlemaps.html'

File: my_app/models.py

from django.db import models
from django.contrib.gis.db import models as gis_models
from django.utils.translation import ugettext_lazy as _

class MyModel(models.Model):

    # ...

    coordinates = gis_models.PolygonField(
        verbose_name=_("Geo coordinates"),
    )

    def __str__(self):
        return self.name

File: my_app/admin.py

from django.contrib import admin
from django.contrib.gis.db.models import PolygonField
from gis_addons.widgets import GoogleMapsOpenLayersWidget
from my_app.models import MyModel

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):

    # ...

    formfield_overrides = {
        PolygonField: {"widget": GoogleMapsOpenLayersWidget}
    }

Post a Comment for "How To Integrate Geodjango With Google Maps API 3?"