edge-match
See docs/reference/README.md for the MUST/SHOULD/MAY convention, and
docs/reference/shared.md/docs/reference/edge_extend.md for rules edge-match shares with other
tools.
Inputs¶
edge-matchMUST coverage-clean the child layer, the same wayedge-extend's own inputs stage does (seedocs/reference/edge_extend.md), and MUST load the parent/clip layer raw, uncleaned, the same wayedge-mosaic's parent load does (seedocs/adr/0086).- The child role MAY span multiple files (e.g. one raw admin boundary file per country), combined internally. The parent/clip 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/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 children to parents¶
- By default,
edge-matchMUST assign every child from the input file to a single parent polygon shared by the whole file, chosen by majority vote of that file's children (assign-one, seedocs/explanation/assign.md); a tie between two candidate parents MUST be broken by the lower parent id. Once the file has a winner, every child in it MUST be assigned to that parent unconditionally, including a child with zero individual overlap with it; such a child is not dropped here, but MAY still drop later at clip time if its extended geometry never reaches the parent (see Clipping), reported as akind='clip-empty'issue row. - When
--multi-parent(multi_parent=True) is given,edge-matchMUST instead assign each child polygon independently to the single parent polygon it shares the largest overlapping area with (assign-many), so one input file's children MAY scatter across many different parents. Use this only when children genuinely belong to different parents, e.g. a poorly-digitized admin4 layer fitting into many admin3 units. - Under
assign-one(default), a whole input file with no child overlapping any parent at all MUST be dropped, not treated as fatal, andedge-matchMUST log a warning naming its children. Underassign-many(--multi-parent), an individual child with no overlap with any parent MUST be dropped the same way. Either case, unlessmergeis set (see Configuration), in which case the dropped child(ren) 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. - A parent matched by zero children MUST be dropped, unless
mergeis set (see Configuration), in which case that parent'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 children by their assigned parent, including a group of exactly one child.- For each group,
edge-matchMUST extend that group's children alone (boundary extraction, point/Voronoi generation, merging; seedocs/reference/edge_extend.md). Clipping to the group's parent 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 child 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 ownparent_fid's geometry, perdocs/reference/edge_clip.md, one distinctparent_fidat a time, each in its own spawned OS subprocess. The orphan group (mergeset only) MUST NOT be clipped; it has no parent to clip against. A parent matched by zero children (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 realparent_fid's clip subprocess fails, aborting the whole run rather than dropping just that group.
Stitching¶
edge-matchMUST run one whole-layer coverage-clean pass over the clipped output, perdocs/reference/edge_stitch.md, using the same fixed gap-closing width asedge-extend's own merge stage (seedocs/reference/edge_extend.md), not a per-feature-scoped pass.
Outputs¶
edge-match's final output MUST pass the hard gate indocs/reference/shared.md(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 shared schema indocs/reference/shared.md, listing every dropped child, every child belonging to a dropped group, every child dropped for an empty clip intersection, every passthrough child and gap-filled parent (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 child'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 child file. - For an
unassigned/dropped_group/clip-empty/passthroughrow,unit_aMUST hold the child's own fid; for adropped_grouprow,parent_fidandreasonMUST record the group's assigned parent and drop reason. For aclip-emptyrow,parent_fidMUST hold the child's assigned parent's fid andreasonMUST explain that the clip intersection came back empty. For apassthroughrow,reasonMUST explain that the child had no overlapping parent and was extended alone and kept unclipped in the output; a passthrough child MUST NOT also appear as anunassignedrow. For agap-fillrow,parent_fidMUST hold the gap-filled parent's fid andreasonMUST explain that the parent had no matched children and was kept unclipped in the output;unit_aMUST be null, since the row is the parent itself, not a child. 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 child files and exactly one parent/clip 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 child file, the output path MUST default to that input
path with a
_matchedsuffix. With multiple child 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 child file is given; any other value MUST raiseValueError(seedocs/adr/0084).edge-matchMAY acceptmatch_column/parent_match_column/child_match_columnto override spatial assignment with an exact code join (seedocs/reference/shared.md,docs/explanation/assign.md).edge-matchMAY acceptmulti_parent: bool = False(CLI:--multi-parent):False(default) assigns the whole input file to one majority-vote parent (assign-one);Trueassigns each child independently to whichever parent it overlaps most (assign-many), for files whose children genuinely scatter across multiple parents (seedocs/explanation/assign.md,docs/adr/0082).multi_parentMUST beFalsewhenever more than one child 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 parent columns and drops both an unmatched child and a zero-children parent;Truecopies every parent column (excludingfid/geom) onto every matched child, keeps an unmatched child's own extended geometry in the output unclipped (kind='passthrough'), and keeps a zero-children parent'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 acceptparent_include/parent_exclude(CLI:--parent-include/--parent-exclude, each a comma-separated column list) to narrow which parent columns get copied onto matched children (default: every parent column exceptfid/geom), andchild_include/child_exclude(CLI:--child-include/--child-exclude) to narrow which of the child's own columns survive in the output (default: every child column;fid/geom/source_fileare always force-kept regardless). Each pair is mutually exclusive with itself; a parent-side flag MAY be combined with a child-side flag. All four MUST raiseValueErrorif given withoutmerge. - With
mergeset,edge-matchMAY additionally acceptprefer: "parent" | "child" | None = None(CLI:--prefer) to auto-resolve a real parent/child column-name collision:"parent"keeps the parent's column and drops the child's,"child"does the reverse. Omittingprefer(the default) preserves raisingValueErroron a real collision.preferMUST raiseValueErrorif given withoutmerge, or combined with any ofparent_include/parent_exclude/child_include/child_exclude(seedocs/reference/shared.md,docs/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_parents(), seedocs/adr/0083) fills a per-parent geometry-coverage gap left by the match; the two compose freely (seedocs/adr/0095).