«« :: 2011 May :: »»


5 comments 2011 may 5 (thu) 9:06  ::  Basic Google Maps with Django

I'm in the process of upgrading a site from Django 1.0 to 1.3 and ran into an unexpected problem. There are a number of pages that use django.contrib.gis to display Google Maps, and these all inexplicably stopped working. These maps don't use any of Django's serious GIS features, they're just maps with a bunch of points on them.

After banging my head against my desk for awhile I figured out the problem and remembered how frustrating it was to get it set up in the first place--there don't seem to be any good tutorials on how to just display a simple map. Hopefully this will fill that void.

So here's a basic Django view in which we place a series of markers with links:

from django.conf import settings
from django.shortcuts import render_to_response
from django.contrib.gis.maps.google.gmap import GoogleMap
from django.contrib.gis.maps.google.overlays import GMarker, GEvent

def google_map(request):
    points = [
        {'lat':'35.42',     'lng': '139.42', 'href':'http://en.wikipedia.org/wiki/Tokyo'},
        {'lat':'51.30',     'lng':   '0.73', 'href':'http://en.wikipedia.org/wiki/London'},
        {'lat':'40.43',     'lng': '-74.0',  'href':'http://en.wikipedia.org/wiki/New_York_City'},
        {'lat':'34.03',     'lng':'-118.15', 'href':'http://en.wikipedia.org/wiki/Los_Angeles'},
        {'lat':'36.774402', 'lng':'-119.755405', 'href':'http://en.wikipedia.org/wiki/Fresno'},]
    markers = []
    for point in points:
        marker = GMarker('POINT(%s %s)' % (point['lng'], point['lat']))
        event = GEvent('click', 'function() { location.href = "%s"}' % point['href'])
        marker.add_event(event)
        markers.append(marker)
    google = GoogleMap(center=(0,0), zoom=1, markers=markers,
                       key=settings.GOOGLE_MAPS_API_PASSWORD)
    return render_to_response('google_map.html',
                              {'google': google,})

Notes:

  • Each point has latitude, longitude, and a URL. For each of these points we create a GMarker, which is the red push-pin-looking thing placed on your map.
  • To each GMarker we add a GEvent, which is just a wrapper around some Javascript. In this case we're launching a URL when the user clicks on the marker.
  • Each GMarker is added to a list.
  • Next we create a GoogleMap object, which has a center point, a zoom level, our list of GMarkers, and your Google Maps API key, which you can get from http://code.google.com/apis/maps/signup.html. No, you can't use mine. :P When you create this object it contacts Google to verify your key, and makes a bunch of functions available to your template.
  • As an aside, note that my API key is named GOOGLE_MAPS_API_PASSWORD. Django settings are displayed in debug screens, except for setting names containing "password", which are obscured. It's not good practice to use DEBUG = True in your production environment so you shouldn't see this anyway, but why take chances?

Here's your google_maps.html template.:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
{{ google.xhtml }}
<head>
  {{ google.style }}
  {{ google.scripts }}
</head>
<body onload="{{ google.js_module }}.map_load()" onunload="GUnload()">
  <div id="{{ google.dom_id }}" style="width:600px; height:400px;"></div>
</body>
</html>

Notes:

  • {{ google.xhtml }} is apparently a bit of HTML that helps these maps work with IE. It needs to go at the top of your page.

  • {{ google.dom_id }} is the CSS id of the <div> that will contain your map. You can control the size of your map using the style= attribute or some CSS.

  • {{ google.scripts }} is the Javascript that will actually write the map onto your page. It consists of a link to a Javascript lib hosted by Google, and a script that writes your map and points and whatever else.

  • {{ google.style }} is the CSS that will make it pretty.

  • {{ google.js_module }} is the name of a Javascript variable, into which is inserted the function actually writes the map and your points into the <div> specified by {{ google.dom_id }}. You have to trigger this script on your page; I do it in the <body> tag. Make sure you use {{ google.js_module }} to call the script! Django changed the name of this script between 1.0 and 1.1; I had hard-coded the name, which was why my maps didn't display. The script looks like this:

    <script type="text/javascript">
      //<![CDATA[
    
      var geodjango = {};
    
      geodjango.map_load = function(){
        if (GBrowserIsCompatible()) {
          geodjango.map = new GMap2(document.getElementById("map"));
          geodjango.map.setCenter(new GLatLng(0, 0), 1);
          geodjango.map.setUIToDefault();
          ...
        }else {
          alert("Sorry, the Google Maps API is not compatible with this browser.");
        }
      }
    
      //]]>
    </script>
    

And there you have it. You should see a nice Google Map with some points plotted on it. Thanks for visiting, and enjoy your map-making!

  |   django gis maps
 

5 comments on this post

Koen at 2:17 p.m. on Mon 13 Jun 2011

Thx for the writeup indeed not much tutorials around this topic.

The only thing I cannot get working is the markers. They are not drawn onto the map. I just see the world map. could it be you mis a line somewhere which is needed to draw the markers on the map?

Koen at 2:56 p.m. on Mon 13 Jun 2011

Ok no problem I get it. Via the {{ google.js_module }} you inject the view code into that jscript. I had a typo also so now it works. Thanks

Maybe usefull to add that you should create a gis/google/js/google-map.js file in the templates directory? this was how I could get it running

liq at 12:54 a.m. on Wed 22 Jun 2011

Koen:
Just add 'django.contrib.gis' to INSTALLED_APPS in your settings.py.

Ibrahim at 3:52 p.m. on Sat 15 Oct 2011

I simply copied your code into my django application and got this error

Could not find the GEOS library (tried "libgeos_c-1"). Try setting GEOS_LIBRARY_PATH in your settings

and i m not getting any solution for it.

kindly reply asap.

gjost at 8:31 a.m. on Sun 16 Oct 2011

@Ibrahim It sounds like you don't have some of the prerequisites installed. GeoDjango depends on a number of geospatial libraries. Check the GeoDjango documentation (https://docs.djangoproject.com/en/dev/ref/contrib/gis/).

On Ubuntu, I had to install more libraries (libc6-dev g++ gcc) just to be able to compile the geospatial libs. I also had to manually link the libgeos libraries into /usr/lib after compilation before it worked for me, but that looks like a slightly different problem from the one you're encountering here.

NOTE: I did my install awhile ago, and the geospatial libs may be included in recent Linux distros.

Comments for this post have been disabled