def create_process_chain_entry(input_object: DataObject,
                               output_object: DataObject):
    """Create a Actinia command of the process chain

    :param input_object:
    :param vector_object:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "t_rast_algebra_%i" % rn,
        "module":
        "t.rast.algebra",
        "inputs": [
            {
                "param": "expression",
                "value": "%(result)s = 1 * %(input)s" % {
                    "result": output_object.grass_name(),
                    "input": input_object.grass_name()
                }
            },
            {
                "param": "basename",
                "value": "trim"
            },
        ]
    }

    return pc
def create_process_chain_entry(cube1_object: DataObject,
                               cube2_object: DataObject,
                               output_object: DataObject):
    """Create a Actinia command of the process chain

    :param cube1_object:
    :param cube2_object:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # t.merge does not have a method to resolve overlaps

    pc = {
        "id":
        "t_merge_%i" % rn,
        "module":
        "t.merge",
        "inputs": [{
            "param": "inputs",
            "value": "%(cube1)s,%(cube2)s" % {
                "cube1": cube1_object.grass_name(),
                "cube2": cube2_object.grass_name()
            }
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }]
    }

    return pc
예제 #3
0
def create_process_chain_entry(input: DataObject, mask: DataObject,
                               output: DataObject):
    """Create a Actinia process description that uses r.mapcalc
       to apply a mask.

       NOTE: according to multilayer_mask, 0 means not masked, 1 means masked
             this is the other way around compared to GRASS

    :param input: The input map name
    :param mask: The mask map name
    :param output: The name of the output map
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "r_mapcalc_%i" % rn,
        "module":
        "r.mapcalc",
        "inputs": [{
            "param": "expression",
            "value": "%(result)s = if(isnull(%(mask)s) || %(mask)s == 0, "
            "null(), %(raw)s)" % {
                "result": output.grass_name(),
                "raw": input.grass_name(),
                "mask": mask.grass_name()
            }
        }]
    }

    return pc
def create_process_chain_entry(
        output_object: DataObject,
        red_object: DataObject,
        green_object: DataObject,
        blue_object: DataObject) -> list:
    """Actinia process to export an RGB composite GeoTiff

    :param output_object:
    :param red_name:
    :param green_name:
    :param blue_name:
    :return: The process chain
    """

    rn = randint(0, 1000000)
    pc = []

    composite = {
        "id": "composite_%i" % rn,
        "module": "r.composite",
        "inputs": [{"param": "red", "value": red_object.grass_name()},
                   {"param": "green", "value": green_object.grass_name()},
                   {"param": "blue", "value": blue_object.grass_name()}],
        "outputs": [{"export": {"type": "raster", "format": "GTiff"},
                     "param": "output",
                     "value": output_object.grass_name()}]}
    pc.append(composite)

    return pc
def create_process_chain_entry(input_time_series: DataObject,
                               nir_band, red_band,
                               output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.ndvi to create the NDVI time series

    :param input_time_series: The input time series object with red and nir bands
    :param output_time_series: The object of the output time series
    :return: A list of Actinia process chain descriptions
    """
    rn = randint(0, 1000000)

    # TODO: adjust t.rast.ndvi to accept nir band and red band names
    #       pass nir_band and red_band to t.rast.ndvi

    pc = [
        {"id": "t_rast_ndvi_%i" % rn,
         "module": "t.rast.ndvi",
         "inputs": [{"param": "input",
                     "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                    {"param": "basename",
                     "value": "ndvi"},
                    {"param": "output",
                     "value": output_time_series.grass_name()}]},
        {"id": "t_rast_color_%i" % rn,
         "module": "t.rast.colors",
         "inputs": [{"param": "input",
                     "value": output_time_series.grass_name()},
                    {"param": "color",
                     "value": "ndvi"}]}]

    return pc
def create__process_chain_entry(input_object: DataObject, target, source,
                                output_object: DataObject):
    """Create a Actinia command of the process chain that uses
       t.rast.renamebands to rename band names.

    :param input_object: The input strds object
    :param dimension:
    :param target:
    :param source:
    :param output_object: The output strds object
    :return: A Actinia process chain description
    """

    # Get info about the time series to extract its resolution settings and
    # bbox
    rn = randint(0, 1000000)

    # source can be null
    if source:
        pc = {
            "id":
            "t_rast_renamebands_%i" % rn,
            "module":
            "t.rast.renamebands",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "target",
                "value": (',').join(target)
            }, {
                "param": "source",
                "value": (',').join(source)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }
    else:
        pc = {
            "id":
            "t_rast_renamebands_%i" % rn,
            "module":
            "t.rast.renamebands",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "target",
                "value": (',').join(target)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }

    return pc
