summaryrefslogtreecommitdiffstats
path: root/webapp/django/contrib/gis/admin/widgets.py
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/django/contrib/gis/admin/widgets.py')
-rw-r--r--webapp/django/contrib/gis/admin/widgets.py92
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