Exemple #1
0
def test_layer_model_floats():
    layer_def = LayerModel(
        dataset="test",
        version="v1.1.1",
        source_type="raster",
        pixel_meaning="test",
        data_type=DataTypeEnum.float32,
        nbits=6,
        grid="10/40000",
        resampling="bilinear",
        source_uri=["s3://test/tiles.geojson"],
        no_data="nan",
    )

    assert isinstance(layer_def.no_data, float)
    assert math.isnan(layer_def.no_data)

    layer_def = LayerModel(
        dataset="test",
        version="v1.1.1",
        source_type=SourceType.raster,
        pixel_meaning="test",
        data_type=DataTypeEnum.float32,
        nbits=6,
        grid="10/40000",
        resampling="bilinear",
        source_uri=["s3://test/tiles.geojson"],
        no_data="2.2",
    )

    assert isinstance(layer_def.no_data, float)
Exemple #2
0
def test_layer_model():
    with pytest.raises(ValidationError):
        layer_def = LayerModel(
            dataset="test",
            version="v1.1.1",
            source_type="raster",
            pixel_meaning="test",
            data_type=DataTypeEnum.uint8,
            nbits=6,
            no_data=0,
            grid="10/40000",
            resampling="wrong",
            source_uri=["s3://test/tiles.geojson"],
        )

    layer_def = LayerModel(
        dataset="test",
        version="v1.1.1",
        source_type="raster",
        pixel_meaning="test",
        data_type=DataTypeEnum.uint8,
        nbits=6,
        no_data=0,
        grid="10/40000",
        resampling="bilinear",
        source_uri=["s3://test/tiles.geojson"],
    )

    resampling = resampling_factory(layer_def.resampling)

    assert resampling == Resampling.bilinear
Exemple #3
0
    def test_models_nan(self):
        good_layer_dict = copy.deepcopy(minimal_layer_dict)
        good_layer_dict.update(no_data="NaN")
        layer = LayerModel.parse_obj(good_layer_dict)
        assert math.isnan(layer.no_data)

        bad_layer_dict = copy.deepcopy(minimal_layer_dict)
        bad_layer_dict.update(no_data="NaNa")
        with pytest.raises(ValidationError):
            LayerModel.parse_obj(bad_layer_dict)
Exemple #4
0
def test_vector_layer():
    layer_dict = {
        **minimal_layer_dict,
        "source_type": "vector",
        "no_data": 0,
        "nbits": 2,
        "data_type": "uint8",
        "order": "desc",
    }
    layer_dict.pop("source_uri")
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.VectorSrcLayer)
    assert layer.__class__.__name__ == "VectorSrcLayer"
    assert layer.dst_profile["dtype"] == "uint8"
    assert layer.dst_profile["compress"] == "DEFLATE"
    assert layer.dst_profile["tiled"] is True
    assert layer.dst_profile["blockxsize"] == 400
    assert layer.dst_profile["blockysize"] == 400
    assert layer.dst_profile["pixeltype"] == "DEFAULT"
    assert layer.dst_profile["nodata"] == 0
    assert layer.dst_profile["nbits"] == 2
    assert layer.calc == "Mg_ha-1"
    assert layer.resampling == Resampling.nearest
    assert layer.rasterize_method is None
    assert layer.order == "desc"
Exemple #5
0
def test_raster_calc_layer():
    layer_dict = {
        **minimal_layer_dict,
        "data_type": "uint8",
        "nbits": 3,
        "no_data": 0,
        "calc":
        "1*(A>10)+1*(A>15)+1*(A>20)+1*(A>25)+1*(A>30)+1*(A>50)+1*(A>75)",
        "resampling": "nearest",
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.RasterSrcLayer)
    assert layer.__class__.__name__ == "RasterSrcLayer"
    assert layer.dst_profile["dtype"] == "uint8"
    assert layer.dst_profile["compress"] == "DEFLATE"
    assert layer.dst_profile["tiled"] is True
    assert layer.dst_profile["blockxsize"] == 400
    assert layer.dst_profile["blockysize"] == 400
    assert layer.dst_profile["pixeltype"] == "DEFAULT"
    assert layer.dst_profile["nodata"] == 0
    assert layer.dst_profile["nbits"] == 3
    assert layer.resampling == Resampling.nearest
    assert (layer.calc ==
            "1*(A>10)+1*(A>15)+1*(A>20)+1*(A>25)+1*(A>30)+1*(A>50)+1*(A>75)")
    assert layer.rasterize_method is None
    assert layer.order is None