예제 #7
0
def create__process_chain_entry(input_object: DataObject, start_time: str,
                                end_time: str, output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.extract to create a subset of a strds
       The filter checks whether the temporal dimension value is
       greater than or equal to the lower boundary (start date/time)
       and the temporal dimension value is less than the value of the
       upper boundary (end date/time). This corresponds to a
       left-closed interval, which contains the lower boundary but not
       the upper boundary.

    :param input_object: The input strds object
    :param start_time:
    :param end_time:
    :param output_object: The output strds object
    :return: A Actinia process chain description
    """

    start_time = start_time.replace('T', ' ')
    end_time = end_time.replace('T', ' ')

    # Get info about the time series to extract its resolution settings and
    # bbox
    rn = randint(0, 1000000)

    # end_time can be null, and we can not find out if end_time is set because
    # the input does not exist yet
    pc = {
        "id":
        "t_rast_extract_%i" % rn,
        "module":
        "t.rast.extract",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "where",
            "value": "start_time >= '%(start)s' "
            "AND start_time <= '%(end)s'" % {
                "start": start_time,
                "end": end_time
            }
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }, {
            "param": "expression",
            "value": "1.0 * %s" % input_object.grass_name()
        }, {
            "param": "basename",
            "value": f"{input_object.name}_extract"
        }, {
            "param": "suffix",
            "value": "num"
        }]
    }

    return pc
예제 #8
0
def create_process_chain_entry(input_object: DataObject, method,
                               output_object: DataObject):
    """Create a Actinia process description.

    :param input_object: The input time series name
    :param method: The method for time reduction
    :param output_map: The name of the output raster map
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # TODO: a new GRASS addon that
    # 1. fetches a list of raster maps in a strds
    # 2. resamples each raster map with the selected method

    # translate openeo method to GRASS method
    if method == "near":
        method = "nearest"
    if method == "cubic":
        method = "bicubic"
    if method == "max":
        method = "maximum"
    if method == "min":
        method = "minimum"
    if method == "med":
        method = "median"
    if method == "q1":
        method = "quart1"
    if method == "q3":
        method = "quart3"

    pc = [{
        "id":
        "t_rast_resample_%i" % rn,
        "module":
        "t.rast.resample",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "method",
            "value": method
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }],
    }]

    return pc
예제 #9
0
def create_process_chain_entry(input_object: DataObject, formula, operators,
                               output_object: DataObject):
    """Create a Actinia process description.

    :param input_object: The input time series object
    :param output_object: The output time series or raster object
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # t.rast.mapcalc

    formula = formula.replace('data', input_object.grass_name())

    pc = {
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [
            {
                "param": "expression",
                "value": "%(formula)s" % {
                    "formula": formula
                }
            },
            {
                "param": "input",
                "value": "%(input)s" % {
                    "input": input_object.grass_name()
                }
            },
            {
                "param": "output",
                "value": output_object.grass_name()
            },
            # the basename will always replace any individual
            # raster map names from the input STRDS,
            # but some basename is required.
            {
                "param": "basename",
                "value": output_object.grass_name()
            }
        ]
    }

    return pc
def create_process_chain_entry(input_object: DataObject, vmin: float,
                               vmax: float, output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.mapcalc
    to filter raster values by the specified interval

    :param input_object: The input time series object
    :param min: smallest allowed value
    :param max: largest allowed value
    :param output_object: The output time series object
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [
            {
                "param": "expression",
                "value": "%(result)s = if(%(raw)s < %(min)s || "
                "%(raw)s > %(max)s), null(), %(raw)s)" % {
                    "result": output_object.grass_name(),
                    "raw": input_object.grass_name(),
                    "min": str(vmin),
                    "max": str(vmax)
                }
            },
            {
                "param": "basename",
                "value": output_object.name
            },
            {
                "param": "output",
                "value": output_object.grass_name()
            },
        ]
    }

    return pc
예제 #11
0
def create_process_chain_entry(
        input_object: DataObject,
        method,
        output_object: DataObject):
    """Create a Actinia process description that uses t.rast.series to reduce a time series.

    :param input_object: The input time series object
    :param method: The method for time reduction
    :param output_map: The name of the output raster object
    :return: A Actinia process chain description
    """
    rn = randint(0, 1000000)

    pc = {"id": "t_rast_series_%i" % rn,
          "module": "t.rast.series",
          "inputs": [{"param": "input", "value": input_object.grass_name()},
                     {"param": "method", "value": method},
                     {"param": "output", "value": output_object.grass_name()}],
          "flags": "t"}

    return pc
예제 #12
0
def create_process_chain_entry(
        nir_time_series: DataObject,
        red_time_series: DataObject,
        blue_time_series: DataObject,
        scale: float,
        output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.mapcalc to create the EVI time series

    :param nir_time_series: The NIR band time series name
    :param red_time_series: The RED band time series name
    :param blue_time_series: The BLUE band time series name
    :param scale: scale factor
    :param output_time_series: The name of the output time series
    :return: A list of Actinia process chain descriptions
    """

    rn = randint(0, 1000000)

    pc = [
        {"id": "t_rast_mapcalc_%i" % rn,
         "module": "t.rast.mapcalc",
         "inputs": [{"param": "expression",
                     "value": "%(result)s = float(2.5 * %(scale)s * (%(nir)s - %(red)s)/"
                              "(%(nir)s * %(scale)s + 6.0 * %(red)s * %(scale)s -7.5 * %(blue)s * %(scale)s + 1.0))" % {
                                  "result": output_time_series.grass_name(),
                                  "nir": nir_time_series.grass_name(),
                                  "red": red_time_series.grass_name(),
                                  "blue": blue_time_series.grass_name(),
                                  "scale": scale}},
                    {"param": "inputs",
                     "value": "%(nir)s,%(red)s,%(blue)s" % {"nir": nir_time_series.grass_name(),
                                                            "red": red_time_series.grass_name(),
                                                            "blue": blue_time_series.grass_name()}},
                    {"param": "basename",
                     "value": output_time_series.name},
                    {"param": "output",
                     "value": output_time_series.grass_name()}]},
        {"id": "t_rast_color_%i" % rn,
         "module": "t.rast.colors",
         "inputs": [{"param": "input",
                     "value": output_time_series.grass_name()},
                    {"param": "color",
                     "value": "ndvi"}]}]

    return pc
