WorkflowSelection

WorkflowSelection connectors allow for Extend Python Scripts to accept lists of Maptek Database Objects from input connectors and to write lists of Maptek Database Objects to output connectors.

A Maptek Database Object is an object stored in the Data Explorer of a Maptek Application.

WorkflowSelection input connectors

You can set a workflow component’s input connector type to WorkflowSelection using an Extend Python Script. If you do, you will need to provide a selection of Maptek Database Objects using another component such as the Get Active Selection component. In the example below, the workflow component created accepts a selection of Maptek Database Objects and reports the number of objects of each type in that selection.

import collections
 
from mapteksdk.project import Project
from mapteksdk.pointstudio.operations import write_report
from mapteksdk.workflows import WorkflowArgumentParser, WorkflowSelection
 
parser = WorkflowArgumentParser()
parser.declare_input_connector("selection", WorkflowSelection)
parser.parse_arguments()
 
project = Project()
 
type_counter = collections.Counter()
type_counter.update([oid.type_name for oid in parser["selection"]])
lines = [f"* {key} : {value}" for key, value in type_counter.items()]
 
write_report("Selected object types", "\n".join(lines))

The workflow component created by the Extend Python Script above has been incorporated into a workflow, which can be downloaded here. You can see a screenshot of it below:

WorkflowSelection output connectors

You can also set the connector type of output connectors of workflow components to WorkflowSelection using an Extend Python Script. That means that Extend Python scripts can be used to generate a component which produces a Maptek Database Object. You can pass this object to other workflow components for further processing.

In the example below, we generate a PointSet containing normally distributed points based on the input parameters. By setting the output connector’s type to WorkflowSelection, we can pass this PointSet to upcoming workflow components.

import numpy
from mapteksdk.project import Project
from mapteksdk.data import PointSet
from mapteksdk.workflows import (WorkflowArgumentParser, WorkflowSelection,
                                 Point3DConnectorType, StringConnectorType,
                                 IntegerConnectorType)
 
parser = WorkflowArgumentParser(
  description="Generate a random point set.")
parser.declare_input_connector(
  "path",
  StringConnectorType,
  connector_name="Path",
  description="Path the pointset will be placed at.")
parser.declare_input_connector(
  "centroid",
  Point3DConnectorType,
  connector_name="Centroid",
  description="Centroid of the random pointset.",
  default=[0, 0, 0])
# Use a point to represent the standard deviation in each dimension.
parser.declare_input_connector(
  "sigma",
  Point3DConnectorType,
  connector_name="Sigma",
  description="Standard deviation for each dimension",
  default=[1, 1, 1])
parser.declare_input_connector(
  "count",
  IntegerConnectorType,
  connector_name="Count",
  description="Number of points to generate",
  default=1000)
 
parser.declare_output_connector(
  "selection",
  WorkflowSelection)
 
parser.parse_arguments()
 
path = parser["path"]
mean = parser["centroid"]
sigma = parser["sigma"]
count = parser["count"]
 
project = Project()
 
rng = numpy.random.default_rng()
points = rng.normal(mean, sigma, (count, 3))
 
with project.new(path, PointSet) as pointset:
  pointset.points = points
 
parser.set_output("selection", [pointset.id])

The workflow component created by the Extend Python Script above has been incorporated into a workflow, which can be downloaded here. You can see a screenshot of it below:

Passing selection to another component

So far we’ve discussed:

  • How to select a Maptek Database Object and process it (by setting the component’s input connector type to WorkflowSelection).

  • How to generate a Maptek Database Object which is selected on creation using a workflow component and pass it to another component (by setting the component’s output connector type to WorkflowSelection).

But what if you wanted to do a bit of both? What if you wanted to pass a selected object from one component to another? In this scenario you would set both the input connector type and the output connector type of an Extend Python Script component to WorkflowSelection.

Here is a script where the input connector type and output connector type have been both set to WorkflowSelection so that the next component can process the selected Maptek Database Object.

Note:  The input connector and output connector have the same connector name. This is encouraged when you want to match the output connector by name when configuring the connector in the Workflow Editor.

import collections
 
from mapteksdk.project import Project
from mapteksdk.pointstudio.operations import write_report
from mapteksdk.workflows import WorkflowArgumentParser, WorkflowSelection
 
parser = WorkflowArgumentParser()

