PageRenderTime 82ms CodeModel.GetById 40ms app.highlight 8ms RepoModel.GetById 32ms app.codeStats 0ms

/django/contrib/gis/admin/widgets.py

https://code.google.com/p/mango-py/
Python | 107 lines | 95 code | 3 blank | 9 comment | 1 complexity | 9147a3b996f842ee2df64d13ba0d376f MD5 | raw file
  1from django.conf import settings
  2from django.contrib.gis.gdal import OGRException
  3from django.contrib.gis.geos import GEOSGeometry, GEOSException
  4from django.forms.widgets import Textarea
  5from django.template import loader, Context
  6from django.utils import translation
  7
  8# Creating a template context that contains Django settings
  9# values needed by admin map templates.
 10geo_context = Context({'ADMIN_MEDIA_PREFIX' : settings.ADMIN_MEDIA_PREFIX,
 11                       'LANGUAGE_BIDI' : translation.get_language_bidi(),
 12                       })
 13
 14class OpenLayersWidget(Textarea):
 15    """
 16    Renders an OpenLayers map using the WKT of the geometry.
 17    """
 18    def render(self, name, value, attrs=None):
 19        # Update the template parameters with any attributes passed in.
 20        if attrs: self.params.update(attrs)
 21
 22        # Defaulting the WKT value to a blank string -- this
 23        # will be tested in the JavaScript and the appropriate
 24        # interface will be constructed.
 25        self.params['wkt'] = ''
 26
 27        # If a string reaches here (via a validation error on another
 28        # field) then just reconstruct the Geometry.
 29        if isinstance(value, basestring):
 30            try:
 31                value = GEOSGeometry(value)
 32            except (GEOSException, ValueError):
 33                value = None
 34
 35        if value and value.geom_type.upper() != self.geom_type:
 36            value = None
 37
 38        # Constructing the dictionary of the map options.
 39        self.params['map_options'] = self.map_options()
 40
 41        # Constructing the JavaScript module name using the name of
 42        # the GeometryField (passed in via the `attrs` keyword).
 43        # Use the 'name' attr for the field name (rather than 'field')
 44        self.params['name'] = name
 45        # note: we must switch out dashes for underscores since js
 46        # functions are created using the module variable
 47        js_safe_name = self.params['name'].replace('-','_')
 48        self.params['module'] = 'geodjango_%s' % js_safe_name
 49
 50        if value:
 51            # Transforming the geometry to the projection used on the
 52            # OpenLayers map.
 53            srid = self.params['srid']
 54            if value.srid != srid:
 55                try:
 56                    ogr = value.ogr
 57                    ogr.transform(srid)
 58                    wkt = ogr.wkt
 59                except OGRException:
 60                    wkt = ''
 61            else:
 62                wkt = value.wkt
 63
 64            # Setting the parameter WKT with that of the transformed
 65            # geometry.
 66            self.params['wkt'] = wkt
 67
 68        return loader.render_to_string(self.template, self.params,
 69                                       context_instance=geo_context)
 70
 71    def map_options(self):
 72        "Builds the map options hash for the OpenLayers template."
 73
 74        # JavaScript construction utilities for the Bounds and Projection.
 75        def ol_bounds(extent):
 76            return 'new OpenLayers.Bounds(%s)' % str(extent)
 77        def ol_projection(srid):
 78            return 'new OpenLayers.Projection("EPSG:%s")' % srid
 79
 80        # An array of the parameter name, the name of their OpenLayers
 81        # counterpart, and the type of variable they are.
 82        map_types = [('srid', 'projection', 'srid'),
 83                     ('display_srid', 'displayProjection', 'srid'),
 84                     ('units', 'units', str),
 85                     ('max_resolution', 'maxResolution', float),
 86                     ('max_extent', 'maxExtent', 'bounds'),
 87                     ('num_zoom', 'numZoomLevels', int),
 88                     ('max_zoom', 'maxZoomLevels', int),
 89                     ('min_zoom', 'minZoomLevel', int),
 90                     ]
 91
 92        # Building the map options hash.
 93        map_options = {}
 94        for param_name, js_name, option_type in map_types:
 95            if self.params.get(param_name, False):
 96                if option_type == 'srid':
 97                    value = ol_projection(self.params[param_name])
 98                elif option_type == 'bounds':
 99                    value = ol_bounds(self.params[param_name])
100                elif option_type in (float, int):
101                    value = self.params[param_name]
102                elif option_type in (str,):
103                    value = '"%s"' % self.params[param_name]
104                else:
105                    raise TypeError
106                map_options[js_name] = value
107        return map_options