Repository navigation
Core Concepts
Four ideas cover the whole library: assets and collections describe what you are studying, image assets hold the pictures of them, pipeline steps do the work, and models are interchangeable engines behind the analysis steps.
The package is organised into four subpackages. rapidtools.core holds the domain objects, rapidtools.data_sources the clients for external imagery and local rasters, rapidtools.models the model wrappers, and rapidtools.processing the pipeline steps. Everything shown here is also re-exported at the top level (import rapidtools as rt). Full signatures live in the API reference.
A PhysicalAsset is the digital twin of one real-world object: a building, a road segment, a utility pole, a vehicle. It holds a Shapely geometry, a dictionary of attributes, and an ImageCollection of the pictures taken of it (image_assets).
from shapely.geometry import Point
from rapidtools import PhysicalAsset
pole = PhysicalAsset(
id='pole_123',
geometry=Point(-118.14, 34.19),
attributes={'asset_type': 'utility_pole', 'material': 'wood'},
)A PhysicalAssetCollection is an ordered container of assets with unique IDs and constant-time lookup by ID. It reads and writes GeoJSON and Shapefiles, converts to a pandas DataFrame, filters by geometry or attribute, and merges with other collections.
from rapidtools import BoundingBox, PhysicalAssetCollection
buildings = PhysicalAssetCollection.from_geojson('buildings.geojson')
subset = buildings.filter_by_geometry(BoundingBox(-118.15, 34.18, -118.13, 34.20))
damaged = subset.filter_by_attribute('gemini_chs_level', '4')
damaged.to_shapefile('damaged.shp', ignore_properties=['image_assets'])
buildings['bldg_01'] # lookup by ID
buildings[:10] # slice into a new collection
len(buildings), 'bldg_01' in buildingsfilter_by_attribute takes an operator ('==' by default, for example '!='). filter_empty() drops assets that received no imagery. See Data Formats and Export for the file formats and the sidecar that keeps image assets across round trips.
BoundingBox and PolygonRegion describe areas of interest in WGS84 (longitude, latitude). A bounding box can be built from a raster's extent, a GeoJSON file or any geometry, buffered, split into tiles, and used to filter collections or to drive basemap downloads.
region = BoundingBox.from_raster('eaton_patch_20250214.tiff')
region = BoundingBox.from_geojson('area.geojson')
region.width, region.height, region.area
tiles = region.tile_by_area(0.0001) # sub-boxes of at most 0.0001 square degreesAn ImageAsset points at one image file and carries properties such as the WGS84 bounds of an aerial crop or the panorama ID of a street-level view, plus optional semantic and instance masks. Extractors create image assets and attach them to physical assets; analyzers and segmenters read them. An image asset can exist before its file is downloaded (allow_missing_file=True), which lets extractors decide what to fetch before spending bandwidth.
Street-level detection adds one more record: an Observation links an asset to a single sighting in a street-level image (image ID, bearing, range), so crops can be regenerated later without re-running detection.
A Pipeline runs a list of steps over a collection. Each step is a callable that takes a collection and returns one, and declares a Stage:
| Stage | Components |
|---|---|
DETECT |
SAM3OrthoFeatureExtractor discovers new assets in a raster; MapillaryFeatureExtractor discovers them along a street-level survey. |
EXTRACT_IMAGERY |
AerialImageryExtractor, GoogleStreetViewImageExtractor, MapillaryImageExtractor, MapillaryObjectImageExtractor attach imagery to assets. |
REGULARIZE |
BuildingRegularizer, RoadwayRegularizer clean geometries. |
SEGMENT |
SAM3ImageSegmenter masks the attached images. |
VERIFY |
DetectionVerifier shows each discovered object's crops to a model and removes what is not the requested class; DuplicateResolver then merges pairs of nearby objects the model is sure are one vehicle. |
ANALYZE |
AssetAnalyzer writes model answers to attributes. |
EXPORT / CUSTOM
|
Your own callables; unknown steps run last. |
Steps can be added in any order: the pipeline sorts them by stage before running, so an analyzer added before an extractor still runs after it. Any plain function can be a step, which is the easiest way to add a custom export or filter.
from rapidtools import Pipeline
def drop_unimaged(collection):
return collection.filter_empty()
pipeline = Pipeline([analyzer, extractor, drop_unimaged])
result = pipeline.run(buildings)A detection pipeline can start from an empty collection: Pipeline([detector, cropper, analyzer]).run(PhysicalAssetCollection()).
Every long-running component and the Pipeline accept a cancel_event (a threading.Event) and raise OperationCancelled at the next asset, tile or batch, keeping partial results. Call rapidtools.configure_logging() to see progress; importing the package never touches logging. Details are in the cancellation and logging guide.
Every model wrapper, hosted or local, implements run_inference(image_inputs, prompt) and returns a ModelOutput (with text, and for segmentation models masks and bounding_boxes). Build one with rapidtools.models.load() and its registry key, then hand it to AssetAnalyzer. Switching providers is a one-word change; the analyzer picks threaded execution for APIs and batched execution for local models on its own.
from rapidtools import AssetAnalyzer
from rapidtools.models import GenerationConfig, load
model = load('claude', api_key='sk-ant-...')
analyzer = AssetAnalyzer(
model,
prompt='Return JSON with a damage_level key (0-4).',
generation=GenerationConfig(json_mode=True, temperature=0.0),
)Answers are written as attributes prefixed with the provider key (claude_damage_level); pass attribute_prefix= to choose your own. Hosted models run max_workers requests in parallel under a RateLimitPolicy (shared cooldown after a failure, then retry passes over the assets that failed). Local models run in batches of batch_size. max_images_per_asset and image_filter choose which attached images the model sees.
The provider-specific classes such as GeminiAssetAnalyzer and Gemma4AssetAnalyzer still work but are deprecated in favour of AssetAnalyzer(load(...)). See Supported Models and Vision-Language Models.
- Aerial Imagery Workflows: orthomosaics, basemaps, crops, SAM 3 detection and regularizers.
- Street-Level Imagery Workflows: Google Street View, Mapillary panoramas and object discovery.
- Data Formats and Export: GeoJSON, Shapefile, DataFrame and the image sidecar.
rAPIdtools is developed by the NHERI RAPID Facility and released under the BSD-3-Clause license. Found a problem on this page? Open an issue or edit the page directly. Missing a capability? Request a feature. No GitHub account? Email us.
Getting started
Workflows
- Aerial Imagery Workflows
- Street-Level Imagery Workflows
- Vision-Language Models
- Data Formats and Export
Using the app
Help
Reference