Exemple #6
0
def test_multi_source_layer():
    layer_dict = {
        **minimal_layer_dict,
        "source_uri": [
            f"s3://{BUCKET}/{GEOJSON_NAME}",
            f"s3://{BUCKET}/{GEOJSON_2_NAME}",
        ],
        "calc":
        "A + B",
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.RasterSrcLayer)
    assert layer.__class__.__name__ == "RasterSrcLayer"
    assert layer.dst_profile["dtype"] == "uint16"
    assert layer.dst_profile["compress"] == "DEFLATE"
    assert layer.dst_profile["tiled"] is True
    assert layer.dst_profile["blockxsize"] == 400
    assert layer.dst_profile["blockysize"] == 400
    assert layer.dst_profile["pixeltype"] == "DEFAULT"
    assert layer.resampling == Resampling.nearest
    assert layer.calc == "A + B"
    assert layer.rasterize_method is None
    assert layer.order is None
    assert layer.geom == MultiPolygon([
        Polygon([[10.0, 10.0], [20.0, 10.0], [20.0, 0.0], [10.0, 0.0],
                 [10.0, 10.0]]),
        Polygon([[-10.0, 10.0], [0.0, 10.0], [0.0, 0.0], [-10.0, 0.0],
                 [-10.0, 10.0]]),
    ])
Exemple #7
0
    def test_version_pattern(self):
        good_versions = [
            "v2019", "v201911", "v20191122", "v1", "v1.2", "v1.2.3"
        ]
        bad_versions = ["v1.beta", "1.2", "version1.2.3", "v.1.2.3"]

        for v in good_versions:
            good_layer_dict = copy.deepcopy(minimal_layer_dict)
            good_layer_dict.update(version=v)
            layer = LayerModel(**good_layer_dict)
            assert layer.version == v

        for v in bad_versions:
            bad_layer_dict = copy.deepcopy(minimal_layer_dict)
            bad_layer_dict.update(version=v)
            with pytest.raises(ValidationError):
                LayerModel(**bad_layer_dict)
Exemple #8
0
def LAYER_MULTI():
    layer_dict_multi = deepcopy(LAYER_DICT)
    layer_dict_multi["source_uri"] = [
        f"s3://{BUCKET}/{GEOJSON_NAME}",
        f"s3://{BUCKET}/{GEOJSON_NAME}",
    ]
    layer_dict_multi["calc"] = "A + B"

    yield layer_factory(LayerModel(**layer_dict_multi))
Exemple #9
0
def test_multi_source_layer_no_calc():
    layer_dict = {
        **minimal_layer_dict,
        "source_uri": [
            f"s3://{BUCKET}/{GEOJSON_NAME}",
            f"s3://{BUCKET}/{GEOJSON_2_NAME}",
        ],
    }

    with pytest.raises(ValidationError):
        layers.layer_factory(LayerModel.parse_obj(layer_dict))
Exemple #10
0
def test_layer_model_multi_band_output_no_no_data():
    LayerModel(
        dataset="test",
        version="v1.1.1",
        source_type=SourceType.raster,
        pixel_meaning="test",
        data_type=DataTypeEnum.uint8,
        nbits=6,
        no_data=None,
        band_count=3,
        calc="test",
        grid="10/40000",
        source_uri=["s3://test/tiles.geojson"],
    )
Exemple #11
0
def test_folder_source_uri():
    layer_dict = {
        **minimal_layer_dict,
        "source_uri": [f"s3://{BUCKET}/folder"],
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.RasterSrcLayer)
    assert layer.geom == MultiPolygon([
        Polygon([[10.0, 10.0], [20.0, 10.0], [20.0, 0.0], [10.0, 0.0],
                 [10.0, 10.0]]),
        Polygon([[-10.0, 10.0], [0.0, 10.0], [0.0, 0.0], [-10.0, 0.0],
                 [-10.0, 10.0]]),
    ])
Exemple #12
0
def test_layer_model_multi_band_no_calc_multi_input():
    # no calc,  multi band input
    with pytest.raises(ValidationError):
        LayerModel(
            dataset="test",
            version="v1.1.1",
            source_type=SourceType.raster,
            pixel_meaning="test",
            data_type=DataTypeEnum.uint8,
            nbits=6,
            no_data=0,
            band_count=1,
            grid="10/40000",
            source_uri=["s3://test/tiles.geojson", "s3://test/tiles.geojson"],
        )
