def test_distance_lookups_with_expression_rhs(self): stx_pnt = self.stx_pnt.transform(SouthTexasCity._meta.get_field('point').srid, clone=True) qs = SouthTexasCity.objects.filter( point__distance_lte=(stx_pnt, F('radius')), ).order_by('name') self.assertEqual( self.get_names(qs), ['Bellaire', 'Downtown Houston', 'Southside Place', 'West University Place'] ) # With a combined expression qs = SouthTexasCity.objects.filter( point__distance_lte=(stx_pnt, F('radius') * 2), ).order_by('name') self.assertEqual(len(qs), 5) self.assertIn('Pearland', self.get_names(qs)) # With spheroid param if connection.features.supports_distance_geodetic: hobart = AustraliaCity.objects.get(name='Hobart') qs = AustraliaCity.objects.filter( point__distance_lte=(hobart.point, F('radius') * 70, 'spheroid'), ).order_by('name') self.assertEqual(self.get_names(qs), ['Canberra', 'Hobart', 'Melbourne']) # With a complex geometry expression self.assertFalse(SouthTexasCity.objects.filter(point__distance_gt=(Union('point', 'point'), 0))) self.assertEqual( SouthTexasCity.objects.filter(point__distance_lte=(Union('point', 'point'), 0)).count(), SouthTexasCity.objects.count(), )
def test_dwithin(self): """ Test the `dwithin` lookup type. """ # Distances -- all should be equal (except for the # degree/meter pair in au_cities, that's somewhat # approximate). tx_dists = [(7000, 22965.83), D(km=7), D(mi=4.349)] au_dists = [(0.5, 32000), D(km=32), D(mi=19.884)] # Expected cities for Australia and Texas. tx_cities = ['Downtown Houston', 'Southside Place'] au_cities = ['Mittagong', 'Shellharbour', 'Thirroul', 'Wollongong'] # Performing distance queries on two projected coordinate systems one # with units in meters and the other in units of U.S. survey feet. for dist in tx_dists: if isinstance(dist, tuple): dist1, dist2 = dist else: dist1 = dist2 = dist qs1 = SouthTexasCity.objects.filter(point__dwithin=(self.stx_pnt, dist1)) qs2 = SouthTexasCityFt.objects.filter(point__dwithin=(self.stx_pnt, dist2)) for qs in qs1, qs2: with self.subTest(dist=dist, qs=qs): self.assertEqual(tx_cities, self.get_names(qs)) # With a complex geometry expression self.assertFalse( SouthTexasCity.objects.exclude( point__dwithin=(Union('point', 'point'), 0))) # Now performing the `dwithin` queries on a geodetic coordinate system. for dist in au_dists: with self.subTest(dist=dist): type_error = isinstance(dist, D) and not oracle if isinstance(dist, tuple): if oracle or spatialite: # Result in meters dist = dist[1] else: # Result in units of the field dist = dist[0] # Creating the query set. qs = AustraliaCity.objects.order_by('name') if type_error: # A ValueError should be raised on PostGIS when trying to # pass Distance objects into a DWithin query using a # geodetic field. with self.assertRaises(ValueError): AustraliaCity.objects.filter( point__dwithin=(self.au_pnt, dist)).count() else: self.assertEqual( au_cities, self.get_names( qs.filter(point__dwithin=(self.au_pnt, dist))))
def test_distance_lookups_with_expression_rhs(self): stx_pnt = self.stx_pnt.transform( SouthTexasCity._meta.get_field("point").srid, clone=True) qs = SouthTexasCity.objects.filter( point__distance_lte=(stx_pnt, F("radius")), ).order_by("name") self.assertEqual( self.get_names(qs), [ "Bellaire", "Downtown Houston", "Southside Place", "West University Place", ], ) # With a combined expression qs = SouthTexasCity.objects.filter( point__distance_lte=(stx_pnt, F("radius") * 2), ).order_by("name") self.assertEqual(len(qs), 5) self.assertIn("Pearland", self.get_names(qs)) # With spheroid param if connection.features.supports_distance_geodetic: hobart = AustraliaCity.objects.get(name="Hobart") AustraliaCity.objects.update(ref_point=hobart.point) for ref_point in [hobart.point, F("ref_point")]: qs = AustraliaCity.objects.filter( point__distance_lte=(ref_point, F("radius") * 70, "spheroid"), ).order_by("name") self.assertEqual(self.get_names(qs), ["Canberra", "Hobart", "Melbourne"]) # With a complex geometry expression self.assertFalse( SouthTexasCity.objects.filter( point__distance_gt=(Union("point", "point"), 0))) self.assertEqual( SouthTexasCity.objects.filter( point__distance_lte=(Union("point", "point"), 0)).count(), SouthTexasCity.objects.count(), )