--- a/web/views/igeocodable.py Thu May 20 20:47:13 2010 +0200
+++ b/web/views/igeocodable.py Thu May 20 20:47:55 2010 +0200
@@ -21,27 +21,59 @@
__docformat__ = "restructuredtext en"
from cubicweb.interfaces import IGeocodable
-from cubicweb.view import EntityView
-from cubicweb.selectors import implements
+from cubicweb.view import EntityView, EntityAdapter, implements_adapter_compat
+from cubicweb.selectors import implements, adaptable
from cubicweb.web import json
+class IGeocodableAdapter(EntityAdapter):
+ """interface required by geocoding views such as gmap-view"""
+ __regid__ = 'IGeocodable'
+ __select__ = implements(IGeocodable) # XXX for bw compat, should be abstract
+
+ @property
+ @implements_adapter_compat('IGeocodable')
+ def latitude(self):
+ """returns the latitude of the entity"""
+ raise NotImplementedError
+
+ @property
+ @implements_adapter_compat('IGeocodable')
+ def longitude(self):
+ """returns the longitude of the entity"""
+ raise NotImplementedError
+
+ @implements_adapter_compat('IGeocodable')
+ def marker_icon(self):
+ """returns the icon that should be used as the marker.
+
+ an icon is defined by a 4-uple:
+
+ (icon._url, icon.size, icon.iconAnchor, icon.shadow)
+ """
+ return (self._cw.uiprops['GMARKER_ICON'], (20, 34), (4, 34), None)
+
+
class GeocodingJsonView(EntityView):
__regid__ = 'geocoding-json'
- __select__ = implements(IGeocodable)
+ __select__ = adaptable('IGeocodable')
binary = True
templatable = False
content_type = 'application/json'
def call(self):
- # remove entities that don't define latitude and longitude
- self.cw_rset = self.cw_rset.filtered_rset(lambda e: e.latitude and e.longitude)
zoomlevel = self._cw.form.pop('zoomlevel', 8)
extraparams = self._cw.form.copy()
extraparams.pop('vid', None)
extraparams.pop('rql', None)
- markers = [self.build_marker_data(rowidx, extraparams)
- for rowidx in xrange(len(self.cw_rset))]
+ markers = []
+ for entity in self.cw_rset.entities():
+ igeocodable = entity.cw_adapt_to('IGeocodable')
+ # remove entities that don't define latitude and longitude
+ if not (igeocodable.latitude and igeocodable.longitude):
+ continue
+ markers.append(self.build_marker_data(entity, igeocodable,
+ extraparams))
center = {
'latitude': sum(marker['latitude'] for marker in markers) / len(markers),
'longitude': sum(marker['longitude'] for marker in markers) / len(markers),
@@ -53,24 +85,19 @@
}
self.w(json.dumps(geodata))
- def build_marker_data(self, row, extraparams):
- entity = self.cw_rset.get_entity(row, 0)
- icon = None
- if hasattr(entity, 'marker_icon'):
- icon = entity.marker_icon()
- else:
- icon = (self._cw.uiprops['GMARKER_ICON'], (20, 34), (4, 34), None)
- return {'latitude': entity.latitude, 'longitude': entity.longitude,
+ def build_marker_data(self, entity, igeocodable, extraparams):
+ return {'latitude': igeocodable.latitude,
+ 'longitude': igeocodable.longitude,
+ 'icon': igeocodable.marker_icon(),
'title': entity.dc_long_title(),
- #icon defines : (icon._url, icon.size, icon.iconAncho', icon.shadow)
- 'icon': icon,
- 'bubbleUrl': entity.absolute_url(vid='gmap-bubble', __notemplate=1, **extraparams),
+ 'bubbleUrl': entity.absolute_url(
+ vid='gmap-bubble', __notemplate=1, **extraparams),
}
class GoogleMapBubbleView(EntityView):
__regid__ = 'gmap-bubble'
- __select__ = implements(IGeocodable)
+ __select__ = adaptable('IGeocodable')
def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
@@ -80,16 +107,14 @@
class GoogleMapsView(EntityView):
__regid__ = 'gmap-view'
- __select__ = implements(IGeocodable)
+ __select__ = adaptable('IGeocodable')
paginable = False
def call(self, gmap_key, width=400, height=400, uselabel=True, urlparams=None):
self._cw.demote_to_html()
- # remove entities that don't define latitude and longitude
- self.cw_rset = self.cw_rset.filtered_rset(lambda e: e.latitude and e.longitude)
- self._cw.add_js('http://maps.google.com/maps?sensor=false&file=api&v=2&key=%s' % gmap_key,
- localfile=False)
+ self._cw.add_js('http://maps.google.com/maps?sensor=false&file=api&v=2&key=%s'
+ % gmap_key, localfile=False)
self._cw.add_js( ('cubicweb.widgets.js', 'cubicweb.gmap.js', 'gmap.utility.labeledmarker.js') )
rql = self.cw_rset.printable_rql()
if urlparams is None:
@@ -98,7 +123,8 @@
loadurl = self._cw.build_url(rql=rql, vid='geocoding-json', **urlparams)
self.w(u'<div style="width: %spx; height: %spx;" class="widget gmap" '
u'cubicweb:wdgtype="GMapWidget" cubicweb:loadtype="auto" '
- u'cubicweb:loadurl="%s" cubicweb:uselabel="%s"> </div>' % (width, height, loadurl, uselabel))
+ u'cubicweb:loadurl="%s" cubicweb:uselabel="%s"> </div>'
+ % (width, height, loadurl, uselabel))
class GoogeMapsLegend(EntityView):