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
75is "Almonds". - A Sentinel-2 SCL pixel of
9is "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
| Field | Type | Description | Required |
|---|---|---|---|
source_uri_field | String | Document field holding the raster URI. Defaults to source_uri. | No |
target_field | String | Field that receives the emitted regions. Defaults to segments. | No |
band | Integer | Raster band to read. Defaults to 0. | No |
values | List | Pixel values to vectorize. Omit to vectorize every distinct value found. | No |
exclude_values | List | Pixel values to skip — nodata, background, water. | No |
class_labels | Object | Maps pixel value to label, as {"75": "Almonds"}. Values without an entry fall back to the raw pixel value. | No |
thresholds | List | Bins continuous data into classes before vectorizing. | No |
min_area_fraction | Double | Discards regions smaller than this fraction of the raster. Defaults to 0.0005. | No |
simplify_tolerance | Double | Douglas–Peucker tolerance for the emitted polygons. 0.0 (default) keeps full detail. | No |
max_regions | Integer | Ceiling on emitted regions. Defaults to 256. | No |
max_pixels | Long | Ceiling on raster size, as a guard against reading an enormous scene. | No |
holes | Boolean | Emit interior rings for regions containing holes. Defaults to true. | No |
streaming | Boolean | Stream the raster rather than reading it whole. Defaults to true. | No |
window | Object | Read only a pixel window, as {x, y, width, height}. | No |
window_field | String | Document field holding that window, instead of a fixed one. | No |
reference_config | Object | Settings for resolving the raster reference (for example, credentials or region). | No |
on_failure_action | String | fail (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
| Use | When |
|---|---|
vectorize | The pixel values already carry the classes — land cover, cloud masks, flood extent, change detection, any thematic or categorical raster. |
image_segment | The regions must be inferred — buildings in an aerial scene, a nodule in a CT slice, vessels in port imagery. |
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.
Related
- Image segment processor — the inference-based sibling
- Image tiling processor — grid tiling with spatial indexing
- Reprojection processor — carries emitted geometry into a
geo_shape - Geospatial