web/views/igeocodable.py
changeset 8830 7fd6c52ef878
parent 8190 2a3c1b787688
equal deleted inserted replaced
8829:bb14dc9848ec 8830:7fd6c52ef878
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """Specific views for entities implementing IGeocodable"""
    18 """Specific views for entities implementing IGeocodable"""
    19 
    19 
    20 __docformat__ = "restructuredtext en"
    20 try:
       
    21     from cubes.geocoding.views import (IGeocodableAdapter,
       
    22                                        GeocodingJsonView,
       
    23                                        GoogleMapBubbleView,
       
    24                                        GoogleMapsView,
       
    25                                        GoogeMapsLegend)
    21 
    26 
    22 from cubicweb.interfaces import IGeocodable
    27     from logilab.common.deprecation import class_moved
    23 from cubicweb.view import EntityView, EntityAdapter, implements_adapter_compat
       
    24 from cubicweb.predicates import implements, adaptable
       
    25 from cubicweb.utils import json_dumps
       
    26 
    28 
    27 class IGeocodableAdapter(EntityAdapter):
    29     msg = '[3.17] cubicweb.web.views.igeocodable moved to cubes.geocoding.views'
    28     """interface required by geocoding views such as gmap-view"""
    30     IGeocodableAdapter = class_moved(IGeocodableAdapter, message=msg)
    29     __needs_bw_compat__ = True
    31     GeocodingJsonView = class_moved(GeocodingJsonView, message=msg)
    30     __regid__ = 'IGeocodable'
    32     GoogleMapBubbleView = class_moved(GoogleMapBubbleView, message=msg)
    31     __select__ = implements(IGeocodable, warn=False) # XXX for bw compat, should be abstract
    33     GoogleMapsView = class_moved(GoogleMapsView, message=msg)
    32 
    34     GoogeMapsLegend = class_moved(GoogeMapsLegend, message=msg)
    33     @property
    35 except ImportError:
    34     @implements_adapter_compat('IGeocodable')
    36     from cubicweb.web import LOGGER
    35     def latitude(self):
    37     LOGGER.warning('[3.17] igeocoding extracted to cube geocoding that was not found. try installing it.')
    36         """returns the latitude of the entity in degree (-90 < float < +90)"""
       
    37         raise NotImplementedError
       
    38 
       
    39     @property
       
    40     @implements_adapter_compat('IGeocodable')
       
    41     def longitude(self):
       
    42         """returns the longitude of the entity in degree (-180 < float < +180)"""
       
    43         raise NotImplementedError
       
    44 
       
    45     @implements_adapter_compat('IGeocodable')
       
    46     def marker_icon(self):
       
    47         """returns the icon that should be used as the marker.
       
    48 
       
    49         an icon is defined by a 4-uple:
       
    50 
       
    51           (icon._url, icon.size,  icon.iconAnchor, icon.shadow)
       
    52         """
       
    53         return (self._cw.uiprops['GMARKER_ICON'], (20, 34), (4, 34), None)
       
    54 
       
    55 
       
    56 class GeocodingJsonView(EntityView):
       
    57     __regid__ = 'geocoding-json'
       
    58     __select__ = adaptable('IGeocodable')
       
    59 
       
    60     binary = True
       
    61     templatable = False
       
    62     content_type = 'application/json'
       
    63 
       
    64     def call(self):
       
    65         zoomlevel = self._cw.form.pop('zoomlevel', None)
       
    66         extraparams = self._cw.form.copy()
       
    67         extraparams.pop('vid', None)
       
    68         extraparams.pop('rql', None)
       
    69         markers = []
       
    70         for entity in self.cw_rset.entities():
       
    71             igeocodable = entity.cw_adapt_to('IGeocodable')
       
    72             # remove entities that don't define latitude and longitude
       
    73             if not (igeocodable.latitude and igeocodable.longitude):
       
    74                 continue
       
    75             markers.append(self.build_marker_data(entity, igeocodable,
       
    76                                                   extraparams))
       
    77         if not markers:
       
    78             return
       
    79         geodata = {
       
    80             'markers': markers,
       
    81             }
       
    82         if zoomlevel:
       
    83             geodata['zoomlevel'] = int(zoomlevel)
       
    84         self.w(json_dumps(geodata))
       
    85 
       
    86     def build_marker_data(self, entity, igeocodable, extraparams):
       
    87         return {'latitude': igeocodable.latitude,
       
    88                 'longitude': igeocodable.longitude,
       
    89                 'icon': igeocodable.marker_icon(),
       
    90                 'title': entity.dc_long_title(),
       
    91                 'bubbleUrl': entity.absolute_url(
       
    92                     vid='gmap-bubble', __notemplate=1, **extraparams),
       
    93                 }
       
    94 
       
    95 
       
    96 class GoogleMapBubbleView(EntityView):
       
    97     __regid__ = 'gmap-bubble'
       
    98     __select__ = adaptable('IGeocodable')
       
    99 
       
   100     def cell_call(self, row, col):
       
   101         entity = self.cw_rset.get_entity(row, col)
       
   102         self.w(u'<div>%s</div>' % entity.view('oneline'))
       
   103         # FIXME: we should call something like address-view if available
       
   104 
       
   105 
       
   106 class GoogleMapsView(EntityView):
       
   107     __regid__ = 'gmap-view'
       
   108     __select__ = adaptable('IGeocodable')
       
   109 
       
   110     paginable = False
       
   111 
       
   112     def call(self, gmap_key, width=400, height=400, uselabel=True, urlparams=None):
       
   113         self._cw.demote_to_html()
       
   114         self._cw.add_js('http://maps.google.com/maps?sensor=false&file=api&v=2&key=%s'
       
   115                         % gmap_key, localfile=False)
       
   116         self._cw.add_js( ('cubicweb.widgets.js', 'cubicweb.gmap.js', 'gmap.utility.labeledmarker.js') )
       
   117         rql = self.cw_rset.printable_rql()
       
   118         if urlparams is None:
       
   119             loadurl = self._cw.build_url(rql=rql, vid='geocoding-json')
       
   120         else:
       
   121             loadurl = self._cw.build_url(rql=rql, vid='geocoding-json', **urlparams)
       
   122         self.w(u'<div style="width: %spx; height: %spx;" class="widget gmap" '
       
   123                u'cubicweb:wdgtype="GMapWidget" cubicweb:loadtype="auto" '
       
   124                u'cubicweb:loadurl="%s" cubicweb:uselabel="%s"> </div>'
       
   125                % (width, height, loadurl, uselabel))
       
   126 
       
   127 
       
   128 class GoogeMapsLegend(EntityView):
       
   129     __regid__ = 'gmap-legend'
       
   130 
       
   131     def call(self):
       
   132         self.w(u'<ol>')
       
   133         for rowidx in xrange(len(self.cw_rset)):
       
   134             self.w(u'<li>')
       
   135             self.wview('listitem', self.cw_rset, row=rowidx, col=0)
       
   136             self.w(u'</li>')
       
   137         self.w(u'</ol>')