Skip to content

1. Map the source schema

First step of preparing an administrative boundary release.

topo-tools schema-map your_admin2.parquet crosswalk.csv

This writes crosswalk.csv without changing the input. schema-map matches columns by cardinality (unique-value count), not by name, so open the crosswalk and check every row before trusting it, for example:

source_column, target_column, unique_count, note
NAME_2,        adm2_name,     8,
PCODE_2,       adm2_code,     8,
LOCAL_REF,     adm2_code1,    8,
NAME_1,        adm1_name,     2,
PCODE_1,       adm1_code,     2,

A source column that happens to share a level's cardinality can match as a decoy second code candidate (adm2_code1 above), even when it's really just a source reference number, not a p-code. The same trap applies to names. Map every name column for a level to that level's name family: the primary name to adm2_name, and any other (a translation, an alternate spelling, or a second name that differs from the first) to the next free adm2_name1, adm2_name2. Never give a column a target outside the adm{n}_code/adm{n}_name families. Blank out a decoy code's target_column before applying the crosswalk:

topo-tools schema-refactor your_admin2.parquet crosswalk.csv admin2_mapped.parquet

The mapped output now has only the columns you kept a target_column for, plus geometry.

With more than one level, copy each parent's codes and names onto its children, coarsest first, overwriting each child in place:

topo-tools schema-join admin2_mapped.parquet admin1_mapped.parquet admin2_mapped.parquet
topo-tools schema-join admin3_mapped.parquet admin2_mapped.parquet admin3_mapped.parquet

Where a child's own value differs from its parent's, schema-join keeps both, adding the parent's as the next free numbered sibling (adm2_name1), and writes one issues row per child for review names.

Next: clean geometry.