예제 #1
0
    def test_union(self):
        """Union with all combinations of geometries/geometry fields."""
        geom = Point(-95.363151, 29.763374, srid=4326)

        union = (
            City.objects.annotate(union=functions.Union("point", geom))
            .get(name="Dallas")
            .union
        )
        expected = fromstr(
            "MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)", srid=4326
        )
        self.assertTrue(expected.equals(union))

        union = (
            City.objects.annotate(union=functions.Union(geom, "point"))
            .get(name="Dallas")
            .union
        )
        self.assertTrue(expected.equals(union))

        union = (
            City.objects.annotate(union=functions.Union("point", "point"))
            .get(name="Dallas")
            .union
        )
        expected = GEOSGeometry("POINT(-96.801611 32.782057)", srid=4326)
        self.assertTrue(expected.equals(union))

        union = (
            City.objects.annotate(union=functions.Union(geom, geom))
            .get(name="Dallas")
            .union
        )
        self.assertTrue(geom.equals(union))
예제 #2
0
    def test_union_mixed_srid(self):
        """The result SRID depends on the order of parameters."""
        geom = Point(61.42915, 55.15402, srid=4326)
        geom_3857 = geom.transform(3857, clone=True)
        tol = 0.001

        for city in City.objects.annotate(union=functions.Union('point', geom_3857)):
            expected = city.point | geom
            self.assertTrue(city.union.equals_exact(expected, tol))
            self.assertEqual(city.union.srid, 4326)

        for city in City.objects.annotate(union=functions.Union(geom_3857, 'point')):
            expected = geom_3857 | city.point.transform(3857, clone=True)
            self.assertTrue(expected.equals_exact(city.union, tol))
            self.assertEqual(city.union.srid, 3857)
예제 #3
0
    def test_diff_intersection_union(self):
        "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
        geom = Point(5, 23, srid=4326)
        qs = Country.objects.all().annotate(
            difference=functions.Difference('mpoly', geom),
            sym_difference=functions.SymDifference('mpoly', geom),
            union=functions.Union('mpoly', geom),
        )

        # For some reason SpatiaLite does something screwy with the Texas geometry here.
        # Also, it doesn't like the null intersection.
        if spatialite:
            qs = qs.exclude(name='Texas')
        else:
            qs = qs.annotate(
                intersection=functions.Intersection('mpoly', geom))

        if oracle:
            # Should be able to execute the queries; however, they won't be the same
            # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or
            # SpatiaLite).
            return
        for c in qs:
            self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
            if not (spatialite or mysql):
                self.assertEqual(c.mpoly.intersection(geom), c.intersection)
            self.assertTrue(
                c.mpoly.sym_difference(geom).equals(c.sym_difference))
            self.assertTrue(c.mpoly.union(geom).equals(c.union))
예제 #4
0
 def test_gis_lookups_with_complex_expressions(self):
     multiple_arg_lookups = {'dwithin', 'relate'}  # These lookups are tested elsewhere.
     lookups = connection.ops.gis_operators.keys() - multiple_arg_lookups
     self.assertTrue(lookups, 'No lookups found')
     for lookup in lookups:
         with self.subTest(lookup):
             City.objects.filter(**{'point__' + lookup: functions.Union('point', 'point')}).exists()
예제 #5
0
 def test_union(self):
     geom = Point(-95.363151, 29.763374, srid=4326)
     ptown = City.objects.annotate(
         union=functions.Union('point', geom)).get(name='Dallas')
     expected = fromstr(
         'MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)', srid=4326)
     self.assertTrue(expected.equals(ptown.union))
예제 #6
0
    def test_union(self):
        """Union with all combinations of geometries/geometry fields."""
        geom = Point(-95.363151, 29.763374, srid=4326)

        union = City.objects.annotate(union=functions.Union('point', geom)).get(name='Dallas').union
        expected = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)', srid=4326)
        self.assertTrue(expected.equals(union))

        union = City.objects.annotate(union=functions.Union(geom, 'point')).get(name='Dallas').union
        self.assertTrue(expected.equals(union))

        union = City.objects.annotate(union=functions.Union('point', 'point')).get(name='Dallas').union
        expected = GEOSGeometry('POINT(-96.801611 32.782057)', srid=4326)
        self.assertTrue(expected.equals(union))

        union = City.objects.annotate(union=functions.Union(geom, geom)).get(name='Dallas').union
        self.assertTrue(geom.equals(union))
