예제 #1
0
 def process(data, kwargs):
     if "features" in data:
         if len(data["features"]) == 0:
             return data
         req_srs = data["projection"]
         buf_srs = kwargs["buf_srs"]
         features = data["features"].set_geometry(
             data["features"].geometry.apply(
                 shapely_transform, args=(req_srs, buf_srs)).buffer(
                     distance=kwargs["distance"],
                     resolution=kwargs["resolution"]).apply(
                         shapely_transform, args=(buf_srs, req_srs)))
         return {"features": features, "projection": req_srs}
     elif "extent" in data:
         if not data["extent"]:
             return data
         req_srs = data["projection"]
         buf_srs = kwargs["buf_srs"]
         distance = kwargs["distance"]
         extent = transform_extent(data["extent"], req_srs, buf_srs)
         extent = Extent(extent, buf_srs).buffered(distance).bbox
         extent = transform_extent(extent, buf_srs, req_srs)
         return {"extent": extent, "projection": req_srs}
     else:
         raise NotImplementedError("Dunno this mode!")
예제 #2
0
 def test_transform_extent(self, shapely_transform):
     src_srs = "some_fiona_crs"
     dst_srs = "another_fiona_crs"
     extent = 0, 0, 1, 1
     expected = 2, 2, 3, 3
     shapely_transform.return_value = geometry.box(*expected)
     result = utils.transform_extent(extent, src_srs=src_srs, dst_srs=dst_srs)
     shapely_transform.assert_called_with(
         geometry.box(*extent), src_srs=src_srs, dst_srs=dst_srs
     )
     self.assertEqual(expected, result)
예제 #3
0
    def get_sources_and_requests(self, **request):
        if request.get("mode") == "extent":
            return [(self.source, request), (None, None),
                    ({
                        "mode": "extent"
                    }, None)]

        req_srs = request["projection"]
        agg_srs = self.projection

        # acquire the extent of the geometry data
        extent_request = {**request, "mode": "extent"}
        extent = self.source.get_data(**extent_request)["extent"]

        if extent is None:
            # make sources_and_request so that we get an empty result
            return [
                (None, None),
                (None, None),
                ({
                    "empty": True,
                    "projection": req_srs
                }, None),
            ]

        # transform the extent into the projection in which we aggregate
        x1, y1, x2, y2 = utils.transform_extent(extent, req_srs, agg_srs)

        # estimate the amount of required pixels
        required_pixels = int(((x2 - x1) * (y2 - y1)) / (self.pixel_size**2))

        # in case this request is too large, we adapt pixel size
        max_pixels = self.max_pixels
        if max_pixels is None:
            max_pixels = config.get("geomodeling.raster-limit")
        pixel_size = self.pixel_size

        if required_pixels > max_pixels and self.auto_pixel_size:
            # adapt with integer multiples of pixel_size
            pixel_size *= ceil(sqrt(required_pixels / max_pixels))
        elif required_pixels > max_pixels:
            raise RuntimeError(
                "The required raster size for the aggregation exceeded "
                "the maximum ({} > {})".format(required_pixels, max_pixels))

        # snap the extent to (0, 0) to prevent subpixel shifts
        x1 = floor(x1 / pixel_size) * pixel_size
        y1 = floor(y1 / pixel_size) * pixel_size
        x2 = ceil(x2 / pixel_size) * pixel_size
        y2 = ceil(y2 / pixel_size) * pixel_size

        # compute the width and height
        width = max(int((x2 - x1) / pixel_size), 1)
        height = max(int((y2 - y1) / pixel_size), 1)

        raster_request = {
            "mode": "vals",
            "projection": agg_srs,
            "start": request.get("start"),
            "stop": request.get("stop"),
            "aggregation": None,  # TODO
            "bbox": (x1, y1, x2, y2),
            "width": width,
            "height": height,
        }

        process_kwargs = {
            "mode": request.get("mode", "intersects"),
            "pixel_size": self.pixel_size,
            "agg_srs": agg_srs,
            "req_srs": req_srs,
            "actual_pixel_size": pixel_size,
            "statistic": self.statistic,
            "result_column": self.column_name,
            "agg_bbox": (x1, y1, x2, y2),
        }

        return [
            (self.source, request),
            (self.raster, raster_request),
            (process_kwargs, None),
        ]