Google Maps and CubicWeb

http://maps.google.com/intl/fr_ALL/images/maps_logo_small_blue.png

There is this so-called 'gmap-view' in CubicWeb, the question is: how to use it ?

Well, first, no surprise, you have to generate an API key to be able to use google maps on your server (make sure your usage conforms the terms as defined by Google).

Now, let's say you have defined the following schema:

class Company(EntityType):
name = String(required=True, maxsize=64)
# ... some other attributes ...
latitude = Float(required=True)
longitude = Float(required=True)class Employee(EntityType):
# ... some attributes ...
works_for = SubjectRelation('Company', cardinality='1*')

And you'd like to be able to display companies on a map; you've also got these nice icons that you'd wish to use as markers on the map. First thing, define those three icons as external resources. You can do that by editing your CUBE/data/external_resources file:

SMALL_MARKER_ICON=DATADIR/small_company.png
MEDIUM_MARKER_ICON=DATADIR/MEDIUM_company.png
BIG_MARKER_ICON=DATADIR/big_company.png

We're nearly done, now. We just have to make our entity class implement the cubicweb.interfaces.IGeocodable interface. Here's an example:

from cubicweb.entities import AnyEntity
from cubicweb.interfaces import IGeocodableclass Company(AnyEntity):
id = 'Company' # this must match the type as defined in your schema
implements = AnyEntity.implements + (IGeocodable,)def size(self):
return self.req.execute('Any COUNT(E) WHERE E works_for C, C eid %(c)s',
{'c': self.eid})# this is a method of IGeocodable
def marker_icon(self):
size = self.size()
if size < 20:
return self.req_external_resource('SMALL_MARKER_ICON')
elif size < 500:
return self.req_external_resource('MEDIUM_MARKER_ICON')
else:
return self.req_external_resource('BIG_MARKER_ICON')

That's it, you can now call the gmap-view on a resultset containing companies:

rset = self.req.execute('Any C WHERE C is Company')
self.wview(rset, 'gmap-view', gmap_key=YOUR_API_KEY)

Further configuration is possible, especially to control the size of the map or the default zoom level.

To be fair, I must say that in a real-life cube, chances are you won't be able to specificy directly latitude and longitude and that you'll only have an address. This is slightly more complex to do since you'll need to query a geocoding service (the google one for instance) to transform your address into latitude/longitude. This will typically be done in a hook

Here is an screenshot of google maps on a production site, the museums in Normandy :