Getting Started
This page shows the recommended onboarding path for new brdr users.
Prerequisites
- Use a projected CRS with meter units.
- Ensure thematic and reference data are in the same CRS.
- Start with a small subset of features before scaling.
Step-by-step
- Create an
Aligner. - Load thematic data (
DictLoader,GeoJsonLoader,GeoDataFrameLoader, …). - Load reference data (local or on-the-fly loaders).
- Run:
process(...)for full distance series outputpredict(...)for candidate distancesevaluate(...)for scored/classified predictions
- Export with
get_results_as_geojson(...)orsave_results(...).
Scoped processing (processing_area)
process(...), predict(...), and evaluate(...) accept an optional processing_area geometry.
- Default:
None(fully backward compatible). - When set: only the intersecting part of each thematic geometry is processed.
- The non-intersecting part is kept unchanged and merged back into the final result.
- Reference preselection still uses a buffered search area around the scoped part, so nearby boundaries just outside the scope can still influence snapping/alignment.
from shapely.geometry import box
# Example scope in working CRS coordinates
scope = box(100000, 200000, 101000, 201000)
# Process only inside scope; outside stays untouched
result = aligner.process(
relevant_distances=[0.5, 1.0],
processing_area=scope,
)Strategy components
Aligner uses four interchangeable strategy components:
processor: geometric alignmentpredictor: selection of interesting distancesevaluator: evaluation/classification of predictionsdescriptor: construction of observations and metadata onProcessResult
By default, Aligner uses the default implementation for each component.
Descriptor/evaluator contract
If you provide a custom descriptor, keep this internal contract in mind:
get_base_observation(...)should return a BRDR observation dict (orNone).get_actual_observation(...)should return a BRDR observation dict (orNone).evaluate(...)uses these observations for comparison/scoring.
If either side returns None, evaluation falls back to conservative TO_CHECK_* classifications.
Custom descriptor (short example)
from brdr.aligner import Aligner
from brdr.descriptor import BaseDescriptor
class NoopDescriptor(BaseDescriptor):
def describe(self, *, aligner, thematic_id, geometry, relevant_distance, process_result):
# Pass ProcessResult through unchanged
return process_result
def get_base_observation(self, *, feature_properties, metadata_field, cache_key=None):
# Evaluator contract: return BRDR observation dict or None
return None
def get_actual_observation(self, *, aligner, process_result, cache_key=None):
# Evaluator contract: return BRDR observation dict or None
return None
aligner = Aligner(descriptor=NoopDescriptor())Topology note
TopologyProcessor relies on explicit thematic IDs passed by Aligner. This avoids ambiguity when multiple thematic features share identical geometry.
Minimal code shape
from brdr.aligner import Aligner
aligner = Aligner(crs="EPSG:31370")
aligner.load_thematic_data(...)
aligner.load_reference_data(...)
aligner_result = aligner.process(relevant_distances=[0.5, 1.0, 1.5])
results = aligner_result.get_results(aligner=aligner)