예제 #7
0
 def test_union(self):
     geom = Point(-95.363151, 29.763374, srid=4326)
     ptown = City.objects.annotate(union=functions.Union('point', geom)).get(name='Dallas')
     tol = 0.00001
     # Undefined ordering
     expected1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)', srid=4326)
     expected2 = fromstr('MULTIPOINT(-95.363151 29.763374,-96.801611 32.782057)', srid=4326)
     self.assertTrue(expected1.equals_exact(ptown.union, tol) or expected2.equals_exact(ptown.union, tol))
예제 #8
0
파일: tests.py 프로젝트: z757482612/django
    def test_relate_lookup(self):
        "Testing the 'relate' lookup type."
        # To make things more interesting, we will have our Texas reference point in
        # different SRIDs.
        pnt1 = fromstr('POINT (649287.0363174 4177429.4494686)', srid=2847)
        pnt2 = fromstr('POINT(-98.4919715741052 29.4333344025053)', srid=4326)

        # Not passing in a geometry as first param raises a TypeError when
        # initializing the QuerySet.
        with self.assertRaises(ValueError):
            Country.objects.filter(mpoly__relate=(23, 'foo'))

        # Making sure the right exception is raised for the given
        # bad arguments.
        for bad_args, e in [((pnt1, 0), ValueError), ((pnt2, 'T*T***FF*', 0), ValueError)]:
            qs = Country.objects.filter(mpoly__relate=bad_args)
            with self.assertRaises(e):
                qs.count()

        # Relate works differently for the different backends.
        if postgis or spatialite or mariadb:
            contains_mask = 'T*T***FF*'
            within_mask = 'T*F**F***'
            intersects_mask = 'T********'
        elif oracle:
            contains_mask = 'contains'
            within_mask = 'inside'
            # TODO: This is not quite the same as the PostGIS mask above
            intersects_mask = 'overlapbdyintersect'

        # Testing contains relation mask.
        if connection.features.supports_transform:
            self.assertEqual(
                Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name,
                'Texas',
            )
        self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name)

        # Testing within relation mask.
        ks = State.objects.get(name='Kansas')
        self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, within_mask)).name)

        # Testing intersection relation mask.
        if not oracle:
            if connection.features.supports_transform:
                self.assertEqual(
                    Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name,
                    'Texas',
                )
            self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name)
            self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name)

        # With a complex geometry expression
        mask = 'anyinteract' if oracle else within_mask
        self.assertFalse(City.objects.exclude(point__relate=(functions.Union('point', 'point'), mask)))
예제 #9
0
 def test_gis_lookups_with_complex_expressions(self):
     multiple_arg_lookups = {
         "dwithin",
         "relate",
     }  # These lookups are tested elsewhere.
     lookups = connection.ops.gis_operators.keys() - multiple_arg_lookups
     self.assertTrue(lookups, "No lookups found")
     for lookup in lookups:
         with self.subTest(lookup):
             City.objects.filter(
                 **{"point__" + lookup: functions.Union("point", "point")}
             ).exists()
예제 #10
0
def get_geometries_union(field_names: List[str],
                         using="default") -> Union[str, functions.Union]:
    """Generate a union of multiple geometry fields."""
    if len(field_names) == 1:
        return next(iter(field_names))  # fastest in set data type
    elif len(field_names) == 2:
        return functions.Union(*field_names)
    elif connections[using].vendor == "postgresql":
        # postgres can handle multiple field names
        return ST_Union(field_names)
    else:
        # other databases do Union(Union(1, 2), 3)
        return reduce(functions.Union, field_names)
예제 #11
0
def get_geometries_union(
    expressions: list[str | functions.GeoFunc], using="default"
) -> str | functions.Union:
    """Generate a union of multiple geometry fields."""
    if not expressions:
        raise ValueError("Missing geometery fields for get_geometries_union()")

    if len(expressions) == 1:
        return next(iter(expressions))  # fastest in set data type
    elif len(expressions) == 2:
        return functions.Union(*expressions)
    elif connections[using].vendor == "postgresql":
        # postgres can handle multiple field names
        return ST_Union(expressions)
    else:
        # other databases do Union(Union(1, 2), 3)
        return reduce(functions.Union, expressions)
