stratified_packager.processing.matching

The matching engine: method resolution, relation-chain keys, spatial fid sets (SPEC §4/§7).

Runs on the algorithm thread during Phase A. Provider pushdown where it pays: relation hops query intermediates with C++-evaluated IN filter expressions (chunked, NULL keys never match); spatial candidates pass through the provider’s spatial index (setFilterRect), then a prepared QgsGeometryEngine over the stratum geometry tests each candidate (prepared once per pair, so the polygon is never re-analysed per feature; never inlined WKT).

All user-facing messaging flows through the QgsProcessingFeedback passed by the caller; fatal conditions raise QgsProcessingException.

Module Attributes

INTERIORS_INTERSECT

The spatial_predicate = auto pattern when neither side is point- or line-like.

Functions

attribute_keys_for_stratum(plan, ...)

Propagate the stratum's keys along the chain to the target layer (SPEC §7.1).

in_filter_expressions(fields, keys)

Build chunked QGIS filter expressions matching fields against keys.

resolve_layer_methods(layers, strat_layer, ...)

Resolve every partitioned vector layer's matching method (SPEC §4).

spatial_fids_for_stratum(layer, ...)

Materialize the matching fid set for one (layer, stratum) pair (SPEC §7.2).

stratum_geometry_in_layer_crs(geometry, ...)

Transform one stratum geometry into the layer's CRS (once per pair, SPEC §7.2).

Classes

LayerMatchPlan(layer_id, method[, chain, ...])

The resolved matching strategy of one packaged, partitioned vector layer.

MatchCondition([key_fields, keys, fids, by_fid])

What one (layer, stratum) pair must satisfy — plain data for worker payloads.

class stratified_packager.processing.matching.LayerMatchPlan(layer_id, method, chain=(), predicates=(), pinned=False)[source]

The resolved matching strategy of one packaged, partitioned vector layer.

Parameters:
__init__(layer_id, method, chain=(), predicates=(), pinned=False)
Parameters:
chain: RelationPath = ()

Attribute matching: hops ordered stratification layer → packaged layer.

layer_id: str

The layer’s id.

method: MatchingMethod

The resolved method — never AUTO.

pinned: bool = False

Whether the chain came from a relation_path pin.

predicates: tuple[str, ...] = ()

Spatial matching: the resolved predicate tokens (named or DE-9IM), combined with OR.

class stratified_packager.processing.matching.MatchCondition(key_fields=(), keys=(), fids=(), by_fid=False)[source]

What one (layer, stratum) pair must satisfy — plain data for worker payloads.

Parameters:
__init__(key_fields=(), keys=(), fids=(), by_fid=False)
Parameters:
by_fid: bool = False

Whether fids (rather than the key columns) define membership.

fids: tuple[int, ...] = ()

Spatial (or self) matching: the matching feature ids.

key_fields: tuple[str, ...] = ()

Attribute matching: the target layer’s key fields.

keys: tuple[tuple[object, ...], ...] = ()

Attribute matching: the matching key tuples (NULL-free).

stratified_packager.processing.matching._auto_predicates(layer, strat_layer)[source]

Expand spatial_predicate = auto to its predicate tuple by geometry type (SPEC §4).

With the layer feature as geometry a and the stratum as geometry b: a polygon stratum against a line layer (or the reverse) defaults to “interiors intersect, OR the line runs along the polygon boundary (dimension 1)”; a point on either side falls back to plain intersects; otherwise the interiors must intersect.

Parameters:
Return type:

tuple[str, ...]

Returns:

One or two resolved tokens (a named predicate or a DE-9IM pattern).

stratified_packager.processing.matching._check_canceled(feedback)[source]

Raise the standard cancellation error when the run was canceled.

Called at the top of the hot per-feature loops (hop queries, spatial candidate tests) so a cancellation interrupts a large layer mid-scan.

Parameters:

feedback (QgsProcessingFeedback) – Execution feedback channel.

Raises:

QgsProcessingException – If cancellation was requested.

Return type:

None

stratified_packager.processing.matching._compile_matcher(engine, predicates)[source]

Compile the per-candidate membership test for one prepared stratum engine (§7.2).

Everything derivable from the predicates alone — engine-method binding, DE-9IM transposition, the intersection/containment implications — is resolved here, once per (layer, stratum), so the returned closure does only prepared GEOS calls per candidate. DE-9IM candidates take a prepared contains fast-accept (when the pattern is implied by containment), then a prepared intersects fast-reject (when the pattern requires intersection), and only the remaining boundary shell pays relatePattern — which has no prepared fast path in GEOS.

Parameters:
  • engine (QgsGeometryEngine) – A geometry engine prepared on the stratum geometry.

  • predicates (Sequence[str]) – The OR-combined resolved predicates (named or DE-9IM).

