Ticket #9364: handle_inherited_geofields.diff
File handle_inherited_geofields.diff, 10.1 KB (added by , 16 years ago) |
---|
-
django/contrib/gis/db/models/query.py
605 605 # set on the `GeoQuery` object of this queryset. 606 606 if aggregate: self.query.aggregate = True 607 607 608 # Is this operation going to be on a related geographic field? 609 if not geo_field in self.model._meta.fields: 608 opts = self.model._meta 609 if not geo_field in opts.fields: 610 # Is this operation going to be on a related geographic field? 610 611 # If so, it'll have to be added to the select related information 611 612 # (e.g., if 'location__point' was given as the field name). 612 613 self.query.add_select_related([field_name]) 613 614 self.query.pre_sql_setup() 614 615 rel_table, rel_col = self.query.related_select_cols[self.query.related_select_fields.index(geo_field)] 615 616 return self.query._field_column(geo_field, rel_table) 617 elif not geo_field in opts.local_fields: 618 # This geographic field is inherited from another model, so we have to 619 # use the db table for the _parent_ model instead. 620 tmp_fld, parent_model, direct, m2m = opts.get_field_by_name(geo_field.name) 621 return self.query._field_column(geo_field, parent_model._meta.db_table) 616 622 else: 617 623 return self.query._field_column(geo_field) -
django/contrib/gis/tests/geoapp/tests.py
1 1 import os, unittest 2 from models import Country, City, State, Feature, MinusOneSRID2 from models import Country, City, PennsylvaniaCity, State, Feature, MinusOneSRID 3 3 from django.contrib.gis import gdal 4 4 from django.contrib.gis.db.backend import SpatialBackend 5 5 from django.contrib.gis.geos import * 6 6 from django.contrib.gis.measure import Distance 7 from django.contrib.gis.tests.utils import no_oracle, no_postgis , oracle, postgis7 from django.contrib.gis.tests.utils import no_oracle, no_postgis 8 8 9 9 # TODO: Some tests depend on the success/failure of previous tests, these should 10 10 # be decoupled. This flag is an artifact of this problem, and makes debugging easier; … … 17 17 def test01_initial_sql(self): 18 18 "Testing geographic initial SQL." 19 19 if DISABLE: return 20 if oracle:20 if SpatialBackend.oracle: 21 21 # Oracle doesn't allow strings longer than 4000 characters 22 22 # in SQL files, and I'm stumped on how to use Oracle BFILE's 23 23 # in PLSQL, so we set up the larger geometries manually, rather … … 38 38 self.assertEqual(8, City.objects.count()) 39 39 40 40 # Oracle cannot handle NULL geometry values w/certain queries. 41 if oracle: n_state = 241 if SpatialBackend.oracle: n_state = 2 42 42 else: n_state = 3 43 43 self.assertEqual(n_state, State.objects.count()) 44 44 … … 147 147 ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo') 148 148 ptown2 = City.objects.gml(precision=9).get(name='Pueblo') 149 149 150 if oracle:150 if SpatialBackend.oracle: 151 151 # No precision parameter for Oracle :-/ 152 152 import re 153 153 gml_regex = re.compile(r'<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925199\d+,38.25500\d+ </gml:coordinates></gml:Point>') … … 167 167 168 168 # Asserting the result of the transform operation with the values in 169 169 # the pre-transformed points. Oracle does not have the 3084 SRID. 170 if not oracle:170 if not SpatialBackend.oracle: 171 171 h = City.objects.transform(htown.srid).get(name='Houston') 172 172 self.assertEqual(3084, h.point.srid) 173 173 self.assertAlmostEqual(htown.x, h.point.x, prec) … … 214 214 qs1 = City.objects.filter(point__disjoint=ptown.point) 215 215 self.assertEqual(7, qs1.count()) 216 216 217 if not postgis:217 if not SpatialBackend.postgis: 218 218 # TODO: Do NULL columns bork queries on PostGIS? The following 219 219 # error is encountered: 220 220 # psycopg2.ProgrammingError: invalid memory alloc request size 4294957297 … … 231 231 # Seeing what cities are in Texas, should get Houston and Dallas, 232 232 # and Oklahoma City because 'contained' only checks on the 233 233 # _bounding box_ of the Geometries. 234 if not oracle:234 if not SpatialBackend.oracle: 235 235 qs = City.objects.filter(point__contained=texas.mpoly) 236 236 self.assertEqual(3, qs.count()) 237 237 cities = ['Houston', 'Dallas', 'Oklahoma City'] … … 259 259 self.assertEqual(0, len(Country.objects.filter(mpoly__contains=okcity.point.wkt))) # Qeury w/WKT 260 260 261 261 # OK City is contained w/in bounding box of Texas. 262 if not oracle:262 if not SpatialBackend.oracle: 263 263 qs = Country.objects.filter(mpoly__bbcontains=okcity.point) 264 264 self.assertEqual(1, len(qs)) 265 265 self.assertEqual('Texas', qs[0].name) … … 272 272 wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84 273 273 274 274 # Oracle doesn't have SRID 3084, using 41157. 275 if oracle:275 if SpatialBackend.oracle: 276 276 # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157) 277 277 # Used the following Oracle SQL to get this value: 278 278 # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL; … … 287 287 # `SDO_OVERLAPBDYINTERSECT` operates differently from 288 288 # `ST_Intersects`, so contains is used instead. 289 289 nad_pnt = fromstr(nad_wkt, srid=nad_srid) 290 if oracle:290 if SpatialBackend.oracle: 291 291 tx = Country.objects.get(mpoly__contains=nad_pnt) 292 292 else: 293 293 tx = Country.objects.get(mpoly__intersects=nad_pnt) … … 329 329 self.assertEqual(True, 'Kansas' in state_names) 330 330 331 331 # Saving another commonwealth w/a NULL geometry. 332 if not oracle:332 if not SpatialBackend.oracle: 333 333 # TODO: Fix saving w/NULL geometry on Oracle. 334 334 State(name='Northern Mariana Islands', poly=None).save() 335 335 … … 398 398 self.assertRaises(e, qs.count) 399 399 400 400 # Relate works differently for the different backends. 401 if postgis:401 if SpatialBackend.postgis: 402 402 contains_mask = 'T*T***FF*' 403 403 within_mask = 'T*F**F***' 404 404 intersects_mask = 'T********' 405 elif oracle:405 elif SpatialBackend.oracle: 406 406 contains_mask = 'contains' 407 407 within_mask = 'inside' 408 408 # TODO: This is not quite the same as the PostGIS mask above … … 417 417 self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, within_mask)).name) 418 418 419 419 # Testing intersection relation mask. 420 if not oracle:420 if not SpatialBackend.oracle: 421 421 self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name) 422 422 self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name) 423 423 self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name) … … 479 479 "Testing the `centroid` GeoQuerySet method." 480 480 if DISABLE: return 481 481 qs = State.objects.exclude(poly__isnull=True).centroid() 482 if oracle: tol = 0.1482 if SpatialBackend.oracle: tol = 0.1 483 483 else: tol = 0.000000001 484 484 for s in qs: 485 485 self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol)) … … 536 536 for c in City.objects.filter(point__isnull=False).num_geom(): 537 537 # Oracle will return 1 for the number of geometries on non-collections, 538 538 # whereas PostGIS will return None. 539 if postgis: self.assertEqual(None, c.num_geom)539 if SpatialBackend.postgis: self.assertEqual(None, c.num_geom) 540 540 else: self.assertEqual(1, c.num_geom) 541 541 542 542 def test24_numpoints(self): 543 543 "Testing the `num_points` GeoQuerySet method." 544 544 if DISABLE: return 545 545 for c in Country.objects.num_points(): self.assertEqual(c.mpoly.num_points, c.num_points) 546 if postgis:546 if SpatialBackend.postgis: 547 547 # Oracle cannot count vertices in Point geometries. 548 548 for c in City.objects.num_points(): self.assertEqual(1, c.num_points) 549 549 … … 558 558 self.assertEqual(c.mpoly.sym_difference(geom), c.sym_difference) 559 559 self.assertEqual(c.mpoly.union(geom), c.union) 560 560 561 def test26_inherited_geofields(self): 562 "Test GeoQuerySet methods on inherited Geometry fields." 563 # Creating a Pennsylvanian city. 564 mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)') 565 566 # All transformation SQL will need to be performed on the 567 # _parent_ table. 568 qs = PennsylvaniaCity.objects.transform(32128) 569 570 self.assertEqual(1, qs.count()) 571 for pc in qs: self.assertEqual(32128, pc.point.srid) 572 561 573 from test_feeds import GeoFeedTest 562 574 from test_sitemaps import GeoSitemapTest 563 575 def suite(): -
django/contrib/gis/tests/geoapp/models.py
16 16 objects = models.GeoManager() 17 17 def __unicode__(self): return self.name 18 18 19 # This is an inherited model from City 20 class PennsylvaniaCity(City): 21 county = models.CharField(max_length=30) 22 objects = models.GeoManager() # TODO: This should be implicitly inherited. 23 19 24 class State(models.Model): 20 25 name = models.CharField(max_length=30) 21 26 poly = models.PolygonField(null=null_flag) # Allowing NULL geometries here.