# GeoJSON Strategy This page describes how OCLI generates the database-facing GeoJSON Feature for UI consumption. It covers the default GeoJsonStrategy (ai makegeojson) and the underlying make_geo_json implementation. - Code: ocli/ocli/ai/makegeojson_strategy.py (strategy wrapper) - Core: ocli/ocli/ai/export_tools.py → make_geo_json() - Related: ocli/ocli/ai/upload_strategy.py (publishing), docs/Upload_strategy.md ## What it does The GeoJsonStrategy produces a single GeoJSON Feature that represents an output raster (or media) and its metadata. The Feature is written next to the main output file as .tiff.geojson and is later uploaded together with the COG by the Upload Strategy. ## Default workflow (ai makegeojson) 1. Load recipe and CLI context (ctx.meta): - COS_KEY: optional override/append for properties.ResultKey - FRIENDLY_NAME: optional override/append for properties.friendly_name - COG_PATH: optional path to the COG input; defaults to Filenames(GlobalProperties.ZONE, recipe).out_cog_tiff - WITH_DEM / WITH_DEM_NORMALS: include auxiliary dem URLs in source 2. Normalize recipe keys: - Ensure recipe.COS.ResultKey reflects COS_KEY override - Ensure recipe.friendly_name reflects FRIENDLY_NAME override 3. Call export_tools.make_geo_json(recipe, cog_path, with_dem, with_dem_normals) 4. Save Feature to disk as f"{cog_path}.geojson" ## Requirements in recipe The defaults expect these keys to be present in the recipe: - COS: - endpoint: base endpoint for backing file URLs (or endpointForDocument) - bucket: target bucket/namespace (e.g., staging) - ResultKey: object key for the main output; a .tiff extension is enforced if missing - GeoJSON.tile: - schema: must be "Tangram" - type: usually "Raster" - url: tiler endpoint, e.g., "/tiler/tiles/{z}/{x}/{y}@2x" - url_params: optional; url will be filled with endpoint/bucket/ResultKey.tiff - tileSize: optional; defaults to 512 - attribution: optional; copied to properties.source.attribution ## Feature structure (DB‑aligned) The produced document conforms to the DB schema used by the UI. Top-level fields: - type: Feature - geometry: taken from GDAL wgs84Extent of the COG (polygon envelope) - created: UTC timestamp - kind, class: copied from recipe if present - draft: false properties: - version: from recipe.version or 1.0 - friendly_name: from recipe - type: from recipe.type (e.g., Image, DEM, Scalar) - ResultKey, Bucket, Endpoint: from recipe.COS - source: composed for tiler consumption - type, url: from recipe.GeoJSON.tile - max_zoom: computed max WebMercator zoom for the COG + 2 (buffer) - tileSize: copied from recipe or 512 - url_params.url: http(s) endpoint to the backing COG: //.tiff - url_dem: //.dem.tiff when WITH_DEM - url_dem_normals: //.dem_normals.tiff when WITH_DEM_NORMALS - attribution: optional - bands: derived from GDAL Info and recipe.band_meta - band_ids: display names - band_meta: per-band fields: band, name, type, min, max, domain_min/max, color_map, etc. - If recipe.domain_min/domain_max/domain_diffmax are present, they are applied to bands - If recipe.color_map is provided, it is attached (preset name or object) - roles: from recipe.properties.roles or ["demo_read", "draft_read"] by default - classification: resolved from recipe.kind and/or recipe.metadata_preset using mapping files - tag: recipe.tag (if any) - visible_metadata: passthrough when present Additional top-level keys set when available: - meta: passthrough from recipe.meta ## Example (excerpt) ```json { "type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[4.49,53.24],[4.46,52.25],[6.07,52.22],[6.14,53.20],[4.49,53.24]]]}, "properties": { "type": "Image", "friendly_name": "default/composite/example", "ResultKey": "default/composite/example.tiff", "Bucket": "staging", "Endpoint": "https://s3.optoss.net", "source": { "url": "/tiler/tiles/{z}/{x}/{y}@2x", "type": "Raster", "max_zoom": 16, "tileSize": 512, "url_params": { "url": "s3:////" } }, "bands": { "band_ids": ["R","G","B","A"], "band_meta": [ {"band":1, "name":"R", "type":"Byte", "min":0, "max":255, "domain_min":0, "domain_max":255} ] }, "roles": ["public_read"], "classification": {"ocli":[3]} }, "created": "2025-10-22T14:25:00+0000", "kind": "ard-raster", "class": "product", "draft": false } ``` ## CLI tips - COS key override: --cos-key "+/suffix" appends to the current ResultKey; without plus replaces it - Friendly name override: --friendly-name works the same way - Provide --with-dem / --with-dem-normals to add auxiliary DEM URLs to properties.source - Use --cog-path to point at a specific COG if not using the standard output path - Use --print-res and --less to pretty-print the produced JSON in the terminal ## Relation to Upload Strategy The Upload Strategy is responsible for uploading the output files to storage. By default, after make_geo_json runs, UploadStrategy will upload: - .tiff - .tiff.geojson (this document) - .dem.tiff (optional) - .dem_normals.tiff (optional) - .document.geojson (the UI collection/document listing) See Upload Strategy for details on how the file list is assembled and how cos_key is resolved: ../../Upload_strategy.md ## Customization hooks - If an AIKP provides its own make_geo_json module at ocli/aikp/document/media/make_geo_json.py with execute(ctx, task), it will be used instead of the default one.