예제 #13
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "result" not in node.arguments:
        raise Exception("The result name must be specified as parameter")
    if "expression" not in node.arguments:
        raise Exception("The expression must be specified as parameter")
    if "basename" not in node.arguments:
        raise Exception("The basename must be specified as parameter")

    result = DataObject(
        name=node.arguments["result"],
        datatype=GrassDataType.STRDS)

    expression = node.arguments["expression"]
    basename = node.arguments["basename"]

    if "a" in node.arguments:
        a = list(node.get_parent_by_name(parent_name="a").output_objects)[-1]
        expression = expression.replace("$a", a.grass_name())
    if "b" in node.arguments:
        b = list(node.get_parent_by_name(parent_name="b").output_objects)[-1]
        expression = expression.replace("$b", b.grass_name())
    if "c" in node.arguments:
        c = list(node.get_parent_by_name(parent_name="c").output_objects)[-1]
        expression = expression.replace("$c", c.grass_name())
    if "d" in node.arguments:
        d = list(node.get_parent_by_name(parent_name="d").output_objects)[-1]
        expression = expression.replace("$d", d.grass_name())
    if "e" in node.arguments:
        e = list(node.get_parent_by_name(parent_name="e").output_objects)[-1]
        expression = expression.replace("$e", e.grass_name())
    if "f" in node.arguments:
        f = list(node.get_parent_by_name(parent_name="f").output_objects)[-1]
        expression = expression.replace("$f", f.grass_name())

    expression = expression.replace("$result", result.grass_name())

    output_objects.append(result)
    node.add_output(output_object=result)

    pc = create_process_chain_entry(expression=expression, basename=basename)
    process_list.extend(pc)

    return output_objects, process_list
def create_process_chain_entry(band1_time_series: DataObject,
                               band2_time_series: DataObject,
                               output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.mapcalc to create the normalized difference time series

    :param band1_time_series: The first band time series object
    :param band2_time_series: The second band time series object
    :param output_time_series: The object of the output time series
    :return: A list of Actinia process chain descriptions
    """

    rn = randint(0, 1000000)

    pc = [{
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [{
            "param": "expression",
            "value": "%(result)s = float((%(band1)s - %(band2)s)/"
            "(%(band1)s + %(band2)s))" % {
                "result": output_time_series.grass_name(),
                "band1": band1_time_series.grass_name(),
                "band2": band2_time_series.grass_name()
            }
        }, {
            "param": "inputs",
            "value": "%(band1)s,%(band2)s" % {
                "band1": band1_time_series.grass_name(),
                "band2": band2_time_series.grass_name()
            }
        }, {
            "param": "basename",
            "value": "nd"
        }, {
            "param": "output",
            "value": output_time_series.grass_name()
        }]
    }, {
        "id":
        "t_rast_color_%i" % rn,
        "module":
        "t.rast.colors",
        "inputs": [{
            "param": "input",
            "value": output_time_series.grass_name()
        }, {
            "param": "color",
            "value": "ndvi"
        }]
    }]

    return pc
예제 #15
0
def create_process_chain_entry(input_object: DataObject, percentile,
                               output_object: DataObject):
    """Create a Actinia process description that uses t.rast.series to reduce a time series.

    :param input_time_series: The input time series object
    :param percentile: The percentile to use for time reduction
    :param output_map: The object of the output raster map
    :return: A Actinia process chain description
    """
    rn = randint(0, 1000000)

    quantile = float(percentile) / 100.0

    pc = {
        "id":
        "t_rast_series_%i" % rn,
        "module":
        "t.rast.series",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "method",
            "value": "quantile"
        }, {
            "param": "quantile",
            "value": quantile
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }],
        "flags":
        "t"
    }

    return pc
예제 #16
0
def create_process_chain_entry(input_time_series: DataObject,
                               bands, wavelengths,
                               output_time_series: DataObject):
    """Create a Actinia command of the process chain that uses g.region to create a valid computational region
    for the provide input strds

    :param north:
    :param south:
    :param east:
    :param west:
    :param crs:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # convert wavelengths to a string
    wvstring = None
    pc = None
    if wavelengths and bands:
        wvstring = (',').join(wavelengths)

        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "wavelengths",
                          "value": "%(wavelengths)s" % {"wavelengths": wvstring}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}
    elif bands:
        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}
    elif wavelengths:
        wvstring = (',').join(wavelengths)
        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}

    return pc
