diff options
Diffstat (limited to 'webapp/django/contrib/gis/admin/widgets.py')
-rw-r--r-- | webapp/django/contrib/gis/admin/widgets.py | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/webapp/django/contrib/gis/admin/widgets.py b/webapp/django/contrib/gis/admin/widgets.py new file mode 100644 index 0000000000..27abc8f59b --- /dev/null +++ b/webapp/django/contrib/gis/admin/widgets.py @@ -0,0 +1,92 @@ +from django.contrib.gis.gdal import OGRException +from django.contrib.gis.geos import GEOSGeometry, GEOSException +from django.forms.widgets import Textarea +from django.template.loader import render_to_string + +class OpenLayersWidget(Textarea): + """ + Renders an OpenLayers map using the WKT of the geometry. + """ + def render(self, name, value, attrs=None): + # Update the template parameters with any attributes passed in. + if attrs: self.params.update(attrs) + + # Defaulting the WKT value to a blank string -- this + # will be tested in the JavaScript and the appropriate + # interfaace will be constructed. + self.params['wkt'] = '' + + # If a string reaches here (via a validation error on another + # field) then just reconstruct the Geometry. + if isinstance(value, basestring): + try: + value = GEOSGeometry(value) + except (GEOSException, ValueError): + value = None + + if value and value.geom_type.upper() != self.geom_type: + value = None + + # Constructing the dictionary of the map options. + self.params['map_options'] = self.map_options() + + # Constructing the JavaScript module name using the ID of + # the GeometryField (passed in via the `attrs` keyword). + self.params['module'] = 'geodjango_%s' % self.params['field_name'] + + if value: + # Transforming the geometry to the projection used on the + # OpenLayers map. + srid = self.params['srid'] + if value.srid != srid: + try: + value.transform(srid) + wkt = value.wkt + except OGRException: + wkt = '' + else: + wkt = value.wkt + + # Setting the parameter WKT with that of the transformed + # geometry. + self.params['wkt'] = wkt + + return render_to_string(self.template, self.params) + + def map_options(self): + "Builds the map options hash for the OpenLayers template." + + # JavaScript construction utilities for the Bounds and Projection. + def ol_bounds(extent): + return 'new OpenLayers.Bounds(%s)' % str(extent) + def ol_projection(srid): + return 'new OpenLayers.Projection("EPSG:%s")' % srid + + # An array of the parameter name, the name of their OpenLayers + # counterpart, and the type of variable they are. + map_types = [('srid', 'projection', 'srid'), + ('display_srid', 'displayProjection', 'srid'), + ('units', 'units', str), + ('max_resolution', 'maxResolution', float), + ('max_extent', 'maxExtent', 'bounds'), + ('num_zoom', 'numZoomLevels', int), + ('max_zoom', 'maxZoomLevels', int), + ('min_zoom', 'minZoomLevel', int), + ] + + # Building the map options hash. + map_options = {} + for param_name, js_name, option_type in map_types: + if self.params.get(param_name, False): + if option_type == 'srid': + value = ol_projection(self.params[param_name]) + elif option_type == 'bounds': + value = ol_bounds(self.params[param_name]) + elif option_type in (float, int): + value = self.params[param_name] + elif option_type in (str,): + value = '"%s"' % self.params[param_name] + else: + raise TypeError + map_options[js_name] = value + return map_options |