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
    
    defmy_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"%}

{%loadi18nl10n%}

{%blockbase_layer%}
varbase_layer=newol.layer.Tile({source:newol.source.XYZ({attributions: [newol.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%}

{%blockoptions%}varoptions= {
  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

classGoogleMapsOpenLayersWidget(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 _

classMyModel(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)classMyModelAdmin(admin.ModelAdmin):

    # ...

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

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