diff --git a/django/contrib/gis/admin/widgets.py b/django/contrib/gis/admin/widgets.py
index 6dbbc60..9b02484 100644
a
|
b
|
from django.templatetags.static import static
|
4 | 4 | from django.utils import translation |
5 | 5 | |
6 | 6 | from django.contrib.gis.gdal import OGRException |
7 | | from django.contrib.gis.geos import GEOSGeometry, GEOSException |
| 7 | from django.contrib.gis.geos import GEOSGeometry, GEOSException, fromstr |
8 | 8 | |
9 | 9 | # Creating a template context that contains Django settings |
10 | 10 | # values needed by admin map templates. |
… |
… |
class OpenLayersWidget(Textarea):
|
105 | 105 | raise TypeError |
106 | 106 | map_options[js_name] = value |
107 | 107 | return map_options |
| 108 | |
| 109 | def _has_changed(self, initial, data): |
| 110 | """ Compare geographic value of data with its initial value. """ |
| 111 | |
| 112 | # Ensure we are dealing with a geographic object |
| 113 | if isinstance(initial, basestring): |
| 114 | try: |
| 115 | initial = GEOSGeometry(initial) |
| 116 | except (GEOSException, ValueError): |
| 117 | initial = None |
| 118 | |
| 119 | # Only do a geographic comparison if both values are available |
| 120 | if initial and data: |
| 121 | data = fromstr(data) |
| 122 | data.transform(initial.srid) |
| 123 | # If the initial value was not added by the browser, the geometry |
| 124 | # provided may be slightly different, the first time it is saved. |
| 125 | # The comparison is done with a very low tolerance. |
| 126 | return not initial.equals_exact(data, tolerance=0.000001) |
| 127 | |
| 128 | else: |
| 129 | # Check for change of state of existence |
| 130 | return bool(initial) != bool(data) |
diff --git a/django/contrib/gis/tests/geoadmin/tests.py b/django/contrib/gis/tests/geoadmin/tests.py
index aa07c2c..040a494 100644
a
|
b
|
from __future__ import absolute_import
|
2 | 2 | |
3 | 3 | from django.test import TestCase |
4 | 4 | from django.contrib.gis import admin |
| 5 | from django.contrib.gis.geos import GEOSGeometry, Point |
5 | 6 | |
6 | 7 | from .models import City |
7 | 8 | |
… |
… |
class GeoAdminTest(TestCase):
|
14 | 15 | admin_js = geoadmin.media.render_js() |
15 | 16 | self.assertTrue(any([geoadmin.openlayers_url in js for js in admin_js])) |
16 | 17 | |
| 18 | def test02_has_changed(self): |
| 19 | """ Check that changes are accurately noticed by the widget. """ |
| 20 | geoadmin = admin.site._registry[City] |
| 21 | form = geoadmin.get_changelist_form(None)() |
| 22 | has_changed = form.fields['point'].widget._has_changed |
| 23 | |
| 24 | initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326) |
| 25 | data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)" |
| 26 | data_almost_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)" |
| 27 | data_changed = "SRID=3857;POINT(1493884.0527237 6894593.8111804)" |
| 28 | |
| 29 | self.assertTrue(has_changed(None, data_changed)) |
| 30 | self.assertTrue(has_changed(initial, "")) |
| 31 | self.assertFalse(has_changed(None, "")) |
| 32 | self.assertFalse(has_changed(initial, data_same)) |
| 33 | self.assertFalse(has_changed(initial, data_almost_same)) |
| 34 | self.assertTrue(has_changed(initial, data_changed)) |
| 35 | |