Skip to main content

Geographic annotation for Plone

Project description


collective.geo.geographer provides geo annotation for Plone.

This package is based on Sean Gillies’s idea (zgeo.geographer) and integrates its functionalities in collective.geo project.

Found a bug? Please, use the issue tracker.


This addon can be installed has any other addons, please follow official documentation.

How it work

Any object that implements zope.annotation.interfaces.IAttributeAnnotatable and IGeoreferenceable can be adapted and geo-referenced.

The former marker is standard for Zope content objects, and the latter can be easily configured via ZCML.

Let’s test with an example placemark, which provides both of the marker interfaces mentioned above.

>>> from zope.interface import implements
>>> from zope.annotation.interfaces import IAttributeAnnotatable
>>> from collective.geo.geographer.interfaces import IGeoreferenceable
>>> class Placemark(object):
...     implements(IGeoreferenceable, IAttributeAnnotatable)
>>> placemark = Placemark()

Adapt it to collective.geo.geographer.interfaces.IGeoreferenced

>>> from collective.geo.geographer.interfaces import IGeoreferenced
>>> geo = IGeoreferenced(placemark)

Its properties should all be None

>>> geo.type is None
>>> geo.coordinates is None
>>> is None

Check whether geo referenceable object has coordinates or not

>>> geo.hasCoordinates()

Now set the location geometry to type Point and coordinates 105.08 degrees West, 40.59 degrees North using setGeoInterface

>>> geo.setGeoInterface('Point', (-105.08, 40.59))

A georeferenced object has type and coordinates attributes which should give us back what we put in.

>>> geo.type
>>> tuple(['%.2f' % x for x in geo.coordinates])
('-105.08', '40.59')
>>> is None

now hasCoordinates method returns True

>>> geo.hasCoordinates()

An event should have been sent

>>> from zope.component.eventtesting import getEvents
>>> from collective.geo.geographer.event import IObjectGeoreferencedEvent
>>> events = getEvents(IObjectGeoreferencedEvent)
>>> events[-1].object is placemark

To remove the coordinate from a georeferenced object, we can use removeGeoInterface method:

>>> geo.removeGeoInterface()
>>> geo.type is None
>>> geo.coordinates is None
>>> is None

Plone integration

Add geo-referenced content

>>> from import setRoles
>>> from import TEST_USER_ID
>>> portal = layer['portal']
>>> setRoles(portal, TEST_USER_ID, ['Manager'])
>>> oid = portal.invokeFactory('Document', 'doc')
>>> doc = portal[oid]

If content type doesn’t implement collective.geo.geographer.interfaces.IGeoreferenceable interfaces we need to provide it

>>> from zope.interface import alsoProvides
>>> alsoProvides(doc, IGeoreferenceable)

now we can set the coordinates

>>> from collective.geo.geographer.interfaces import IWriteGeoreferenced
>>> geo = IWriteGeoreferenced(doc)
>>> geo.setGeoInterface('Point', (-100, 40))

and reindex the document.

>>> doc.reindexObject(idxs=['zgeo_geometry'])

We can create a subscriber for collective.geo.geographer.event.IObjectGeoreferencedEvent to do that automatically.

Check the catalog results

>>> from Products.CMFCore.utils import getToolByName
>>> catalog = getToolByName(portal, 'portal_catalog')
>>> brain = [b for b in catalog({'getId': 'doc'})][0]
>>> brain.zgeo_geometry['type']
>>> brain.zgeo_geometry['coordinates']
(-100, 40)

A simple view - geoview - notify us if a context is geo referenceable

>>> view = doc.restrictedTraverse('@@geoview')
>>> view.isGeoreferenceable()

and return its coordinates

>>> view.getCoordinates()
('Point', (-100, 40))

When we remove the coordinates, corresponding index will return None

>>> geo.removeGeoInterface()
>>> doc.reindexObject(idxs=['zgeo_geometry'])
>>> brain = [b for b in catalog({'getId': 'doc'})][0]
>>> brain.zgeo_geometry


  • Sean Gillies
  • Giorgio Borelli
  • Christian Ledermann
  • Mirco Angelini


2.0 (2013-10-29)

  • Changed package layout [gborelli]
  • remove style key from zgeo_geometry metadata [gborelli]
  • move IGeoCoder utility to c.geo.mapwidget [gborelli]
  • remove IGeoCoder adapter [gborelli]

1.7 (2013-04-11)

  • Fixed permission on GeoreferencingAnnotator. See #3 [gborelli]
  • Moved showCoordinatesTab to c.geo.contentlocations [gborelli]
  • Added hasCoordinates method to GeoreferencingAnnotator to check whether an object has been georeferenced or not [gborelli]
  • Added a method in order to hidden Coordinates tab for dexterity content types [valentinaB]
  • Changed Version of Geopy (moved from 0.94.2 to 0.95) to support Google api v3 in geocoder [cippino]

1.6 (2013-01-28)

  • Fixed [gborelli]

1.5 (2013-01-28)

  • Added Sphinx documentation [gborelli]
  • Added travis-ci configurations [gborelli]
  • Moved reindexDocSubscriber to collective.geo.contentlocations [gborelli]
  • Refactored test and removed dependency from old Topic content type [gborelli]

1.4 (2012-02-11)

  • changed tests using [gborelli]
  • Added IGeoCoder utility [gborelli]
  • Marked as deprecated IGeoCoder adapter [gborelli]
  • Added removeGeoInterface to remove coordinates from an object [mircoangelini]

0.1.3 (2011-09-05)

  • plone 4.1 fixes [gborelli]
  • include Products.CMFCore to make plone 4.1 happy [nan010]
  • changed Browser import from Testing.testbrowser [gborelli]
  • added z3c.autoinclude entry point [gborelli]

0.1.2 (2010-12-28)

  • Moved IGeoView from c.geo.contentlocations

0.1.1 (2010-11-13)

  • moved geocoderview to portal root

0.1 (2010-10-31)

  • removed zgeo.geographer dependency
  • zgeo.plone.geographer code refactoring
  • moved from zgeo.plone.geographer

Project details

Release history Release notifications

History Node


This version
History Node


History Node


History Node


History Node


History Node


History Node


History Node


History Node


History Node


History Node


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date (39.2 kB) Copy SHA256 hash SHA256 Source None Oct 29, 2013

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging CloudAMQP CloudAMQP RabbitMQ AWS AWS Cloud computing Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page