diff options
Diffstat (limited to 'lib/python2.7/site-packages/django/contrib/gis/forms/widgets.py')
-rw-r--r-- | lib/python2.7/site-packages/django/contrib/gis/forms/widgets.py | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/django/contrib/gis/forms/widgets.py b/lib/python2.7/site-packages/django/contrib/gis/forms/widgets.py new file mode 100644 index 0000000..909684e --- /dev/null +++ b/lib/python2.7/site-packages/django/contrib/gis/forms/widgets.py @@ -0,0 +1,120 @@ +from __future__ import unicode_literals + +import logging + +from django.conf import settings +from django.contrib.gis import gdal +from django.contrib.gis.geos import GEOSGeometry, GEOSException +from django.forms.widgets import Widget +from django.template import loader +from django.utils import six +from django.utils import translation + +logger = logging.getLogger('django.contrib.gis') + + +class BaseGeometryWidget(Widget): + """ + The base class for rich geometry widgets. + Renders a map using the WKT of the geometry. + """ + geom_type = 'GEOMETRY' + map_srid = 4326 + map_width = 600 + map_height = 400 + display_raw = False + + supports_3d = False + template_name = '' # set on subclasses + + def __init__(self, attrs=None): + self.attrs = {} + for key in ('geom_type', 'map_srid', 'map_width', 'map_height', 'display_raw'): + self.attrs[key] = getattr(self, key) + if attrs: + self.attrs.update(attrs) + + def serialize(self, value): + return value.wkt if value else '' + + def deserialize(self, value): + try: + return GEOSGeometry(value, self.map_srid) + except (GEOSException, ValueError) as err: + logger.error( + "Error creating geometry from value '%s' (%s)" % ( + value, err) + ) + return None + + def render(self, name, value, attrs=None): + # If a string reaches here (via a validation error on another + # field) then just reconstruct the Geometry. + if isinstance(value, six.string_types): + value = self.deserialize(value) + + if value: + # Check that srid of value and map match + if value.srid != self.map_srid: + try: + ogr = value.ogr + ogr.transform(self.map_srid) + value = ogr + except gdal.OGRException as err: + logger.error( + "Error transforming geometry from srid '%s' to srid '%s' (%s)" % ( + value.srid, self.map_srid, err) + ) + + context = self.build_attrs(attrs, + name=name, + module='geodjango_%s' % name.replace('-','_'), # JS-safe + serialized=self.serialize(value), + geom_type=gdal.OGRGeomType(self.attrs['geom_type']), + STATIC_URL=settings.STATIC_URL, + LANGUAGE_BIDI=translation.get_language_bidi(), + ) + return loader.render_to_string(self.template_name, context) + + +class OpenLayersWidget(BaseGeometryWidget): + template_name = 'gis/openlayers.html' + class Media: + js = ( + 'http://openlayers.org/api/2.11/OpenLayers.js', + 'gis/js/OLMapWidget.js', + ) + + +class OSMWidget(BaseGeometryWidget): + """ + An OpenLayers/OpenStreetMap-based widget. + """ + template_name = 'gis/openlayers-osm.html' + default_lon = 5 + default_lat = 47 + + class Media: + js = ( + 'http://openlayers.org/api/2.11/OpenLayers.js', + 'http://www.openstreetmap.org/openlayers/OpenStreetMap.js', + 'gis/js/OLMapWidget.js', + ) + + @property + def map_srid(self): + # Use the official spherical mercator projection SRID on versions + # of GDAL that support it; otherwise, fallback to 900913. + if gdal.HAS_GDAL and gdal.GDAL_VERSION >= (1, 7): + return 3857 + else: + return 900913 + + def render(self, name, value, attrs=None): + default_attrs = { + 'default_lon': self.default_lon, + 'default_lat': self.default_lat, + } + if attrs: + default_attrs.update(attrs) + return super(OSMWidget, self).render(name, value, default_attrs) |