def create_process_chain_entry(data_object: DataObject) -> dict:
    """Create a Actinia command of the process chain that uses g.region to create a valid computational region
    for the provide input strds

    :param data_object: Input raster map data object
    :return: A Actinia process chain description
    """
    rn = randint(0, 1000000)

    pc = {
        "id": "g_region_%i" % rn,
        "module": "g.region",
        "inputs": [{
            "param": "raster",
            "value": str(data_object.grass_name())
        }],
        "flags": "p"
    }

    return pc
예제 #18
0
def create_process_chain_entry(data_object: DataObject):
    """Create a Actinia command of the process chain that computes the regional statistics based on a
    strds and a polygon.

    :param data_object: The name of the raster layer
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)
    pc = []

    exporter = {
        "id": "exporter_%i" % rn,
        "module": "exporter",
        "outputs": [{"export": {"type": "raster", "format": "GTiff"},
                     "param": "map",
                     "value": data_object.grass_name()}]}

    pc.append(exporter)

    return pc
def create_process_chain_entry(input_object: DataObject, options: dict):
    """Create a Actinia command of the process chain that computes the regional statistics based on a
    strds and a polygon.

    :param input_object: The name of the raster layer
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)
    pc = []

    output_format = "GTiff"
    if input_object.is_vector():
        output_format = "GML"

    # the actinia exporter currently does not support GDAL creation options
    # parameter options is ignored
    options_list = list()
    for key in options:
        optstr = ("%s=%s" % (key, options[key]))
        options_list.append(optstr)

    exporter = {
        "id":
        "save_result_%i" % rn,
        "module":
        "exporter",
        "outputs": [{
            "export": {
                "type": input_object.datatype.value,
                "format": output_format
            },
            "param": "map",
            "value": input_object.grass_name()
        }]
    }

    pc.append(exporter)

    return pc