# Input and output connectors can have the same name.
parser.declare_input_connector("selection", WorkflowSelection)
parser.declare_output_connector("selection", WorkflowSelection)
parser.parse_arguments()
 
project = Project()
 
type_counter = collections.Counter()
type_counter.update([oid.type_name for oid in parser["selection"]])
lines = [f"* {key} : {value}" for key, value in type_counter.items()]
 
write_report("Selected object types", "\n".join(lines))
 
parser.set_output("selection", parser["selection"])

You can download a workflow that includes the above script here and view a screenshot of it below:

Modifying a Selection

In the previous example, we passed a selected object to another component. Using an Extend Python Script, it is also possible to modify the selection before passing it to another component.

The following script creates a new selection from a given selection. The new selection only contains objects with greater than the specified number of points.

from mapteksdk.project import Project
from mapteksdk.pointstudio.operations import write_report
from mapteksdk.workflows import WorkflowArgumentParser, WorkflowSelection, IntegerConnectorType
 
parser = WorkflowArgumentParser(
  description="Filter objects with less than Limit points")
parser.declare_input_connector("selection", WorkflowSelection)
parser.declare_input_connector(
  "limit",
  IntegerConnectorType,
  default=100,
  connector_name="Limit",
  description="All objects with point count lower than this are filtered.")
parser.declare_output_connector("selection", WorkflowSelection)
parser.parse_arguments()
 
project = Project()
 
limit = parser["limit"]
 
selection = []
for oid in parser["selection"]:
  try:
    with project.read(oid) as item:
      if item.point_count > limit:
        selection.append(item)
  except AttributeError:
    # The object does not have a point count. Filter it.
    pass
  except TypeError:
    # The object is not supported by the SDK. Filter it.
    pass
 
parser.set_output("selection", selection)

You can download a workflow that includes the above script here and view a screenshot of it below:

Multiple WorkflowSelection Connectors

Workflow components can have multiple input and output connectors of the same type. We can use this principle to create a workflow component that contains multiple WorkflowSelection connectors. For instance, in the example below, we create three separate types of selections from the original input selection: surfaces, annotations and all other objects. Each output selection is processed simultaneously by different components.

Note:  The output connectors must all have different connector names. The same applies to all input connectors.

from mapteksdk.workflows import WorkflowArgumentParser, WorkflowSelection
from mapteksdk.project import Project, Surface, Text2D, Text3D, Marker
 
parser = WorkflowArgumentParser(
  description="Split a selection into surfaces, annotations and other"
)
parser.declare_input_connector(
  "selection",
  WorkflowSelection,
  description="Selection to split.")
parser.declare_output_connector(
  "surfaces",
  WorkflowSelection,
  description="The Surfaces in the selection.")
parser.declare_output_connector(
  "annotations",
  WorkflowSelection,
  description="The annotations in the selection.")
parser.declare_output_connector(
  "other",
  WorkflowSelection,
  description="All non-Surfaces and non-annotations in the selection.")
parser.parse_arguments()
 
project = Project()
 
surfaces = []
annotations = []
other = []
for oid in parser["selection"]:
  if oid.is_a(Surface):
    surfaces.append(oid)
  elif oid.is_a((Text2D, Text3D, Marker)):
    annotations.append(oid)
  else:
    other.append(oid)
 
parser.set_output("surfaces", surfaces)
parser.set_output("annotations", annotations)
parser.set_output("other", other)

You can download a workflow that includes the above script here and view a screenshot of it below.

Summary

When creating WorkflowSelection connectors, keep the following in mind:

  • You cannot access the ObjectIDs in a WorkflowSelection object before connecting to a running application using the Project class.

  • When passing a selection between components, both components must connect to the same application otherwise the selection may not represent the intended objects.

  • If an input connector’s type is set to WorkflowSelection, consider adding an output connector of the same type to match. This may be the same selection as the one passed in, or it may be a new selection if the cloned or created new objects.

  • A script can have multiple output connectors of type WorkflowSelection.

  • Connectors of type WorkflowSelection are conventionally called “selection” (Note the lower case “s”). It is the type Maptek Database Object and not the name "selection" that marks a connector as accepting a selection. It is possible (but not wise) to have a connector called "selection" which accepts any type.

  • If a script accepts multiple input or output connectors of type WorkflowSelection, each must have a different name. It is preferable to only use the name "selection" if there is only one input and/or output connector of type WorkflowSelection.