예제 #12
0
    def test_diff_intersection_union(self):
        geom = Point(5, 23, srid=4326)
        qs = Country.objects.all().annotate(
            difference=functions.Difference('mpoly', geom),
            sym_difference=functions.SymDifference('mpoly', geom),
            union=functions.Union('mpoly', geom),
            intersection=functions.Intersection('mpoly', geom),
        )

        if oracle:
            # Should be able to execute the queries; however, they won't be the same
            # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or
            # SpatiaLite).
            return
        for c in qs:
            self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
            if not (spatialite or mysql):
                self.assertEqual(c.mpoly.intersection(geom), c.intersection)
            self.assertTrue(c.mpoly.sym_difference(geom).equals(c.sym_difference))
            self.assertTrue(c.mpoly.union(geom).equals(c.union))
예제 #13
0
    def test_diff_intersection_union(self):
        geom = Point(5, 23, srid=4326)
        qs = Country.objects.annotate(
            difference=functions.Difference("mpoly", geom),
            sym_difference=functions.SymDifference("mpoly", geom),
            union=functions.Union("mpoly", geom),
            intersection=functions.Intersection("mpoly", geom),
        )

        if connection.ops.oracle:
            # Should be able to execute the queries; however, they won't be the same
            # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or
            # SpatiaLite).
            return
        for c in qs:
            self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
            if connection.features.empty_intersection_returns_none:
                self.assertIsNone(c.intersection)
            else:
                self.assertIs(c.intersection.empty, True)
            self.assertTrue(c.mpoly.sym_difference(geom).equals(c.sym_difference))
            self.assertTrue(c.mpoly.union(geom).equals(c.union))
예제 #14
0
    def test_relate_lookup(self):
        "Testing the 'relate' lookup type."
        # To make things more interesting, we will have our Texas reference point in
        # different SRIDs.
        pnt1 = fromstr("POINT (649287.0363174 4177429.4494686)", srid=2847)
        pnt2 = fromstr("POINT(-98.4919715741052 29.4333344025053)", srid=4326)

        # Not passing in a geometry as first param raises a TypeError when
        # initializing the QuerySet.
        with self.assertRaises(ValueError):
            Country.objects.filter(mpoly__relate=(23, "foo"))

        # Making sure the right exception is raised for the given
        # bad arguments.
        for bad_args, e in [
            ((pnt1, 0), ValueError),
            ((pnt2, "T*T***FF*", 0), ValueError),
        ]:
            qs = Country.objects.filter(mpoly__relate=bad_args)
            with self.assertRaises(e):
                qs.count()

        contains_mask = "T*T***FF*"
        within_mask = "T*F**F***"
        intersects_mask = "T********"
        # Relate works differently on Oracle.
        if connection.ops.oracle:
            contains_mask = "contains"
            within_mask = "inside"
            # TODO: This is not quite the same as the PostGIS mask above
            intersects_mask = "overlapbdyintersect"

        # Testing contains relation mask.
        if connection.features.supports_transform:
            self.assertEqual(
                Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name,
                "Texas",
            )
        self.assertEqual(
            "Texas",
            Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name)

        # Testing within relation mask.
        ks = State.objects.get(name="Kansas")
        self.assertEqual(
            "Lawrence",
            City.objects.get(point__relate=(ks.poly, within_mask)).name)

        # Testing intersection relation mask.
        if not connection.ops.oracle:
            if connection.features.supports_transform:
                self.assertEqual(
                    Country.objects.get(mpoly__relate=(pnt1,
                                                       intersects_mask)).name,
                    "Texas",
                )
            self.assertEqual(
                "Texas",
                Country.objects.get(mpoly__relate=(pnt2,
                                                   intersects_mask)).name)
            self.assertEqual(
                "Lawrence",
                City.objects.get(point__relate=(ks.poly,
                                                intersects_mask)).name,
            )

        # With a complex geometry expression
        mask = "anyinteract" if connection.ops.oracle else within_mask
        self.assertFalse(
            City.objects.exclude(
                point__relate=(functions.Union("point", "point"), mask)))