From 1fdbcadd223641f63d0548c39860d255cef325ed Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Tue, 15 Mar 2011 02:26:37 +0000 Subject: [PATCH] Fixed #15378 -- Now properly handle OGR layers that have features with invalid geometries. Thanks, kunitoki for bug report and initial patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@15813 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../gis/tests/data/invalid/emptypoints.dbf | Bin 0 -> 77 bytes .../gis/tests/data/invalid/emptypoints.shp | Bin 0 -> 112 bytes .../gis/tests/data/invalid/emptypoints.shx | Bin 0 -> 108 bytes django/contrib/gis/tests/layermap/models.py | 3 +++ django/contrib/gis/tests/layermap/tests.py | 14 ++++++++++++-- django/contrib/gis/utils/layermapping.py | 5 ++++- 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 django/contrib/gis/tests/data/invalid/emptypoints.dbf create mode 100644 django/contrib/gis/tests/data/invalid/emptypoints.shp create mode 100644 django/contrib/gis/tests/data/invalid/emptypoints.shx diff --git a/django/contrib/gis/tests/data/invalid/emptypoints.dbf b/django/contrib/gis/tests/data/invalid/emptypoints.dbf new file mode 100644 index 0000000000000000000000000000000000000000..aa2109047a4f7b5d4f7fdc372c065148aff5f8c7 GIT binary patch literal 77 ocmZRMXP07RU|?`$-~p0oAe@20&C>-Y=m%nO!+21dR{;SG0EU$V@&Et; literal 0 HcmV?d00001 diff --git a/django/contrib/gis/tests/data/invalid/emptypoints.shp b/django/contrib/gis/tests/data/invalid/emptypoints.shp new file mode 100644 index 0000000000000000000000000000000000000000..bdcfb83be42f71ecb07c7d395f4c40e13e6cde16 GIT binary patch literal 112 dcmZQzQ0HR64lG_UGcYh>mm^gaWDFBX699FH0a*Y5 literal 0 HcmV?d00001 diff --git a/django/contrib/gis/tests/data/invalid/emptypoints.shx b/django/contrib/gis/tests/data/invalid/emptypoints.shx new file mode 100644 index 0000000000000000000000000000000000000000..dea663eb087d4a778415da28a9ee226864363515 GIT binary patch literal 108 ccmZQzQ0HR64$NLKGcYh>mm^iw2&jPx0C0B!hyVZp literal 0 HcmV?d00001 diff --git a/django/contrib/gis/tests/layermap/models.py b/django/contrib/gis/tests/layermap/models.py index 3a34d16f3fe..51213eb0b81 100644 --- a/django/contrib/gis/tests/layermap/models.py +++ b/django/contrib/gis/tests/layermap/models.py @@ -43,6 +43,9 @@ class ICity1(CityBase): class ICity2(ICity1): dt_time = models.DateTimeField(auto_now=True) +class Invalid(models.Model): + point = models.PointField() + # Mapping dictionaries for the models above. co_mapping = {'name' : 'Name', 'state' : {'name' : 'State'}, # ForeignKey's use another mapping dictionary for the _related_ Model (State in this case). diff --git a/django/contrib/gis/tests/layermap/tests.py b/django/contrib/gis/tests/layermap/tests.py index a11752a2820..ad7a50462c2 100644 --- a/django/contrib/gis/tests/layermap/tests.py +++ b/django/contrib/gis/tests/layermap/tests.py @@ -4,16 +4,19 @@ from decimal import Decimal from django.utils.copycompat import copy from django.utils.unittest import TestCase -from django.contrib.gis.gdal import DataSource +from django.contrib.gis.gdal import DataSource, OGRException from django.contrib.gis.tests.utils import mysql from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey -from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping +from models import \ + City, County, CountyFeat, Interstate, ICity1, ICity2, Invalid, State, \ + city_mapping, co_mapping, cofeat_mapping, inter_mapping shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data')) city_shp = os.path.join(shp_path, 'cities', 'cities.shp') co_shp = os.path.join(shp_path, 'counties', 'counties.shp') inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp') +invalid_shp = os.path.join(shp_path, 'invalid', 'emptypoints.shp') # Dictionaries to hold what's expected in the county shapefile. NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo'] @@ -265,3 +268,10 @@ class LayerMapTest(TestCase): self.assertEqual(6, ICity1.objects.count()) self.assertEqual(3, ICity2.objects.count()) + + def test07_invalid_layer(self): + "Tests LayerMapping on invalid geometries. See #15378." + invalid_mapping = {'point': 'POINT'} + lm = LayerMapping(Invalid, invalid_shp, invalid_mapping, + source_srs=4326) + lm.save(silent=True) diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index dac53f819bf..0f3a72213dc 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -294,7 +294,10 @@ class LayerMapping(object): if isinstance(model_field, GeometryField): # Verify OGR geometry. - val = self.verify_geom(feat.geom, model_field) + try: + val = self.verify_geom(feat.geom, model_field) + except OGRException: + raise LayerMapError('Could not retrieve geometry from feature.') elif isinstance(model_field, models.base.ModelBase): # The related _model_, not a field was passed in -- indicating # another mapping for the related Model.