Map
Data and space / clio.map.v1
Place sites, observations, shapes, or trajectories in geographic context and follow their spatial relationships.
When to use it
Place sites, observations, shapes, or trajectories in geographic context and follow their spatial relationships.
What the agent supplies
Interactive points, ordered trajectories, or GeoJSON geometry on a map.
The agent chooses the content and binds it to the component. CLIO then renders the view and its available controls.
When this view uses the same dataset as another view, selection travels with each row. A person can find the same observation across the views.

What the agent receives
The exact output of load_skill, including resolved local definitions.
load_skill("a2ui-catalog-clio-workspace", file="catalog.json#/components/clio.map.v1"){
"allOf": [
{
"$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon"
},
{
"properties": {
"weight": {
"description": "Relative flex weight of this component inside a Row or Column. Only meaningful as a direct child of one.",
"type": "number"
}
},
"type": "object"
},
{
"dependentRequired": {
"dataQuery": [
"dataUri"
],
"filterFields": [
"dataUri"
],
"orderField": [
"trackField"
],
"trackField": [
"dataUri",
"orderField"
]
},
"properties": {
"action": {
"$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action"
},
"actionLabel": {
"$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString"
},
"categoryField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column grouping points into categories."
},
"component": {
"const": "clio.map.v1"
},
"dataQuery": {
"additionalProperties": false,
"description": "A server-side table query applied to dataUri: the table-query request body (POST /v1/artifacts/{id}/table-query) without format. The server runs filter, then aggregate, then downsample, then sort, then offset/limit. Omit columns to request every column of dataUri \u2014 except alongside aggregate, where columns is required, since aggregate's output columns (e.g. price_mean) don't exist in the source and so cannot be inferred. limit bounds the rows in ONE response (a transfer size), not the underlying data; offset pages through a larger result across several requests. When a chart or map query would otherwise exceed limit without an explicit downsample, the server instead samples evenly across the full range and reports that it did, rather than silently truncating to the first rows. limit's own maximum here is a generous safety ceiling, not the deployment's real per-response cap, which is server-configured. A viewer (e.g. an interactive data-table) may layer its own user-driven paging/filtering/sorting on top of this dataQuery without replacing it \u2014 the agent's own filter/aggregate/downsample intent still applies underneath. Shared verbatim by clio.chart.v1, clio.map.v1, and clio.data-table.v1.",
"if": {
"properties": {
"aggregate": {
"not": {
"type": "null"
}
}
},
"required": [
"aggregate"
]
},
"properties": {
"aggregate": {
"anyOf": [
{
"additionalProperties": false,
"description": "Group rows by groupBy (empty or omitted: one global group) and reduce; each metric becomes a result column named {column}_{fn}, which must not repeat a groupBy column.",
"properties": {
"groupBy": {
"items": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"maxItems": 64,
"type": "array",
"uniqueItems": true
},
"metrics": {
"items": {
"additionalProperties": false,
"properties": {
"column": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"fn": {
"enum": [
"mean",
"min",
"max",
"count",
"sum",
"median"
],
"type": "string"
}
},
"required": [
"column",
"fn"
],
"type": "object"
},
"maxItems": 64,
"minItems": 1,
"type": "array",
"uniqueItems": true
}
},
"required": [
"metrics"
],
"type": "object"
},
{
"type": "null"
}
]
},
"columns": {
"anyOf": [
{
"items": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"maxItems": 64,
"minItems": 1,
"type": "array",
"uniqueItems": true
},
{
"type": "null"
}
]
},
"downsample": {
"anyOf": [
{
"additionalProperties": false,
"description": "How the server thins rows before limit applies. none keeps every row; stride keeps evenly spaced rows (per entityColumn up to maxPerEntity when set, else overall up to limit); per_entity_lttb runs LTTB on (x, y) per entityColumn (the whole table is one series without it) and needs x and y.",
"if": {
"properties": {
"mode": {
"const": "per_entity_lttb"
}
},
"required": [
"mode"
]
},
"properties": {
"entityColumn": {
"anyOf": [
{
"maxLength": 128,
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
]
},
"maxPerEntity": {
"default": 500,
"maximum": 2000,
"minimum": 1,
"type": "integer"
},
"mode": {
"default": "none",
"enum": [
"none",
"stride",
"per_entity_lttb"
],
"type": "string"
},
"x": {
"anyOf": [
{
"maxLength": 128,
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
]
},
"y": {
"anyOf": [
{
"maxLength": 128,
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
]
}
},
"then": {
"properties": {
"x": {
"not": {
"type": "null"
}
},
"y": {
"not": {
"type": "null"
}
}
},
"required": [
"x",
"y"
]
},
"type": "object"
},
{
"type": "null"
}
]
},
"filter": {
"anyOf": [
{
"items": {
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"op": {
"const": "eq"
}
}
},
"then": {
"properties": {
"value": {
"anyOf": [
{
"type": [
"string",
"number",
"boolean"
]
},
{
"additionalProperties": false,
"properties": {
"path": {
"pattern": "^/",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
]
}
},
"required": [
"value"
]
}
},
{
"if": {
"properties": {
"op": {
"const": "in"
}
}
},
"then": {
"properties": {
"value": {
"anyOf": [
{
"items": {
"type": [
"string",
"number",
"boolean"
]
},
"maxItems": 10000,
"minItems": 1,
"type": "array"
},
{
"additionalProperties": false,
"properties": {
"path": {
"pattern": "^/",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
]
}
},
"required": [
"value"
]
}
},
{
"if": {
"properties": {
"op": {
"const": "range"
}
}
},
"then": {
"properties": {
"value": {
"anyOf": [
{
"items": {
"type": [
"string",
"number",
"boolean",
"null"
]
},
"maxItems": 2,
"minItems": 2,
"type": "array"
},
{
"additionalProperties": false,
"properties": {
"path": {
"pattern": "^/",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
]
}
},
"required": [
"value"
]
}
},
{
"if": {
"properties": {
"op": {
"const": "isnull"
}
}
},
"then": {
"properties": {
"value": {
"anyOf": [
{
"type": [
"boolean",
"null"
]
},
{
"additionalProperties": false,
"properties": {
"path": {
"pattern": "^/",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
]
}
}
}
},
{
"if": {
"properties": {
"op": {
"const": "contains"
}
}
},
"then": {
"properties": {
"value": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"additionalProperties": false,
"properties": {
"path": {
"pattern": "^/",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
]
}
},
"required": [
"value"
]
}
}
],
"description": "One predicate; all filter entries are AND-ed. eq: value is a non-null scalar. in: value is a non-empty list of scalars. range: value is [min, max], inclusive, either side may be null. isnull: value omitted or true matches nulls, false matches non-nulls. contains: value is a non-empty string, matched as a case-insensitive substring of a string column (a per-column text filter).",
"properties": {
"column": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"op": {
"enum": [
"eq",
"in",
"range",
"isnull",
"contains"
],
"type": "string"
},
"value": {}
},
"required": [
"column",
"op"
],
"type": "object"
},
"maxItems": 64,
"type": "array"
},
{
"type": "null"
}
]
},
"limit": {
"anyOf": [
{
"maximum": 50000,
"minimum": 1,
"type": "integer"
},
{
"type": "null"
}
]
},
"offset": {
"anyOf": [
{
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"sort": {
"anyOf": [
{
"items": {
"additionalProperties": false,
"description": "One dataQuery.sort key; earlier entries in the list sort first.",
"properties": {
"column": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"desc": {
"default": false,
"type": "boolean"
}
},
"required": [
"column"
],
"type": "object"
},
"maxItems": 64,
"type": "array"
},
{
"type": "null"
}
]
}
},
"then": {
"required": [
"columns"
]
},
"type": "object"
},
"dataUri": {
"description": "A workspace file path or artifact:// reference; CLIO registers a path as an artifact before validation. Requires latitudeField/longitudeField/labelField; a referenced dataset is bounded by dataQuery/limit, not the inline point cap.",
"not": {
"pattern": "\\s"
},
"pattern": "^artifact://artifact_[A-Za-z0-9_-]+$",
"type": "string"
},
"detailField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column holding each point's detail text."
},
"filterFields": {
"description": "With dataUri, columns worth filtering while exploring this map. Choose one or more real columns from the task and dataset, such as a category, magnitude, or time column. Use a registered table even for small maps when these native filters matter. The viewer creates typed controls and applies them to the map and Reference this; omit for the viewer's default fields.",
"items": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"maxItems": 12,
"minItems": 1,
"type": "array",
"uniqueItems": true
},
"geojsonUri": {
"description": "Artifact URI of a GeoJSON FeatureCollection. Geometry is read by reference and drawn as points, lines, and polygons; feature properties supply labelField, categoryField, or valueField when named.",
"not": {
"pattern": "\\s"
},
"pattern": "^artifact://artifact_[A-Za-z0-9_-]+$",
"type": "string"
},
"idField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column holding each point's stable id."
},
"labelField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column holding each point's label (required with dataUri)."
},
"latitudeField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column holding latitude (required with dataUri)."
},
"longitudeField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column holding longitude (required with dataUri)."
},
"orderField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "With trackField, time or numeric sequence column ordering positions along each trajectory."
},
"points": {
"description": "Inline points (at most 500) \u2014 this array rides the surface's own wire message, so it is capped for transfer size; for a larger dataset use dataUri instead, unbounded and paged/downsampled by the viewer.",
"items": {
"additionalProperties": false,
"properties": {
"category": {
"description": "Nominal group, such as station type. Use value for measured numbers.",
"maxLength": 120,
"type": "string"
},
"detail": {
"maxLength": 2000,
"type": "string"
},
"id": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"label": {
"maxLength": 240,
"minLength": 1,
"type": "string"
},
"latitude": {
"maximum": 90,
"minimum": -90,
"type": "number"
},
"longitude": {
"maximum": 180,
"minimum": -180,
"type": "number"
},
"value": {
"description": "Optional measured magnitude for a continuous colour scale and legend.",
"type": "number"
}
},
"required": [
"id",
"label",
"latitude",
"longitude"
],
"type": "object"
},
"maxItems": 500,
"minItems": 1,
"type": "array"
},
"selected": {
"maxLength": 128,
"type": "string"
},
"selection": {
"$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicValue",
"description": "Bind to /selection/<key>; the bound value is a SelectionState ({field, values[], source?}, see $defs/SelectionState). Components bound to the same path share one selection."
},
"selectionField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Dataset column the shared selection's values are drawn from; required when selection is bound."
},
"title": {
"$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString"
},
"trackField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "With dataUri, column identifying each trajectory (for example storm_id). Rows with the same value form one path."
},
"valueField": {
"maxLength": 128,
"minLength": 1,
"type": "string",
"description": "Numeric dataset column used for a continuous colour scale and legend."
},
"valueLabel": {
"description": "Human-readable name for the numeric map legend, such as Displacement.",
"maxLength": 80,
"type": "string"
},
"valueUnit": {
"description": "Unit shown beside a continuous-colour legend's values.",
"maxLength": 40,
"type": "string"
}
},
"required": [
"component"
],
"type": "object"
},
{
"description": "Exactly one of points, dataUri, or geojsonUri is required.",
"oneOf": [
{
"not": {
"anyOf": [
{
"required": [
"dataUri"
]
},
{
"required": [
"geojsonUri"
]
}
]
},
"required": [
"points"
]
},
{
"not": {
"anyOf": [
{
"required": [
"points"
]
},
{
"required": [
"geojsonUri"
]
}
]
},
"required": [
"dataUri"
]
},
{
"not": {
"anyOf": [
{
"required": [
"points"
]
},
{
"required": [
"dataUri"
]
}
]
},
"required": [
"geojsonUri"
]
}
]
},
{
"description": "dataUri requires the point field names.",
"if": {
"required": [
"dataUri"
]
},
"then": {
"required": [
"latitudeField",
"longitudeField",
"labelField"
]
}
},
{
"not": {
"required": [
"categoryField",
"valueField"
]
}
},
{
"description": "selectionField is required when selection is bound (an object, not a literal).",
"if": {
"properties": {
"selection": {
"type": "object"
}
},
"required": [
"selection"
]
},
"then": {
"required": [
"selectionField"
]
}
}
],
"description": "Interactive points, ordered trajectories, or GeoJSON geometry on a map.",
"type": "object",
"unevaluatedProperties": false
}
Standard refs (not loadable here): https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action, https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon, https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString, https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicValue