1
from __future__ import unicode_literals
5
from django.conf import settings
6
from django.contrib.gis import gdal
7
from django.contrib.gis.geos import GEOSGeometry, GEOSException
8
from django.forms.widgets import Widget
9
from django.template import loader
10
from django.utils import six
11
from django.utils import translation
13
logger = logging.getLogger('django.contrib.gis')
16
class BaseGeometryWidget(Widget):
18
The base class for rich geometry widgets.
19
Renders a map using the WKT of the geometry.
21
geom_type = 'GEOMETRY'
28
template_name = '' # set on subclasses
30
def __init__(self, attrs=None):
32
for key in ('geom_type', 'map_srid', 'map_width', 'map_height', 'display_raw'):
33
self.attrs[key] = getattr(self, key)
35
self.attrs.update(attrs)
37
def serialize(self, value):
38
return value.wkt if value else ''
40
def deserialize(self, value):
42
return GEOSGeometry(value, self.map_srid)
43
except (GEOSException, ValueError) as err:
45
"Error creating geometry from value '%s' (%s)" % (
50
def render(self, name, value, attrs=None):
51
# If a string reaches here (via a validation error on another
52
# field) then just reconstruct the Geometry.
53
if isinstance(value, six.string_types):
54
value = self.deserialize(value)
57
# Check that srid of value and map match
58
if value.srid != self.map_srid:
61
ogr.transform(self.map_srid)
63
except gdal.OGRException as err:
65
"Error transforming geometry from srid '%s' to srid '%s' (%s)" % (
66
value.srid, self.map_srid, err)
69
context = self.build_attrs(attrs,
71
module='geodjango_%s' % name.replace('-','_'), # JS-safe
72
serialized=self.serialize(value),
73
geom_type=gdal.OGRGeomType(self.attrs['geom_type']),
74
STATIC_URL=settings.STATIC_URL,
75
LANGUAGE_BIDI=translation.get_language_bidi(),
77
return loader.render_to_string(self.template_name, context)
80
class OpenLayersWidget(BaseGeometryWidget):
81
template_name = 'gis/openlayers.html'
84
'http://openlayers.org/api/2.11/OpenLayers.js',
85
'gis/js/OLMapWidget.js',
89
class OSMWidget(BaseGeometryWidget):
91
An OpenLayers/OpenStreetMap-based widget.
93
template_name = 'gis/openlayers-osm.html'
99
'http://openlayers.org/api/2.11/OpenLayers.js',
100
'http://www.openstreetmap.org/openlayers/OpenStreetMap.js',
101
'gis/js/OLMapWidget.js',
106
# Use the official spherical mercator projection SRID on versions
107
# of GDAL that support it; otherwise, fallback to 900913.
108
if gdal.HAS_GDAL and gdal.GDAL_VERSION >= (1, 7):
113
def render(self, name, value, attrs=None):
115
'default_lon': self.default_lon,
116
'default_lat': self.default_lat,
119
default_attrs.update(attrs)
120
return super(OSMWidget, self).render(name, value, default_attrs)