Return type:

Callable[[QgsGeometry], bool]

Returns:

A callable testing one candidate geometry (a null geometry never matches).

stratified_packager.processing.matching._implied_by_containment(pattern, /)[source]

Report whether a DE-9IM pattern is guaranteed by the stratum containing the candidate.

When the prepared engine (built on stratum S) reports contains(C), the transposed matrix IM(C, S) is guaranteed II non-empty, IE = F and BE = F — nothing else. pattern is therefore implied iff cell 0 accepts any non-empty intersection (T/* — a dimension digit is not guaranteed), cells 2 and 5 accept F, and every other cell is a wildcard. True for the auto T******** (§4), letting the interior majority short-circuit on a prepared contains instead of a full relate.

Parameters:

pattern (str) – A nine-character DE-9IM pattern (feature-vs-stratum orientation).

Return type:

bool

Returns:

Whether contains alone proves the pattern.

stratified_packager.processing.matching._query_far_keys(layer, match_fields, keys, collect_fields, feedback)[source]

Query layer for features whose match_fields are in keys; collect new keys.

Parameters:
  • layer (QgsVectorLayer) – The intermediate layer (its subsetString applies implicitly).

  • match_fields (Sequence[str]) – Fields matched against the incoming keys.

  • keys (Iterable[tuple[object, ...]]) – Incoming key tuples (NULL-free).

  • collect_fields (Sequence[str]) – Fields whose values form the outgoing keys.

  • feedback (QgsProcessingFeedback) – Execution feedback channel (cancellation).

Return type:

set[tuple[object, ...]]

Returns:

The outgoing key tuples, NULL-bearing ones dropped.

Raises:

QgsProcessingException – On cancellation.

stratified_packager.processing.matching._requires_intersection(pattern, /)[source]

Report whether pattern is unsatisfiable by disjoint geometries (§7.2 prefilter gate).

Two geometries intersect iff at least one of their interior-interior, interior-boundary, boundary-interior or boundary-boundary cells is non-empty. A pattern that demands a dimension (not F, not the wildcard *) in any of those four cells can only match intersecting geometries, so a cheap prepared intersects test can pre-reject candidates before the fuller relatePattern. The test is symmetric, so pattern orientation is irrelevant here.

Parameters:

pattern (str) – A nine-character DE-9IM pattern.

Return type:

bool

Returns:

Whether every match must intersect.

stratified_packager.processing.matching._resolve_chain(layer, strat_layer, graph, paths, pin_raw)[source]

Pick the relation chain: a valid pin wins; else the unique shortest path.

The returned hops run stratification layer → packaged layer (propagation order); pins are given in the opposite, layer-→-strat order (SPEC §4) and are reversed here.

Parameters:
Return type:

tuple[RelationHop, ...]

Returns:

The chain in propagation order.

Raises:

QgsProcessingException – On invalid pins, no path, or unpinned ambiguity.

stratified_packager.processing.matching._resolve_one(layer, strat_layer, graph, feedback)[source]

Resolve one layer’s plan.

Parameters:
Return type:

LayerMatchPlan

Returns:

The plan.

Raises:

QgsProcessingException – Per the §4 rules.

stratified_packager.processing.matching._resolve_predicates(layer, strat_layer, raw)[source]

Resolve the spatial_predicate value to a tuple of predicates (SPEC §4).

The value is a comma-separated list whose tokens combine additively (OR). Each token is a named predicate or a 9-character DE-9IM pattern (the T/F case-insensitive, normalized to uppercase). The sole token auto expands by geometry type (_auto_predicates()) and cannot be combined with other tokens.

Parameters:
  • layer (QgsVectorLayer) – The packaged layer.

  • strat_layer (QgsVectorLayer) – The stratification layer.

  • raw (str) – The raw value (auto, or a comma-separated list of named predicates and DE-9IM patterns).

Return type:

tuple[str, ...]

Returns:

The resolved predicates, de-duplicated in input order.

Raises:

QgsProcessingException – On an unrecognized token, or auto combined with others.

stratified_packager.processing.matching._transpose_de9im(pattern, /)[source]

Transpose a row-major DE-9IM pattern (swap the intersection matrix’s rows and columns).

The prepared engine computes IM(stratum, feature) while the predicate is written relate(feature, stratum, pattern) — the transpose of that matrix — so the pattern is transposed to match. Self-transpose patterns (e.g. the auto T********) are unchanged.

Parameters:

pattern (str) – A nine-character DE-9IM pattern.

Return type:

str

Returns:

The transposed pattern.

stratified_packager.processing.matching.attribute_keys_for_stratum(plan, stratum_feature, stratum_name, project, feedback)[source]

Propagate the stratum’s keys along the chain to the target layer (SPEC §7.1).

Each hop queries the next layer with chunked, C++-evaluated IN filters, honoring that layer’s subsetString (selections on intermediates are ignored by construction — the request reads the layer, not its selection). NULL keys never match. The final hop’s far-side key set becomes the membership condition.

Parameters:
  • plan (LayerMatchPlan) – The layer’s attribute plan (chain in strat → layer order).

  • stratum_feature (QgsFeature) – The stratum feature.

  • stratum_name (str) – The resolved stratum name (for feedback only).

  • project (QgsProject) – The project (resolves intermediate layers by id).

  • feedback (QgsProcessingFeedback) – Execution feedback channel.

Return type:

MatchCondition

Returns:

The membership condition; for an empty chain (the layer is the stratification layer) a single-fid condition.

Raises:

QgsProcessingException – If an intermediate layer of the chain is missing, or on cancellation during a hop query.

stratified_packager.processing.matching.in_filter_expressions(fields, keys)[source]

Build chunked QGIS filter expressions matching fields against keys.

Single fields render as "f" IN (...); composite keys as chunked OR-of-AND groups (SPEC §7.1).

Parameters:
Return type:

list[str]

Returns:

One C++-evaluable expression per chunk (empty when there are no keys).

stratified_packager.processing.matching.resolve_layer_methods(layers, strat_layer, graph, feedback)[source]

Resolve every partitioned vector layer’s matching method (SPEC §4).

Errors are aggregated so the user sees every misconfigured layer at once.

Parameters:
Return type:

dict[str, LayerMatchPlan]

Returns:

One plan per layer id.

Raises:

QgsProcessingException – Listing every layer whose method cannot be resolved (no path and no geometry, ambiguous chains without a pin, invalid pins or predicate tokens).

stratified_packager.processing.matching.spatial_fids_for_stratum(layer, stratum_geometry, stratum_name, predicates, feedback)[source]

Materialize the matching fid set for one (layer, stratum) pair (SPEC §7.2).

The candidate filter is the provider’s spatial index (setFilterRect with the stratum’s bbox, already in the layer’s CRS); the exact test is a prepared QgsGeometryEngine over the stratum geometry — prepared once per pair, then each candidate is tested against the OR of the resolved predicates. Preparing the (often complex, admin-boundary) stratum polygon turns each test from O(vertices) into roughly O(log vertices), the dominant cost on large layers. No attributes are fetched.

Parameters:
  • layer (QgsVectorLayer) – The packaged layer (its subsetString applies implicitly).

  • stratum_geometry (QgsGeometry) – The stratum geometry in the layer’s CRS.

  • stratum_name (str) – The resolved stratum name (for feedback only).

  • predicates (Sequence[str]) – The resolved predicates (named or DE-9IM) from the layer’s plan, combined with OR.

  • feedback (QgsProcessingFeedback) – Execution feedback channel (messages and cancellation).

Return type:

MatchCondition

Returns:

The fid-set condition.

Raises:

QgsProcessingException – On cancellation during the candidate scan.

stratified_packager.processing.matching.stratum_geometry_in_layer_crs(geometry, strat_layer, layer, project, feedback)[source]

Transform one stratum geometry into the layer’s CRS (once per pair, SPEC §7.2).

Whether a transform is needed is decided by the QgsCoordinateTransform itself: a short-circuited transform (equivalent or invalid CRSs) returns the geometry unchanged. Every real transform is reported with source and target authids.

Parameters:
Return type:

QgsGeometry

Returns:

The geometry in the layer’s CRS.

Raises:

QgsProcessingException – If the coordinate transform fails (the §7.2 best-effort containment happens in the caller).

stratified_packager.processing.matching.INTERIORS_INTERSECT: Final = 'T********'

The spatial_predicate = auto pattern when neither side is point- or line-like.

stratified_packager.processing.matching._KEY_CHUNK: Final = 1000

Values (or key tuples) per IN chunk in intermediate hop queries (SPEC §7.1).

stratified_packager.processing.matching._NAMED_ENGINE_METHOD: Final[dict[str, str]] = {'contains': 'within', 'crosses': 'crosses', 'intersects': 'intersects', 'overlaps': 'overlaps', 'touches': 'touches', 'within': 'contains'}

Resolved named predicate → the prepared-engine method testing it against a candidate (§7.2).

Keys mirror NAMED_SPATIAL_PREDICATES.

stratified_packager.processing.matching._NAMED_PREDICATES: Final[frozenset[str]] = frozenset({'contains', 'crosses', 'intersects', 'overlaps', 'touches', 'within'})

Named predicates mapping 1:1 onto QGIS expression functions (SPEC §4).