예제 #20
0
def create_process_chain_entry(input_object: DataObject,
                               spatial_extent,
                               temporal_extent,
                               bands,
                               output_object: DataObject):
    """Create a Actinia process description that r.info, v.info, or t.info.

    :param input_object: The input object name
    :param spatial_extent: spatial filter
    :param temporal_extent: temporal filter
    :param bands: bands to extract
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = []

    if input_object.is_raster():
        importer = {"id": "r_info_%i" % rn, "module": "r.info", "inputs": [
            {"param": "map", "value": input_object.grass_name()}, ],
            "flags": "g"}

    elif input_object.is_vector():
        importer = {"id": "v_info_%i" % rn, "module": "v.info", "inputs": [
            {"param": "map", "value": input_object.grass_name()}, ],
            "flags": "g"}

    elif input_object.is_strds():
        importer = {"id": "t_info_%i" % rn, "module": "t.info", "inputs": [
            {"param": "input", "value": input_object.grass_name()}, ],
            "flags": "g"}

    elif input_object.is_stac():
        instance_id = input_object.mapset
        collection_id = f"stac.{instance_id}.rastercube.{input_object.name}"
        strds_name = (output_object.grass_name()).replace('@', '_')
        # Define the import process of the STAC collection
        stac_input_importer = {
                    "import_descr": {
                        "source": collection_id,
                        "type": "stac"
                    },
                    "param": "map",
                    "value": strds_name
                }
        param_import = _get_stac_importer(stac_input_importer, spatial_extent,
                                          temporal_extent, bands, rn)
        stac_importchain = {
                "id": "importer_1",
                "module": "importer",
                "inputs": [param_import]
            }

        pc.append(stac_importchain)

        importer = {"id": "t_info_%i" % rn, "module": "t.info", "inputs": [
            {"param": "input", "value": strds_name}, ],
            "flags": "g"}
    else:
        raise Exception("Unsupported datatype")

    pc.append(importer)

    # TODO: spatial extent can also be a GeoJSON object
    if spatial_extent is not None:
        north = spatial_extent["north"]
        south = spatial_extent["south"]
        west = spatial_extent["west"]
        east = spatial_extent["east"]
        if "crs" in spatial_extent:
            crs = str(spatial_extent["crs"])
        else:
            crs = "4326"

        if crs.isnumeric():
            crs = "EPSG:" + crs

        if input_object.is_raster():
            region_bbox = {
                "id": "g_region_bbox_%i" %
                rn, "module": "g.region.bbox", "inputs": [
                    {
                        "param": "n", "value": str(north)}, {
                        "param": "s", "value": str(south)}, {
                        "param": "e", "value": str(east)}, {
                        "param": "w", "value": str(west)}, {
                        "param": "crs", "value": str(crs)}, {
                        "param": "raster", "value": input_object.grass_name()},
                    ]}
        elif input_object.is_strds() or input_object.is_stac():
            region_bbox = {
                "id": "g_region_bbox_%i" %
                rn, "module": "g.region.bbox", "inputs": [
                    {
                        "param": "n", "value": str(north)}, {
                        "param": "s", "value": str(south)}, {
                        "param": "e", "value": str(east)}, {
                        "param": "w", "value": str(west)}, {
                        "param": "crs", "value": str(crs)}, {
                        "param": "strds", "value": input_object.grass_name()},
                        ]
                    }
        else:
            region_bbox = {"id": "g_region_bbox_%i" % rn,
                           "module": "g.region.bbox",
                           "inputs": [{"param": "n", "value": str(north)},
                                      {"param": "s", "value": str(south)},
                                      {"param": "e", "value": str(east)},
                                      {"param": "w", "value": str(west)},
                                      {"param": "crs", "value": str(crs)}, ]}

        pc.append(region_bbox)

    if input_object.is_strds() and \
       (temporal_extent is not None or bands is not None):
        wherestring = ""
        if temporal_extent:
            start_time = temporal_extent[0].replace('T', ' ')
            if len(temporal_extent) > 1:
                end_time = temporal_extent[1].replace('T', ' ')
                wherestring = "start_time >= '%(start)s' AND start_time < '%(end)s'" % {
                                                "start": start_time, "end": end_time}
            # end_time can be null, use only start_time for filtering
            else:
                wherestring = "start_time >= '%(start)s'" % {"start": start_time}
            if bands:
                wherestring = wherestring + " AND "
        if bands:
            wherestring = wherestring + \
                "semantic_label in ('%(band_names)s')" % {"band_names": ("', '").join(bands)}

        pc_strdsfilter = {
            "id": "t_rast_extract_%i" % rn,
            "module": "t.rast.extract",
            "inputs": [{"param": "input",
                        "value": input_object.grass_name()},
                       {"param": "where",
                        "value": wherestring},
                       {"param": "output",
                        "value": output_object.grass_name()},
                       {"param": "expression",
                        "value": "1.0 * %s" % input_object.name},
                       {"param": "basename",
                        "value": output_object.name},
                       {"param": "suffix",
                        "value": "num"}]}

        pc.append(pc_strdsfilter)

    return pc
예제 #21
0
def create_process_chain_entry(data_object: DataObject,
                               output_object: DataObject):
    """Create a Actinia process description that uses t.rast.series
       and r.mapcalc to create a multilayer mask.

    :param data_object: The input time series object
    :param output_object: The name of the output raster map
    :return: A Actinia process chain description
    """

    output_temp_object = DataObject(name=f"{output_object.name}_temp",
                                    datatype=GrassDataType.RASTER)

    # get number of maps in input_time_series
    iface = ActiniaInterface()
    # this is not working because the input object might not yet exist
    status_code, layer_data = iface.layer_info(
        layer_name=data_object.grass_name())
    if status_code != 200:
        return make_response(
            jsonify(
                {
                    "description":
                    "An internal error occurred "
                    "while catching GRASS GIS layer information "
                    "for layer <%s>!\n Error: %s"
                    "" % (data_object, str(layer_data))
                }, 400))
    nmaps = layer_data['number_of_maps']

    rn = randint(0, 1000000)

    pc = [{
        "id":
        "t_rast_series_%i" % rn,
        "module":
        "t.rast.series",
        "inputs": [{
            "param": "input",
            "value": data_object.grass_name()
        }, {
            "param": "method",
            "value": "count"
        }, {
            "param": "output",
            "value": output_temp_object.grass_name()
        }],
        "flags":
        "t"
    }, {
        "id":
        "r_mapcalc_%i" % rn,
        "module":
        "r.mapcalc",
        "inputs": [{
            "param": "expression",
            "value": "%(result)s = int(if(%(raw)s < %(nmaps)s, 1, 0))" % {
                "result": output_object.grass_name(),
                "raw": output_temp_object.grass_name(),
                "nmaps": str(nmaps)
            }
        }],
    }]
    # g.remove raster name=output_name_tmp -f ?

    return pc
def create_process_chain_entry(input_object: DataObject, polygons: str):
    """Create a Actinia command of the process chain that computes the regional statistics based on a
    strds and a polygon.

    The computational region will be set to the vector map, the previous region will be saved and after processing
    restored. A mask will be set that uses the vector file as input. This mask will be removed in the end.

    :param input_object: The name of the strds
    :param polygons: The URL to the vector file that defines the regions of interest
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)
    pc = []

    importer = {
        "id":
        "importer_%i" % rn,
        "module":
        "importer",
        "inputs": [{
            "import_descr": {
                "source": polygons,
                "type": "vector"
            },
            "param": "map",
            "value": "polygon"
        }]
    }

    g_region_1 = {
        "id": "g_region_1_%i" % rn,
        "module": "g.region",
        "inputs": [{
            "param": "save",
            "value": "previous_region"
        }],
        "flags": "g"
    }

    g_region_2 = {
        "id": "g_region_2_%i" % rn,
        "module": "g.region",
        "inputs": [{
            "param": "vector",
            "value": "polygon"
        }],
        "flags": "g"
    }

    r_mask_1 = {
        "id": "r_mask_1_%i" % rn,
        "module": "r.mask",
        "inputs": [{
            "param": "vector",
            "value": "polygon"
        }]
    }

    t_rast_univar = {
        "id": "t_rast_univar_%i" % rn,
        "module": "t.rast.univar",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }]
    }

    r_mask_2 = {"id": "r_mask_2_%i" % rn, "module": "r.mask", "flags": "r"}

    g_region_3 = {
        "id": "g_region_3_%i" % rn,
        "module": "g.region",
        "inputs": [{
            "param": "region",
            "value": "previous_region"
        }],
        "flags": "g"
    }

    pc.append(importer)
    pc.append(g_region_1)
    pc.append(g_region_2)
    pc.append(r_mask_1)
    pc.append(t_rast_univar)
    pc.append(r_mask_2)
    pc.append(g_region_3)

    return pc
