Skip to main content
Version: 0.13.0

Vectorize ingest processor

The vectorize ingest processor turns a categorical raster into indexable geometry — with no model, no GPU, and no inference endpoint.

It is the deterministic sibling of image_segment. Where that processor asks an inference provider to find regions, vectorize reads the regions straight out of the pixel values, because for a whole class of imagery they are already there:

  • A USDA CDL pixel of 75 is "Almonds".
  • A Sentinel-2 SCL pixel of 9 is "cloud high probability".
  • Flood masks, burn scars, NLCD and CORINE land-cover tiles, and most change-detection products are all the same shape of data.

Asking a neural network to rediscover a label the file already states is wasteful anywhere, and disqualifying in an air-gapped deployment, where it would make a GPU mandatory in order to read an integer.

It emits the same contract as image_segment

Each detected region carries label, score, area_fraction, bbox, mask_xy_shape and centroid_xy_shape — exactly what image_segment emits. So reproject carries the result to a geo_shape, and every downstream query, aggregation and tile layer keeps working untouched.

A pipeline can swap one processor for the other and nothing else changes. That interchangeability is the point of the design, not a coincidence of it.

Because the classes are known rather than predicted, score is always 1.0 — this is a measurement, not an estimate.

Request fields

FieldTypeDescriptionRequired
source_uri_fieldStringDocument field holding the raster URI. Defaults to source_uri.No
target_fieldStringField that receives the emitted regions. Defaults to segments.No
bandIntegerRaster band to read. Defaults to 0.No
valuesListPixel values to vectorize. Omit to vectorize every distinct value found.No
exclude_valuesListPixel values to skip — nodata, background, water.No
class_labelsObjectMaps pixel value to label, as {"75": "Almonds"}. Values without an entry fall back to the raw pixel value.No
thresholdsListBins continuous data into classes before vectorizing.No
min_area_fractionDoubleDiscards regions smaller than this fraction of the raster. Defaults to 0.0005.No
simplify_toleranceDoubleDouglas–Peucker tolerance for the emitted polygons. 0.0 (default) keeps full detail.No
max_regionsIntegerCeiling on emitted regions. Defaults to 256.No
max_pixelsLongCeiling on raster size, as a guard against reading an enormous scene.No
holesBooleanEmit interior rings for regions containing holes. Defaults to true.No
streamingBooleanStream the raster rather than reading it whole. Defaults to true.No
windowObjectRead only a pixel window, as {x, y, width, height}.No
window_fieldStringDocument field holding that window, instead of a fixed one.No
reference_configObjectSettings for resolving the raster reference (for example, credentials or region).No
on_failure_actionStringfail (default) or skip. Any other value is rejected.No

Example

Vectorize a cropland layer, keeping only orchard classes, then hand the result to reproject:

PUT /_ingest/pipeline/cropland
{
"description": "Vectorize CDL orchard classes and project them to WGS84",
"processors": [
{
"vectorize": {
"source_uri_field": "source_uri",
"target_field": "segments",
"band": 0,
"values": [75, 76, 204, 69],
"class_labels": {
"75": "Almonds",
"76": "Walnuts",
"204": "Pistachios",
"69": "Grapes"
},
"min_area_fraction": 0.001
}
},
{
"reproject": {
"field": "segments",
"shape_field": "mask_xy_shape",
"target_field": "mask"
}
}
]
}

Each entry in segments then looks like:

{
"label": "Almonds",
"score": 1.0,
"area_fraction": 0.0421,
"bbox": [612340.0, 4183220.0, 613880.0, 4184960.0],
"crs": "EPSG:5070",
"mask_xy_shape": { "type": "polygon", "coordinates": [ [ [612340.0, 4183220.0], "..." ] ] },
"centroid_xy_shape": { "type": "point", "coordinates": [613110.0, 4184090.0] }
}

Choosing between vectorize and image_segment

UseWhen
vectorizeThe pixel values already carry the classes — land cover, cloud masks, flood extent, change detection, any thematic or categorical raster.
image_segmentThe regions must be inferred — buildings in an aerial scene, a nodule in a CT slice, vessels in port imagery.
info

Because both emit the same fields, you can start with vectorize on the data that has labels and add image_segment for the data that does not, without changing your mappings, queries, or tile layers.