GeoAgent + STAC tools¶
This notebook demonstrates GeoAgent's STAC tool surface without requiring a real QGIS session or an LLM API key. It uses geoagent.testing QGIS mocks, direct tool calls, and the public Microsoft Planetary Computer STAC API.
- Install:
pip install "GeoAgent[stac]". - No provider key is required unless you call
agent.chat(...). - The final cell loads a selected STAC raster asset URL into the mock QGIS project.
%pip install -q "GeoAgent[stac]"
Create a STAC-enabled GeoAgent. The tiny model stand-in avoids provider setup because this notebook calls tools directly rather than sending prompts to a model.
from geoagent import auto_approve_all, for_stac
from geoagent.testing import MockQGISIface, MockQGISProject
import json
class NotebookModel:
stateful = False
def tool_payload(result):
"""Return the JSON payload from a Strands direct tool-call result."""
if isinstance(result, dict) and "content" in result:
content = result.get("content") or []
text = (
content[0].get("text", "")
if content and isinstance(content[0], dict)
else ""
)
if result.get("status") == "error":
raise RuntimeError(text or "GeoAgent tool call failed")
if text:
return json.loads(text)
return result
project = MockQGISProject()
iface = MockQGISIface(project)
agent = for_stac(
iface,
project,
model=NotebookModel(),
confirm=auto_approve_all,
permission_profile="Trusted auto-approve",
)
agent.tool_names
List a few collections from the catalog.
catalog_url = "https://planetarycomputer.microsoft.com/api/stac/v1"
collections = tool_payload(
agent.tool.list_stac_collections(catalog_url=catalog_url, limit=8)
)
[(c["id"], c.get("title")) for c in collections["collections"]]
Search Sentinel-2 L2A items over Knoxville, Tennessee for a short date range. The bbox order is west, south, east, north.
search = tool_payload(
agent.tool.search_stac_items(
catalog_url=catalog_url,
collection="sentinel-2-l2a",
bbox=[-84.10, 35.80, -83.70, 36.10],
datetime="2024-06-01/2024-06-30",
limit=5,
)
)
search["count"], search["items"][:2]
Inspect the first item's assets and choose a visual or raster asset.
if not search["items"]:
raise RuntimeError("No STAC items found. Try a wider date range or bbox.")
first = search["items"][0]
assets = tool_payload(
agent.tool.get_stac_item_assets(
catalog_url=catalog_url,
collection=first["collection"],
item_id=first["id"],
)
)
asset_candidates = assets["assets"]
asset = next(
(
item
for item in asset_candidates
if item["key"] in {"visual", "rendered_preview", "B04", "red"}
or "tiff" in str(item.get("type", "")).lower()
),
asset_candidates[0],
)
asset
Load the selected asset URL into the mock QGIS project. In a real QGIS session, the same tool calls iface.addRasterLayer(...); if QGIS cannot load the URL directly, GeoAgent returns the asset URL and a structured reason instead of pretending the layer was added.
load_result = tool_payload(
agent.tool.add_stac_asset_to_qgis(
asset_href=asset["href"],
layer_name=f"{first['collection']} {asset['key']}",
)
)
loaded_layers = [layer.name() for layer in project.mapLayers().values()]
load_result, loaded_layers