def create_process_chain_entry(input_object: DataObject, vector_object,
                               output_object: DataObject):
    """Create a Actinia command of the process chain

    :param input_object:
    :param vector_object:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = [{
        "id":
        "v_in_geojson_%i" % rn,
        "module":
        "v.in.geojson",
        "inputs": [
            {
                "param": "input",
                "value": vector_object
            },
            {
                "param": "output",
                "value": "geojson_mask"
            },
        ]
    }, {
        "id":
        "v_to_rast_%i" % rn,
        "module":
        "v.to.rast",
        "inputs": [
            {
                "param": "input",
                "value": "geojson_mask"
            },
            {
                "param": "output",
                "value": "MASK"
            },
            {
                "param": "type",
                "value": "point,line,area"
            },
            {
                "param": "use",
                "value": "val"
            },
        ]
    }, {
        "id":
        "t_rast_algebra_%i" % rn,
        "module":
        "t.rast.algebra",
        "inputs": [
            {
                "param": "expression",
                "value": "%(result)s = 1 * %(input)s" % {
                    "result": output_object.grass_name(),
                    "input": input_object.grass_name()
                }
            },
            {
                "param": "basename",
                "value": output_object.name
            },
        ]
    }, {
        "id": "r_mask_%i" % rn,
        "module": "r_mask",
        "inputs": {
            "flags": "r"
        }
    }]

    return pc
def create__process_chain_entry(input_object: DataObject, target, source,
                                output_object: DataObject):
    """Create a Actinia command of the process chain that uses
       t.rast.renamebands to rename band names.

    :param input_object: The input strds object
    :param dimension:
    :param target:
    :param source:
    :param output_object: The output strds object
    :return: A Actinia process chain description
    """

    # Get info about the time series to extract its resolution settings and
    # bbox
    rn = randint(0, 1000000)

    # TODO: do not create a new STRDS
    #       only update labels in the input STRDS ?

    pc = []
    # source can be null
    if source:
        p = {
            "id":
            "t_rast_renamelabels_%i" % rn,
            "module":
            "t.rast.renamelabels",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "new",
                "value": (',').join(target)
            }, {
                "param": "old",
                "value": (',').join(source)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }
    else:
        p = {
            "id":
            "t_rast_renamelabels_%i" % rn,
            "module":
            "t.rast.renamelabels",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "new",
                "value": (',').join(target)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }

    pc.append(p)

    p = {
        "id":
        "t_info_%i" % rn,
        "module":
        "t.info",
        "inputs": [{
            "param": "input",
            "value": output_object.grass_name()
        }, {
            "param": "type",
            "value": "strds"
        }],
        "flags":
        'g'
    }

    pc.append(p)

    return pc
def create_process_chain_entry(input_object: DataObject,
                               mask_object: DataObject, mask_value,
                               output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.mapcalc
    to mask raster values based on a mask dataset and a replacement value

    :param input_object: The input time series name
    :param mask_object: time series to use as mask
    :param mask_value: values in input are replaced with this value if mask is not null
    :param output_object: The output time series name
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    if mask_value == "null":
        pc = {
            "id":
            "t_rast_mapcalc_%i" % rn,
            "module":
            "t.rast.mapcalc",
            "inputs": [
                {
                    "param": "expression",
                    "value": "if(isnull(%(mask_name)s), "
                    "%(raw)s, null())" % {
                        "mask_name": mask_object.grass_name(),
                        "raw": input_object.grass_name()
                    }
                },
                {
                    "param": "input",
                    "value": "%(input)s" % {
                        "input": input_object.grass_name()
                    }
                },
                {
                    "param": "basename",
                    "value": output_object.grass_name()
                },
                {
                    "param": "output",
                    "value": output_object.grass_name()
                },
            ]
        }
    else:
        pc = {
            "id":
            "t_rast_mapcalc_%i" % rn,
            "module":
            "t.rast.mapcalc",
            "inputs": [
                {
                    "param": "expression",
                    "value": "if(isnull(%(mask_name)s), "
                    "%(raw)s, %(mask_value)s)" % {
                        "mask_name": mask_object.grass_name(),
                        "raw": input_object.grass_name(),
                        "mask_value": mask_value
                    }
                },
                {
                    "param": "input",
                    "value": "%(input)s" % {
                        "input": input_object.grass_name()
                    }
                },
                {
                    "param": "basename",
                    "value": output_object.grass_name()
                },
                {
                    "param": "output",
                    "value": output_object.grass_name()
                },
            ]
        }

    return pc
예제 #26
0
def create_process_chain_entry(input_time_series: DataObject,
                               nir_band, red_band, target_band,
                               output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.ndvi to create the NDVI time series

    :param input_time_series: The input time series object with red and nir bands
    :param output_time_series: The object of the output time series
    :return: A list of Actinia process chain descriptions
    """
    rn = randint(0, 1000000)

    if target_band is not None:
        pc = [
            {"id": "t_rast_ndvi_%i" % rn,
             "module": "t.rast.ndvi",
             "inputs": [{"param": "input",
                         "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                        {"param": "red",
                         "value": red_band},
                        {"param": "nir",
                         "value": nir_band},
                        {"param": "target",
                         "value": target_band},
                        {"param": "basename",
                         "value": output_time_series.name},
                        {"param": "output",
                         "value": output_time_series.grass_name()}]}]
    else:
        pc = [
            {"id": "t_rast_ndvi_%i" % rn,
             "module": "t.rast.ndvi",
             "inputs": [{"param": "input",
                         "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                        {"param": "red",
                         "value": red_band},
                        {"param": "nir",
                         "value": nir_band},
                        {"param": "basename",
                         "value": output_time_series.name},
                        {"param": "output",
                         "value": output_time_series.grass_name()}]},
            {"id": "t_rast_color_%i" % rn,
             "module": "t.rast.colors",
             "inputs": [{"param": "input",
                         "value": output_time_series.grass_name()},
                        {"param": "color",
                         "value": "ndvi"}]}]

    if target_band is not None:
        p = {"id": "t_info_%i" % rn,
             "module": "t.info",
             "inputs": [{"param": "input", "value": input_time_series.grass_name()},
                        {"param": "type", "value": "strds"}],
             "flags": 'g'}
    else:
        p = {"id": "t_info_%i" % rn,
             "module": "t.info",
             "inputs": [{"param": "input", "value": output_time_series.grass_name()},
                        {"param": "type", "value": "strds"}],
             "flags": 'g'}

    pc.append(p)

    return pc
