diff -r a64f48dd5fe4 -r 9ab2b4c74baf web/views/igeocodable.py --- 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'
' % (width, height, loadurl, uselabel)) + u'cubicweb:loadurl="%s" cubicweb:uselabel="%s"> ' + % (width, height, loadurl, uselabel)) class GoogeMapsLegend(EntityView):