Skip to content

Commit

Permalink
fix mask_polygon (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
metzm authored Dec 9, 2022
1 parent 9f26b9f commit e668545
Showing 1 changed file with 147 additions and 105 deletions.
252 changes: 147 additions & 105 deletions src/openeo_grass_gis_driver/actinia_processing/mask_polygon_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
import json
from random import randint

from openeo_grass_gis_driver.actinia_processing.base import \
check_node_parents, DataObject, GrassDataType, \
create_output_name
from openeo_grass_gis_driver.models.process_graph_schemas import \
ProcessGraphNode, ProcessGraph
from openeo_grass_gis_driver.models.process_schemas import \
Parameter, ProcessDescription, ReturnValue, ProcessExample
from openeo_grass_gis_driver.actinia_processing.base import (
check_node_parents,
DataObject,
GrassDataType,
create_output_name,
)
from openeo_grass_gis_driver.models.process_graph_schemas import (
ProcessGraphNode,
ProcessGraph,
)
from openeo_grass_gis_driver.models.process_schemas import (
Parameter,
ProcessDescription,
ReturnValue,
ProcessExample,
)
from .base import PROCESS_DICT, PROCESS_DESCRIPTION_DICT, Node

__license__ = "Apache License, Version 2.0"
Expand All @@ -24,54 +33,53 @@ def create_process_description():
p_data = Parameter(
description="Any openEO process object that returns raster datasets "
"or space-time raster dataset",
schema={"type": "object", "subtype": "raster-cube"},
optional=False,
)
p_poly = Parameter(
description="One or more polygons used for filtering",
schema={
"type": "object",
"subtype": "raster-cube"},
optional=False)
p_poly = Parameter(description="One or more polygons used for filtering",
schema={"anyOf": [
{
"type": "object",
"subtype": "geojson"
},
{
"type": "object",
"subtype": "vector-cube"
}]},
optional=False)
"anyOf": [
{"type": "object", "subtype": "geojson"},
{"type": "object", "subtype": "vector-cube"},
]
},
optional=False,
)
p_value = Parameter(
description="The value used to replace non-zero and `true` values with",
schema={
"type": "object",
"subtype": "string"},
optional=True)
schema={"type": "object", "subtype": "string"},
optional=True,
)
p_inside = Parameter(
description="If set to `true` all pixels for which the point at the pixel center "
"**does** intersect with any polygon are replaced",
schema={
"type": "boolean"},
optional=True)
schema={"type": "boolean"},
optional=True,
)

rv = ReturnValue(description="Processed EO data.",
schema={"type": "object", "subtype": "raster-cube"})
rv = ReturnValue(
description="Processed EO data.",
schema={"type": "object", "subtype": "raster-cube"},
)

# Example
arguments = {
"data": {"from_node": "get_data_1"},
"mask": "some geojson",
"replacement": "null",
"replacement": "null",
}
node = ProcessGraphNode(process_id=PROCESS_NAME, arguments=arguments)
graph = ProcessGraph(
title="title",
description="description",
process_graph={
"filter_polygon_1": node})
process_graph={"filter_polygon_1": node},
)
examples = [
ProcessExample(
title="Simple example",
description="Simple example",
process_graph=graph)]
title="Simple example", description="Simple example", process_graph=graph
)
]

pd = ProcessDescription(
id=PROCESS_NAME,
Expand All @@ -83,18 +91,25 @@ def create_process_description():
"data": p_data,
"mask": p_poly,
"replacement": p_value,
"inside": p_inside},
"inside": p_inside,
},
returns=rv,
examples=examples)
examples=examples,
)

return json.loads(pd.to_json())


PROCESS_DESCRIPTION_DICT[PROCESS_NAME] = create_process_description()


def create_process_chain_entry(input_object: DataObject, vector_object,
mask_value, inside, output_object: DataObject):
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:
Expand All @@ -107,68 +122,96 @@ def create_process_chain_entry(input_object: DataObject, vector_object,
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())"}
]}]
importer = {
"id": "v_in_geojson_%i" % rn,
"module": "v.in.geojson",
"inputs": [
{"param": "input", "value": json.dumps(vector_object)},
{"param": "output", "value": "geojson_mask"},
],
}

mask_dict = {
"id": "r_mask_%i" % rn,
"module": "r.mask",
"inputs": [{"param": "raster", "value": "polymask"}],
}
if inside is True:
mask_dict["flags"] = "i"

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"},
],
},
mask_dict,
]

# 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": output_object.name},
{"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": output_object.grass_name()},
{"param": "output",
"value": output_object.grass_name()},
]}
if mask_value is None or mask_value == "null":
mask_value = "null()"

do_mask = {
"id": "t_rast_mapcalc_%i" % rn,
"module": "t.rast.mapcalc",
"inputs": [
{
"param": "expression",
"value": "%(result)s = if(isnull(%(inmap)s), %(maskval)s, %(inmap)s)"
% {
"result": output_object.name,
"inmap": input_object.grass_name(),
"maskval": str(mask_value),
},
},
{"param": "inputs", "value": input_object.grass_name()},
{"param": "basename", "value": output_object.name},
{"param": "output", "value": output_object.name},
],
}

remove_maps = [
{
"id": "g_remove_rast_%i" % rn,
"module": "g.remove",
"inputs": [
{"param": "type", "value": "raster"},
{"param": "name", "value": "MASK,polymask"},
],
"flags": "f",
},
{
"id": "g_remove_vect_%i" % rn,
"module": "g.remove",
"inputs": [
{"param": "type", "value": "vector"},
{"param": "name", "value": "geojson_mask"},
],
"flags": "f",
},
]

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

pc.append(importer)
pc.append(create_mask)
pc.extend(create_mask)
pc.append(do_mask)
pc.extend(remove_maps)
pc.append(output_info)

return pc

Expand All @@ -183,11 +226,8 @@ def get_process_list(node: Node):
input_objects, process_list = check_node_parents(node=node)
output_objects = []

if "data" not in node.arguments or \
"mask" not in node.arguments:
raise Exception(
"Process %s requires parameter data, polygons" %
PROCESS_NAME)
if "data" not in node.arguments or "mask" not in node.arguments:
raise Exception("Process %s requires parameter data, polygons" % PROCESS_NAME)

if "replacement" in node.arguments:
mask_value = node.arguments["replacement"]
Expand All @@ -208,12 +248,14 @@ def get_process_list(node: Node):
input_object = list(input_objects)[-1]

output_object = DataObject(
name=create_output_name(input_object.name, node),
datatype=GrassDataType.STRDS)
name=create_output_name(input_object.name, node), datatype=GrassDataType.STRDS
)
output_objects.append(output_object)
node.add_output(output_object=output_object)

pc = create_process_chain_entry(
input_object, vector_object, mask_value, inside, output_object)
input_object, vector_object, mask_value, inside, output_object
)
process_list.extend(pc)

return output_objects, process_list
Expand Down

0 comments on commit e668545

Please sign in to comment.