edge-match
See edge-extend for the rules edge-match shares with it.
Inputs¶
edge-matchMUST coverage-clean the input layer, the same wayedge-extend's own inputs stage does (seedocs/pages/3-edge/reference/edge_extend.md), and MUST load the overlay layer raw, uncleaned, the same wayedge-mosaic's overlay load does (seedocs/adr/0086).- The input role MAY span multiple files (e.g. one raw admin boundary file per country), combined internally. The overlay layer MUST remain a single file.
- The main output MUST NOT carry a
source_filecolumn; it is an internal working column only, used byassign-one's per-file grouping (seedocs/pages/3-edge/explanation/assign.md), not exported. The issues report MAY carrysource_file, shortened to its parent directory plus filename (e.g.sen/adm2.parquet), never the full input path (seedocs/adr/0087).
Assigning input features to overlay features¶
- By default,
edge-matchMUST assign every input feature from the input file to a single overlay feature shared by the whole file, chosen by majority vote of that file's input features (assign-one, seedocs/pages/3-edge/explanation/assign.md); a tie between two candidate overlay features MUST be broken by the lower overlay feature id. Once the file has a winner, every input feature in it MUST be assigned to that overlay feature unconditionally, including an input feature with zero individual overlap with it; such an input feature is not dropped here, but MAY still drop later at clip time if its extended geometry never reaches the overlay feature (see Clipping), reported as akind='clip-empty'issue row. - When
--per-feature(per_feature=True) is given,edge-matchMUST instead assign each input polygon independently to the single overlay feature polygon it shares the largest overlapping area with (assign-many), so one input file's input features MAY scatter across many different overlay features. Use this only when input features genuinely belong to different overlay features, e.g. a poorly-digitized admin4 layer fitting into many admin3 units. - Under
assign-one(default), a whole input file with no input feature overlapping any overlay feature at all MUST be dropped, not treated as fatal, andedge-matchMUST log a warning naming its input features. Underassign-many(--per-feature), an individual input feature with no overlap with any overlay feature MUST be dropped the same way. Either case, unlessmergeis set (see Configuration), in which case the dropped input feature(s) are instead grouped into one orphan group of their own and extended together (see "Extending each group"), kept unclipped in the output. Either case MUST also be recorded in the issues report described under Outputs. - An overlay feature matched by zero input features MUST be dropped, unless
mergeis set (see Configuration), in which case that overlay feature's own geometry and attributes are kept unclipped in the output instead. This case MUST also be recorded in the issues report described under Outputs.
Extending each group¶
edge-matchMUST group input features by their assigned overlay feature, including a group of exactly one input feature.- For each group,
edge-matchMUST extend that group's input features alone (boundary extraction, point/Voronoi generation, merging; seedocs/pages/3-edge/reference/edge_extend.md). Clipping to the group's overlay feature happens later, batched across all groups (see Clipping below), not inside this step. - Each group's extension MUST run in an isolated process, separate from
every other group and from
edge-match's own process. - A group whose extension fails MUST be dropped from the output, not
treated as fatal to the whole run, and
edge-matchMUST log an error naming it, since this may signal a real data problem even though it isn't fatal.edge-matchMUST raise only if every group fails to produce output. Every input feature belonging to a failed group MUST be recorded in the issues report described under Outputs.
Clipping¶
edge-matchMUST clip every real group's reassembled, extended output to its ownoverlay_fid's geometry, perdocs/pages/3-edge/reference/edge_clip.md, one distinctoverlay_fidat a time, each in its own spawned OS subprocess. The orphan group (mergeset only) MUST NOT be clipped; it has no overlay feature to clip against. An overlay feature matched by zero input features (mergeset only) MUST be appended to the clipped result afterward, via its own unclipped geometry, before stitching.- Unlike a failed group's extension,
edge-matchMUST raise immediately if any realoverlay_fid's clip subprocess fails, aborting the whole run rather than dropping just that group. edge-matchMUST merge or keep every clip-detached piece in the clipped result, recording each one with an edge neighbour as akind='detached-part'row.
Stitching¶
edge-matchMUST run one whole-layer coverage-clean pass over the clipped output, perdocs/pages/3-edge/reference/edge_stitch.md, using the same fixed gap-closing width asedge-extend's own merge stage (seedocs/pages/3-edge/reference/edge_extend.md), not a per-feature-scoped pass.
Outputs¶
edge-match's final output MUST pass the coverage check (no overlap, no gap at or belowSNAP_TOLERANCE) before export. A wider leftover gap does not block export (seedocs/adr/0035).edge-matchMUST export the final merged layer.edge-matchMUST also export an issues report alongside it, using the same columns as every other tool's issues report, listing every dropped input feature, every input feature belonging to a dropped group, every input feature dropped for an empty clip intersection, every clip-detached piece with an edge neighbour, every passthrough input feature and gap-filled overlay feature (mergeset only), and every leftover gap wider thanSNAP_TOLERANCE, so a human can audit what didn't make it into the output or what may need review.- For an
unassigned/dropped_group/clip-empty/passthroughrow,source_fileMUST record the input feature's own origin file as a parent-directory-plus-filename (not the full path). For agap-fillorgaprow,source_fileMUST be null, since neither has a single originating input file. - For an
unassigned/dropped_group/clip-empty/passthroughrow,unit_aMUST hold the input feature's own fid; for adropped_grouprow,overlay_fidandreasonMUST record the group's assigned overlay feature and drop reason. For aclip-emptyrow,overlay_fidMUST hold the input feature's assigned overlay feature's fid andreasonMUST explain that the clip intersection came back empty. For apassthroughrow,reasonMUST explain that the input feature had no overlapping overlay feature and was extended alone and kept unclipped in the output; a passthrough input feature MUST NOT also appear as anunassignedrow. For agap-fillrow,overlay_fidMUST hold the gap-filled overlay feature's fid andreasonMUST explain that the overlay feature had no matched input features and was kept unclipped in the output;unit_aMUST be null, since the row is the overlay feature itself, not an input feature. For agaprow,area_m2,max_width_m, andthinness_ratioMUST be populated instead. A field that doesn't apply to a row's kind MUST be null. edge-matchMUST produce the issues report only when it has at least one row; when it would be empty, no file MUST be written (and a stale file from a previous run at that path MUST be removed).
Configuration (api.edge_match.match() / CLI)¶
edge-matchMUST accept one or more input files and exactly one overlay file per call. The CLI additionally accepts--input(repeatable and comma-separable) alongside the glob-capableINPUT_FILEpositional, both usable together, matchingedge-mosaic's own--inputidiom.- With a single input file, the output path MUST default to that input
path with a
_matchedsuffix. With multiple input files,output_pathMUST be given explicitly. The issues-report path MUST default to the output path with an_issuessuffix. edge-matchMUST raiseFileExistsErrorif either output path already exists and overwriting wasn't requested.step, if given, MUST be one ofinputs,assign,groups,edge-clip,edge-stitch,outputs; any other value MUST raiseValueError.stepMUST beNonewhenever more than one input file is given; any other value MUST raiseValueError(seedocs/adr/0084).edge-matchMAY acceptmatch_column/overlay_match_column/input_match_columnto override spatial assignment with an exact code join (seedocs/pages/3-edge/explanation/assign.md).edge-matchMAY acceptper_feature: bool = False(CLI:--per-feature):False(default) assigns the whole input file to one majority-vote overlay feature (assign-one);Trueassigns each input feature independently to whichever overlay feature it overlaps most (assign-many), for files whose input features genuinely scatter across multiple overlay features (seedocs/pages/3-edge/explanation/assign.md,docs/adr/0082).per_featureMUST beFalsewhenever more than one input file is given; any other value MUST raiseValueError(seedocs/adr/0084).edge-matchMAY acceptmerge: bool = False(CLI:--merge, a plain boolean flag):False(default) copies no overlay columns and drops both an unmatched input feature and an unmatched overlay feature;Truecopies every overlay column (excludingfid/geom) onto every matched input feature, keeps an unmatched input feature's own extended geometry in the output unclipped (kind='passthrough'), and keeps an unmatched overlay feature's own geometry in the output unclipped (kind='gap-fill'). There is no way to enable one behavior without the other.- With
mergeset,edge-matchMAY additionally acceptoverlay_include/overlay_exclude(CLI:--overlay-include/--overlay-exclude, each a comma-separated column list) to narrow which overlay columns get copied onto matched input features (default: every overlay column exceptfid/geom), andinput_include/input_exclude(CLI:--input-include/--input-exclude) to narrow which of the input layer's own columns survive in the output (default: every input column;fid/geom/source_fileare always force-kept regardless). Each pair is mutually exclusive with itself; an overlay-side flag MAY be combined with an input-side flag. All four MUST raiseValueErrorif given withoutmerge. - With
mergeset,edge-matchMAY additionally acceptprefer: "overlay" | "input" | None = None(CLI:--prefer) to auto-resolve a real overlay/input column-name collision:"overlay"keeps the overlay layer's column and drops the input layer's,"input"does the reverse. Omittingprefer(the default) preserves raisingValueErroron a real collision.preferMUST raiseValueErrorif given withoutmerge, or combined with any ofoverlay_include/overlay_exclude/input_include/input_exclude(seedocs/adr/0077,docs/adr/0081,docs/adr/0088). edge-matchMAY opt into cascading admin-hierarchy columns viafill_schema/--fill-schema, right after stitching and before export (both the single-file step loop and the multi-file combine path).name_field/code_field/--name-field/--code-field(given together or both omitted; omitted falls back to structural auto-detection) anddepth_column/--depth-column(defaultadm_lvl) narrow it; all MUST raiseValueErrorif given withoutfill_schema=True.edge-matchMUST raiseValueErrorifdepth_columnalready names an existing column whenfill_schemais set.fill_schemais independent ofmerge: it fills a per-row schema-depth gap left by the input data itself, whilemerge's own gap-fill (fill_unmatched_overlays(), seedocs/adr/0083) fills a per-overlay geometry-coverage gap left by the match; the two compose freely (seedocs/adr/0095).
Examples¶
Example 1: fit an admin4 layer into a single country boundary, output name chosen automatically¶
topo-tools edge-match adm4.geojson adm0.geojson
Example 2: fit admin3 into admin2 groups, explicit output¶
topo-tools edge-match adm3.gpkg adm2.gpkg adm3_matched.gpkg
Example 3: custom issues report path¶
topo-tools edge-match adm3.gpkg adm2.gpkg adm3_matched.gpkg \
--issues-file match_report.gpkg
Example 4: cascade admin-hierarchy columns and stamp each row's depth before export¶
topo-tools edge-match adm3.gpkg adm2.gpkg adm3_matched.gpkg --fill-schema