|
0
|
1 |
from django import forms |
|
|
2 |
from django.utils.translation import ugettext_lazy as _ |
|
|
3 |
|
|
|
4 |
# While this couples the geographic forms to the GEOS library, |
|
|
5 |
# it decouples from database (by not importing SpatialBackend). |
|
|
6 |
from django.contrib.gis.geos import GEOSGeometry |
|
|
7 |
|
|
|
8 |
class GeometryField(forms.Field): |
|
|
9 |
""" |
|
|
10 |
This is the basic form field for a Geometry. Any textual input that is |
|
|
11 |
accepted by GEOSGeometry is accepted by this form. By default, |
|
|
12 |
this includes WKT, HEXEWKB, WKB (in a buffer), and GeoJSON. |
|
|
13 |
""" |
|
|
14 |
widget = forms.Textarea |
|
|
15 |
|
|
|
16 |
default_error_messages = { |
|
|
17 |
'no_geom' : _(u'No geometry value provided.'), |
|
|
18 |
'invalid_geom' : _(u'Invalid geometry value.'), |
|
|
19 |
'invalid_geom_type' : _(u'Invalid geometry type.'), |
|
|
20 |
'transform_error' : _(u'An error occurred when transforming the geometry ' |
|
|
21 |
'to the SRID of the geometry form field.'), |
|
|
22 |
} |
|
|
23 |
|
|
|
24 |
def __init__(self, **kwargs): |
|
|
25 |
# Pop out attributes from the database field, or use sensible |
|
|
26 |
# defaults (e.g., allow None). |
|
|
27 |
self.srid = kwargs.pop('srid', None) |
|
|
28 |
self.geom_type = kwargs.pop('geom_type', 'GEOMETRY') |
|
|
29 |
self.null = kwargs.pop('null', True) |
|
|
30 |
super(GeometryField, self).__init__(**kwargs) |
|
|
31 |
|
|
|
32 |
def clean(self, value): |
|
|
33 |
""" |
|
|
34 |
Validates that the input value can be converted to a Geometry |
|
|
35 |
object (which is returned). A ValidationError is raised if |
|
|
36 |
the value cannot be instantiated as a Geometry. |
|
|
37 |
""" |
|
|
38 |
if not value: |
|
|
39 |
if self.null and not self.required: |
|
|
40 |
# The geometry column allows NULL and is not required. |
|
|
41 |
return None |
|
|
42 |
else: |
|
|
43 |
raise forms.ValidationError(self.error_messages['no_geom']) |
|
|
44 |
|
|
|
45 |
# Trying to create a Geometry object from the form value. |
|
|
46 |
try: |
|
|
47 |
geom = GEOSGeometry(value) |
|
|
48 |
except: |
|
|
49 |
raise forms.ValidationError(self.error_messages['invalid_geom']) |
|
|
50 |
|
|
|
51 |
# Ensuring that the geometry is of the correct type (indicated |
|
|
52 |
# using the OGC string label). |
|
|
53 |
if str(geom.geom_type).upper() != self.geom_type and not self.geom_type == 'GEOMETRY': |
|
|
54 |
raise forms.ValidationError(self.error_messages['invalid_geom_type']) |
|
|
55 |
|
|
|
56 |
# Transforming the geometry if the SRID was set. |
|
|
57 |
if self.srid: |
|
|
58 |
if not geom.srid: |
|
|
59 |
# Should match that of the field if not given. |
|
|
60 |
geom.srid = self.srid |
|
|
61 |
elif self.srid != -1 and self.srid != geom.srid: |
|
|
62 |
try: |
|
|
63 |
geom.transform(self.srid) |
|
|
64 |
except: |
|
|
65 |
raise forms.ValidationError(self.error_messages['transform_error']) |
|
|
66 |
|
|
|
67 |
return geom |