Exemple #13
0
def test_layer_model_multi_band_no_data_different():
    # varying no data types
    with pytest.raises(ValidationError):
        LayerModel(
            dataset="test",
            version="v1.1.1",
            source_type=SourceType.raster,
            pixel_meaning="test",
            data_type=DataTypeEnum.uint8,
            nbits=6,
            no_data=[1, 2, 3],
            band_count=3,
            calc="A * 5",
            grid="10/40000",
            source_uri=["s3://test/tiles.geojson"],
        )
Exemple #14
0
def test_get_grid_tiles():
    # message = ""
    # try:
    #     len(PIPE.get_grid_tiles())
    # except NotImplementedError:
    #     message = "not implemented"
    # assert message == "not implemented"

    layer_dict = {
        **LAYER_DICT,
        "grid": "10/40000",
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    pipe = RasterPipe(layer)
    assert len(pipe.get_grid_tiles()) == 648
Exemple #15
0
def test_pipe_factory_raster_src_layer():
    layer_dict = {
        **minimal_layer_dict,
        "dataset": "aqueduct_erosion_risk",
        "version": "v201911",
        "pixel_meaning": "level",
        "no_data": 0,
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    pipe = pipe_factory(layer)
    assert isinstance(pipe, RasterPipe)
    assert pipe.__class__.__name__ == "RasterPipe"

    pipe = pipe_factory(layer, SUBSET)
    assert isinstance(pipe, RasterPipe)
    assert pipe.__class__.__name__ == "RasterPipe"
Exemple #16
0
def cli(
    dataset: str,
    version: str,
    subset: Optional[List[str]],
    overwrite: bool,
    layer_json: str,
):

    layer_dict = json.loads(layer_json)
    layer_dict.update({"dataset": dataset, "version": version})
    layer_def = LayerModel.parse_obj(layer_dict)

    # Raster sources must have an source URI
    if layer_def.source_type == "raster" and layer_def.source_uri is None:
        raise ValueError("URI specification is required for raster sources")

    # Finally, actually process the layer
    tiles, skipped_tiles, failed_tiles, existing_tiles = pixetl(
        layer_def,
        subset,
        overwrite,
    )

    nb_tiles = len(tiles)
    nb_skipped_tiles = len(skipped_tiles)
    nb_failed_tiles = len(failed_tiles)
    nb_existing_tiles = len(existing_tiles)

    LOGGER.info(f"Successfully processed {len(tiles)} tiles")
    LOGGER.info(f"{nb_skipped_tiles} tiles skipped.")
    LOGGER.info(f"{nb_existing_tiles} tiles already existed.")
    LOGGER.info(f"{nb_failed_tiles} tiles failed.")
    if nb_tiles:
        LOGGER.info(f"Processed tiles: {tiles}")
    if nb_skipped_tiles:
        LOGGER.info(f"Skipped tiles: {skipped_tiles}")
    if nb_existing_tiles:
        LOGGER.info(f"Existing tiles: {existing_tiles}")
    if nb_failed_tiles:
        LOGGER.info(f"Failed tiles: {failed_tiles}")
        sys.exit(
            "Program terminated with Errors. Some tiles failed to process")
Exemple #17
0
def test_raster_layer_uri():
    layer_dict = {
        **minimal_layer_dict,
        "no_data": 0,
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.RasterSrcLayer)
    assert layer.__class__.__name__ == "RasterSrcLayer"
    assert layer.dst_profile["dtype"] == "uint16"
    assert layer.dst_profile["compress"] == "DEFLATE"
    assert layer.dst_profile["tiled"] is True
    assert layer.dst_profile["blockxsize"] == 400
    assert layer.dst_profile["blockysize"] == 400
    assert layer.dst_profile["pixeltype"] == "DEFAULT"
    assert layer.dst_profile["nodata"] == 0
    assert layer.resampling == Resampling.nearest
    assert layer.calc is None
    assert layer.rasterize_method is None
    assert layer.order is None
def test_transform_final_wm():
    layer_dict_wm = deepcopy(LAYER_DICT)
    layer_dict_wm["grid"] = "zoom_0"
    layer_dict_wm["source_uri"] = [f"s3://{BUCKET}/{GEOJSON_2_NAME}"]

    layer_wm = layers.layer_factory(LayerModel(**layer_dict_wm))

    assert isinstance(layer_wm, layers.RasterSrcLayer)
    tile = RasterSrcTile("000R_000C", layer_wm.grid, layer_wm)

    assert tile.dst[tile.default_format].crs.is_valid
    tile.transform()

    LOGGER.debug(tile.local_dst[tile.default_format].uri)
    with rasterio.Env(**GDAL_ENV), rasterio.open(
            tile.local_dst[tile.default_format].uri) as src:
        src_profile = src.profile
        output = src.read(1)

    LOGGER.debug(src_profile)

    assert output.shape == (256, 256)

    assert src_profile["blockxsize"] == layer_wm.grid.blockxsize
    assert src_profile["blockysize"] == layer_wm.grid.blockysize
    assert src_profile["compress"].lower(
    ) == layer_wm.dst_profile["compress"].lower()
    assert src_profile["count"] == 1
    assert src_profile["crs"] == {"init": layer_wm.grid.crs.srs}
    assert src_profile["crs"].is_valid
    assert src_profile["driver"] == "GTiff"
    assert src_profile["dtype"] == layer_wm.dst_profile["dtype"]
    assert src_profile["height"] == layer_wm.grid.cols
    assert src_profile["interleave"] == "band"
    assert src_profile["nodata"] == layer_wm.dst_profile["nodata"]
    assert src_profile["tiled"] is True
    assert src_profile["width"] == layer_wm.grid.rows
    # assert src_profile["nbits"] == nbits # Not exposed in rasterio API

    assert not hasattr(src_profile, "compress")
    os.remove(tile.local_dst[tile.default_format].uri)
Exemple #19
0
def _get_subset_tiles() -> Set[RasterSrcTile]:
    layer_dict = {
        **minimal_layer_dict,
        "dataset": "aqueduct_erosion_risk",
        "version": "v201911",
        "pixel_meaning": "level",
        "no_data": 0,
        "grid": "1/4000",
    }
    layer = layers.layer_factory(LayerModel.parse_obj(layer_dict))

    assert isinstance(layer, layers.RasterSrcLayer)

    pipe = RasterPipe(layer)

    tiles = set()
    for i in range(10, 12):
        for j in range(10, 12):
            assert isinstance(pipe.grid, LatLngGrid)
            tile_id = pipe.grid.xy_to_tile_id(j, i)
            tiles.add(
                RasterSrcTile(tile_id=tile_id, grid=pipe.grid, layer=layer))

    return tiles
Exemple #20
0
 def test_models_bad_order(self):
     bad_layer_dict = {**minimal_layer_dict, "order": "random"}
     with self.assertRaises(ValidationError) as e:
         _ = LayerModel.parse_obj(bad_layer_dict)
         assert "order" in str(e)
Exemple #21
0
def LAYER_WM():
    layer_dict_wm = deepcopy(LAYER_DICT)
    layer_dict_wm["grid"] = "zoom_14"

    yield layer_factory(LayerModel(**layer_dict_wm))
Exemple #22
0
from unittest import mock

from gfw_pixetl.models.pydantic import LayerModel
from gfw_pixetl.pipes import RasterPipe
from gfw_pixetl.pixetl import pixetl
from tests.conftest import minimal_layer_dict

LAYER_DICT = deepcopy(minimal_layer_dict)
LAYER_DICT.update({
    "dataset": "aqueduct_erosion_risk",
    "version": "v201911",
    "pixel_meaning": "level",
    "grid": "1/4000",
})

RASTER_LAYER_DEF = LayerModel.parse_obj(LAYER_DICT)

SUBSET = ["10N_010E"]


def test_pixetl():

    cwd = os.getcwd()

    with mock.patch.object(RasterPipe,
                           "create_tiles",
                           return_value=(list(), list(), list(), list())):
        tiles, skipped_tiles, failed_tiles, existing_tiles = pixetl(
            RASTER_LAYER_DEF,
            subset=SUBSET,
            overwrite=True,
Exemple #23
0
 def test_models_good_rasterize_method(self):
     good_layer_dict = {**minimal_layer_dict, "rasterize_method": "count"}
     _ = LayerModel.parse_obj(good_layer_dict)
Exemple #24
0
 def test_models_bad_rasterize_method(self):
     bad_layer_dict = {**minimal_layer_dict, "rasterize_method": "random"}
     with self.assertRaises(ValidationError) as e:
         _ = LayerModel.parse_obj(bad_layer_dict)
         assert "rasterize_method" in str(e)
Exemple #25
0
 def test_models_bad_source_type(self):
     bad_layer_dict = {**minimal_layer_dict, "source_type": "frog"}
     with self.assertRaises(ValidationError) as e:
         _ = LayerModel.parse_obj(bad_layer_dict)
         assert "source_type" in str(e)
Exemple #26
0
def LAYER():
    layer_def = LayerModel.parse_obj(LAYER_DICT)
    yield layer_factory(layer_def)