1
from django.contrib.gis.gdal import OGRException
2
from django.contrib.gis.geos import GEOSGeometry, GEOSException
3
from django.forms.widgets import Textarea
4
from django.template.loader import render_to_string
6
class OpenLayersWidget(Textarea):
8
Renders an OpenLayers map using the WKT of the geometry.
10
def render(self, name, value, attrs=None):
11
# Update the template parameters with any attributes passed in.
12
if attrs: self.params.update(attrs)
14
# Defaulting the WKT value to a blank string -- this
15
# will be tested in the JavaScript and the appropriate
16
# interfaace will be constructed.
17
self.params['wkt'] = ''
19
# If a string reaches here (via a validation error on another
20
# field) then just reconstruct the Geometry.
21
if isinstance(value, basestring):
23
value = GEOSGeometry(value)
24
except (GEOSException, ValueError):
27
if value and value.geom_type.upper() != self.geom_type:
30
# Constructing the dictionary of the map options.
31
self.params['map_options'] = self.map_options()
33
# Constructing the JavaScript module name using the ID of
34
# the GeometryField (passed in via the `attrs` keyword).
35
self.params['module'] = 'geodjango_%s' % self.params['field_name']
38
# Transforming the geometry to the projection used on the
40
srid = self.params['srid']
41
if value.srid != srid:
50
# Setting the parameter WKT with that of the transformed
52
self.params['wkt'] = wkt
54
return render_to_string(self.template, self.params)
56
def map_options(self):
57
"Builds the map options hash for the OpenLayers template."
59
# JavaScript construction utilities for the Bounds and Projection.
60
def ol_bounds(extent):
61
return 'new OpenLayers.Bounds(%s)' % str(extent)
62
def ol_projection(srid):
63
return 'new OpenLayers.Projection("EPSG:%s")' % srid
65
# An array of the parameter name, the name of their OpenLayers
66
# counterpart, and the type of variable they are.
67
map_types = [('srid', 'projection', 'srid'),
68
('display_srid', 'displayProjection', 'srid'),
69
('units', 'units', str),
70
('max_resolution', 'maxResolution', float),
71
('max_extent', 'maxExtent', 'bounds'),
72
('num_zoom', 'numZoomLevels', int),
73
('max_zoom', 'maxZoomLevels', int),
74
('min_zoom', 'minZoomLevel', int),
77
# Building the map options hash.
79
for param_name, js_name, option_type in map_types:
80
if self.params.get(param_name, False):
81
if option_type == 'srid':
82
value = ol_projection(self.params[param_name])
83
elif option_type == 'bounds':
84
value = ol_bounds(self.params[param_name])
85
elif option_type in (float, int):
86
value = self.params[param_name]
87
elif option_type in (str,):
88
value = '"%s"' % self.params[param_name]
91
map_options[js_name] = value