skip to navigation
skip to content

collective.geo.geographer 1.6

Geographic annotation for Plone

Latest Version: 2.1


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.

How it work

Any object that implements 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 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

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

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 implements 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 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 is None
File Type Py Version Uploaded on Size (md5) Source 2013-01-28 39KB