Exemplo n.º 1
0
def conditional_transform(
    expression: str | functions.GeoFunc, expression_srid: int, output_srid: int
) -> str | functions.Transform:
    """Apply a CRS Transform to the queried field if that is needed."""
    if expression_srid != output_srid:
        expression = functions.Transform(expression, srid=output_srid)
    return expression
Exemplo n.º 2
0
 def test_simplify_geojson(self):
     fn = functions.AsGeoJSON(query.Simplify(
         functions.Transform('geom', self.srid), self.tol),
                              precision=2)
     sqs = self.qs.all().annotate(geojson=fn)
     geom = geos.GEOSGeometry(sqs[0].geojson, self.srid)
     source = self.qs[0].geom
     self.assertNotEqual(geom, source)
     self.assertNotEqual(geom.srid, source.srid)
     self.assertLess(geom.num_coords, source.num_coords)
Exemplo n.º 3
0
    def test_transform(self):
        # Pre-transformed points for Houston and Pueblo.
        ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774)
        prec = 3  # Precision is low due to version variations in PROJ and GDAL.

        # Asserting the result of the transform operation with the values in
        #  the pre-transformed points.
        h = City.objects.annotate(pt=functions.Transform('point', ptown.srid)).get(name='Pueblo')
        self.assertEqual(2774, h.pt.srid)
        self.assertAlmostEqual(ptown.x, h.pt.x, prec)
        self.assertAlmostEqual(ptown.y, h.pt.y, prec)
Exemplo n.º 4
0
    def test_inherited_geofields(self):
        "Database functions on inherited Geometry fields."
        # Creating a Pennsylvanian city.
        PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')

        # All transformation SQL will need to be performed on the
        # _parent_ table.
        qs = PennsylvaniaCity.objects.annotate(new_point=functions.Transform('point', srid=32128))

        self.assertEqual(1, qs.count())
        for pc in qs:
            self.assertEqual(32128, pc.new_point.srid)
Exemplo n.º 5
0
    def test_transform(self):
        # Pre-transformed points for Houston and Pueblo.
        ptown = fromstr("POINT(992363.390841912 481455.395105533)", srid=2774)

        # Asserting the result of the transform operation with the values in
        #  the pre-transformed points.
        h = City.objects.annotate(
            pt=functions.Transform("point", ptown.srid)).get(name="Pueblo")
        self.assertEqual(2774, h.pt.srid)
        # Precision is low due to version variations in PROJ and GDAL.
        self.assertLess(ptown.x - h.pt.x, 1)
        self.assertLess(ptown.y - h.pt.y, 1)
Exemplo n.º 6
0
    def extent(self, srid=None):
        """Returns the GeoQuerySet extent as a 4-tuple.

        Keyword args:
        srid -- EPSG id for for transforming the output geometry.
        """
        expr = self.geo_field.name
        if srid:
            expr = geofn.Transform(expr, srid)
        expr = models.Extent(expr)
        clone = self.all()
        name, val = clone.aggregate(expr).popitem()
        return val
 def test_serialize_queryset_simplify(self):
     fn = query.Simplify(functions.Transform('geom', 4269), 1.01)
     qs = Location.objects.all()
     for obj in qs:
         obj.geom = obj.geom.buffer(1.5)
         obj.save()
     qs = qs.annotate(simplify=fn)
     obj = qs[0]
     serializer = SimplifyLocationSerializer(obj)
     g = geos.GEOSGeometry(json.dumps(serializer.data['geometry']),
                           srid=obj.simplify.srid)
     self.assertEqual(g, obj.simplify)
     self.assertEqual(obj.simplify.srid, 4269)
     self.assertEqual(serializer.data['crs']['properties']['name'][-4:], '4269')
Exemplo n.º 8
0
 def select(self):
     kwargs = {}
     data = self.cleaned_data
     tolerance, srs, format = map(data.get, ('simplify', 'srs', 'format'))
     expr = field = query.geo_field(self.queryset).name
     srid = getattr(srs, 'srid', None)
     if srid:
         expr = functions.Transform(expr, srid)
     if data['op']:
         expr = data['op'](expr)
     if data['precision'] is not None:
         kwargs.update(precision=data['precision'])
     if tolerance:
         expr = query.Simplify(expr, tolerance)
     if format:
         expr = format(expr, **kwargs)
     if expr != field:
         attrname = self.data.get('format')
         self.queryset = self.queryset.annotate(**{attrname: expr})
Exemplo n.º 9
0
    def tile(self, bbox, z=0, format=None, clip=True):
        """Returns a GeoQuerySet intersecting a tile boundary.

        Arguments:
        bbox -- tile extent as geometry
        Keyword args:
        z -- tile zoom level used as basis for geometry simplification
        format -- vector tile format as str (pbf, geojson)
        clip -- clip geometries to tile boundary as boolean
        """
        # Tile grid uses 3857, but GeoJSON coordinates should be in 4326.
        tile_srid = 3857
        bbox = getattr(bbox, 'geos', bbox)
        clone = filter_geometry(self, intersects=bbox)
        field = clone.geo_field
        srid = field.srid
        sql = field.name
        try:
            tilew = self.tilewidths[z]
        except IndexError:
            tilew = self.tilewidths[-1]
        if bbox.srid != srid:
            bbox = bbox.transform(srid, clone=True)
        # Estimate tile width in degrees instead of meters.
        if bbox.srs.geographic:
            p = geos.Point(tilew, tilew, srid=tile_srid)
            p.transform(srid)
            tilew = p.x
        if clip:
            bufbox = bbox.buffer(tilew)
            sql = geofn.Intersection(sql, bufbox.envelope)
        sql = SimplifyPreserveTopology(sql, tilew)
        if format == 'pbf':
            return clone.pbf(bbox, geo_col=sql)
        sql = geofn.Transform(sql, 4326)
        return clone.annotate(**{format: sql})