def create_process_chain_entry(input_object: DataObject, vector_object,
                               mask_value, inside, output_object: DataObject):
    """Create a Actinia command of the process chain

    :param input_object:
    :param vector_object:
    :return: A Actinia process chain description
    """

    # TODO: support geojson as input

    rn = randint(0, 1000000)
    pc = []

    importer = {
        "id":
        "v_in_geojson_%i" % rn,
        "module":
        "v.in.geojson",
        "inputs": [
            {
                "param": "input",
                "value": vector_object
            },
            {
                "param": "output",
                "value": "geojson_mask"
            },
        ]
    }

    if inside is False:
        create_mask = {
            "id":
            "v_to_rast_%i" % rn,
            "module":
            "v.to.rast",
            "inputs": [
                {
                    "param": "input",
                    "value": "geojson_mask"
                },
                {
                    "param": "output",
                    "value": "polymask"
                },
                {
                    "param": "type",
                    "value": "area"
                },
                {
                    "param": "use",
                    "value": "val"
                },
            ]
        }
    else:
        create_mask = [{
            "id":
            "v_to_rast_%i" % rn,
            "module":
            "v.to.rast",
            "inputs": [
                {
                    "param": "input",
                    "value": "geojson_mask"
                },
                {
                    "param": "output",
                    "value": "polymask_inv"
                },
                {
                    "param": "type",
                    "value": "area"
                },
                {
                    "param": "use",
                    "value": "val"
                },
            ]
        }, {
            "id":
            "r:mapcalc_%i" % rn,
            "module":
            "r.mapcalc",
            "inputs": [{
                "param":
                "expression",
                "value":
                "polymask = if(isnull(polymask_inv), 1, null())"
            }]
        }]

    # replace all pixels where mask is null
    if mask_value == "null":
        do_mask = {
            "id":
            "t_rast_mapcalc_%i" % rn,
            "module":
            "t.rast.mapcalc",
            "inputs": [
                {
                    "param": "expression",
                    "value": "%(result)s = if(isnull(%(mask_name)s), "
                    "%(raw)s, null())" % {
                        "result": output_object.grass_name(),
                        "mask_name": "polymask",
                        "raw": input_object.grass_name()
                    }
                },
                {
                    "param": "basename",
                    "value": "masked"
                },
                {
                    "param": "output",
                    "value": output_object.grass_name()
                },
            ]
        }
    else:
        do_mask = {
            "id":
            "t_rast_mapcalc_%i" % rn,
            "module":
            "t.rast.mapcalc",
            "inputs": [
                {
                    "param": "expression",
                    "value": "%(result)s = if(isnull(%(mask_name)s), "
                    "%(raw)s, %(mask_value)s)" % {
                        "result": output_object.grass_name(),
                        "mask_name": "polymask",
                        "raw": input_object.grass_name(),
                        "mask_value": mask_value
                    }
                },
                {
                    "param": "basename",
                    "value": "masked"
                },
                {
                    "param": "output",
                    "value": output_object.grass_name()
                },
            ]
        }

    pc.append(importer)
    pc.append(create_mask)
    pc.append(do_mask)

    return pc
