Exemplo n.º 1
0
    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(),
        )
Exemplo n.º 2
0
    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))))
Exemplo n.º 3
0
    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(),
        )