예제 #28
0
def create_process_chain_entry(input_object: DataObject, dimtype, formula,
                               operators, output_object: DataObject):
    """Create a Actinia process description.

    :param input_object: The input time series object
    :param dimension: dimension to reduce
    :param output_object: The output time series or raster object
    :return: A Actinia process chain description
    """

    # dimension is the name of the dimension. The name is arbitrary.
    # Need to check the dimension name and get its type.
    # Supported dimension types are "temporal" and "bands".
    # Dimension type "spatial" should also be supported.
    # We can not check dimension names of the input object here
    # because the input object does not exist yet.
    # Use a new GRASS addon t.rast.reduce ?
    # There are no dimension names in GRASS, only dimension types
    # -> deadlock: dimension names are openeo specific
    #              we need the openeo object to get the dimension type
    #              from the dimension name
    #              BUT the openeo object does not exist yet
    # implement openeo / STAC like dimensions in GRASS ?

    rn = randint(0, 1000000)
    pc = []

    if dimtype == 'temporal':
        # t.rast.series

        # exactly one function: map openeo function to r.series method

        method = operators[0]
        if method == "mean":
            method = "average"
        elif method == "count":
            method = "count"
        elif method == "median":
            method = "median"
        elif method == "min":
            method = "minimum"
        elif method == "max":
            method = "maximum"
        elif method == "sd":
            method = "stddev"
        elif method == "sum":
            method = "sum"
        elif "variance" in formula:
            method = "variance"
        else:
            raise Exception('Unsupported method <%s> for temporal reduction.' %
                            (method))

        # TODO: quantiles with openeo options probabilites
        # (list of values between 0 and 1)
        # q as number of intervals to calculate quantiles for

        series = {
            "id":
            "t_rast_series_%i" % rn,
            "module":
            "t.rast.series",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "method",
                "value": method
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }],
            "flags":
            "t"
        }
        pc.append(series)
        r2strds = {
            "id":
            "t_rast2strds_%i" % rn,
            "module":
            "t.rast2strds",
            "inputs": [{
                "param": "strds",
                "value": input_object.grass_name()
            }, {
                "param": "raster",
                "value": output_object.grass_name()
            }, {
                "param": "bandname",
                "value": method
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }
        pc.append(r2strds)

    elif dimtype == 'bands':
        # t.rast.mapcalc

        # t.rast.bandcalc needs the formula and translates
        # "data[<index>]" to appropriate band references
        # with <index> being a number, 0 for first band
        # the order of bands is obtained from g.bands

        pc = [{
            "id":
            "t_rast_bandcalc_%i" % rn,
            "module":
            "t.rast.bandcalc",
            "inputs": [{
                "param": "expression",
                "value": "%(formula)s" % {
                    "formula": formula
                }
            }, {
                "param": "input",
                "value": "%(input)s" % {
                    "input": input_object.grass_name()
                }
            }, {
                "param": "basename",
                "value": output_object.name
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }]

    return pc
예제 #29
0
def create_process_chain_entry(input_object: DataObject,
                               mask_object: DataObject, mask_value: str,
                               output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.mapcalc
    to mask raster values based on a mask dataset and a replacement value

    :param input_object: The input time series name
    :param mask_object: time series to use as mask
    :param mask_value: values in input are replaced with this value if mask is not null
    :param output_object: The output time series name
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    if mask_value == "null":
        mask_value = "null()"

    pc = []

    p = {
        "id":
        "t_rast_mask_%i" % rn,
        "module":
        "t.rast.mask",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "mask",
            "value": mask_object.grass_name()
        }, {
            "param": "basename",
            "value": output_object.name
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }, {
            "param": "value",
            "value": mask_value
        }],
        "flags":
        "i"
    }

    pc.append(p)

    p = {
        "id":
        "t_info_%i" % rn,
        "module":
        "t.info",
        "inputs": [{
            "param": "input",
            "value": output_object.grass_name()
        }, {
            "param": "type",
            "value": "strds"
        }],
        "flags":
        'g'
    }

    pc.append(p)

    return pc