Final visualisation strategy
Input > pre-processing > analysis > output > FINAL OUTPUT > upload
In this very generalised AIKP flow, FINAL OUTPUT signifies creation of the final version of data output (from AIKP) that would go to the COS and be presented in the webUI.
For raster data, that means creation of COG (raster) and GeoJSON (metadata).
For vector data, that means custom GeoJSON.
For tabular data, that means ….
For multidimensional data, that means ….
For time series, that means ….
ai makecog CLI command
/ocli/cli/ai.py
After desired output raster data is created inside the AIKP (as .tiff or ENVI), this general command/tool transformes it to COG.
determines the correct input/output files for a geospatial task (now DEM, DEM normals, or standard raster data)
verifies the input file exists and is unambiguous
calls make_cog function (
ocli/ai/export_tools/make_cog)
ocli/ai/export_tools/make_cog
responsible for generating a Cloud-Optimized GeoTIFF (COG) from a raster file using GDAL converts a raster input file (e.g. GeoTIFF or IMG) into a COG format
it’s essentially a polished wrapper around gdal.Translate() with added checks, logging, and smart config
input (what it expects) and output names predefined
input_default = filenames.pred8c
output_path = filenames.out_cog_tiff
def make_cog(input_path, output_path, callback=None, mask_band=None, nodata=None, bandList=None, overview_resampling='average'):
additional options:
full / zone = passed as
@argument_zone= full satellite image/tiff or bounding box around ROI (comes also from previous computational steps)–source
= override default input path, supports .geojsonand.tiff–nodata
= if not preset during visualization step –mask-band
= if not preset during visualization step –overview-resample <> = choice of resampling algorithms, options:
nearest = nearest neighbor interpolation, fastest, but can look blocky, best for categorical data
average = computes the mean value of the contributing input pixels, good for continuous data = DEFAULT
bilinear = bilinear interpolation, takes a weighted average of the 4 nearest input pixels, good for continuous rasters
cubic = bicubic interpolation, uses 16 surrounding pixels, produces smoother results than bilinear, but a bit slower, better for visual presentation or fine-scaled data
cubicspline =cubic spline interpolation, slower, but visually higher-quality
lanczos = high-quality interpolation using a Lanczos filter (sinc function), uses a larger neighborhood ( 6×6 pixels), slowest, but highest quality
ai makegeojson CLI command
ai/makegeojson_startegy.py
GeoJsonStrategy class is responsible for generating GeoJSON data based on a given task.
By default for raster data, it uses a standard method to generate metadata.
However, if a custom strategy is defined in the task’s configuration, it tries to dynamically import that custom logic and execute it.
This is used for other output data types like vector, for example.
When initialized, it checks if the task has a template configuration by looking for a specific module (make_geo_json.py) inside that template (which contains a custom execute() method).
if the custom module isn’t found, it logs a message and falls back to the default built-in
make_geojson_common()methodif the custom module is found and successfully loaded, it runs that.
Parameters
As always, additional options are available.
–friendly-name
--friendly-name="+task specific details"
The use of –friendly-name is recommended, as it helps with finding the result in the GUI and is generally more user friendly to have a file named for example “Croatia 20-01-2023” than “zfahkfahk3837ud_uh44”.
Friendly name separated by / creates the tree structure in webUI, allowing for easier file organization.
Beginning of friendly name can be set with task set command before recipe creation (task set friendly_name="user/chosen/strucutre/" ), while this option in makegeojson step allows for adding the last step/name of the published dataset based on user decided name.
--friendly-name="task specific details"- overrides friendly name.--friendly-name="+suffix_string"- appends the ‘suffix_string’ to existing friendly name.
–cos-key
--cos-key="+_v2"
The –cos-key parameter is not necessary when the publishing is done for the first (and only) time in the task, but if the same task is being reused to publish several different files, then the use of the cos key is mandatory.
--cos-key="custom/path/to/document"- override file name.--cos-key="+_suffix_string"- appends the ‘_suffix_string’ to existing file name (before the extension). Example:bucket/path/to/filename.glbbecomesbucket/path/to/filename_suffix_string.glb
–friendly-name and –cos-key collaboration
By default friendly-name and cos-key are taken from a task recipe.
In some cases, you may need/want to reuse the existing task to publish several artifacts.
So the use of --friendly-name and --cos-key simultaneously to override document name and file (artifact) name allows
to not override a previously published document.
--friendly-name and --cos-key changes corresponding parameters in GeoJSON document.
Then it published during ai publish post as is.
ai upload should upload produced task artifact with --cos-key taken from generated GeoJSON (by ai makegeojson command).
default makegeojson for raster data
ai/export_tools.py
This is where default make_geo_json() function is defined (used by make_geojson_common() method explained above).
When make_geo_json() is called, it generates a structured GeoJSON object based on raster metadata and configuration details from the recipe.
checks if the recipe contains all the necessary keys for generating GeoJSON—like the COS key (cloud storage unique key) and a result key
loads metadata from the specified raster file (cog_path) using GDAL tools, extracting coordinate bounds and zoom level
builds the properties for the GeoJSON: this includes information like the raster’s friendly name, storage location, roles, classification data (read from local JSON maps), and band info. Depending on the schema type (like ‘Tangram’), it composes tile source info as well.
packages all this into a GeoJSON Feature, attaches optional metadata, and returns it
custom makegeojson module
An example of this can be found in ocli/aikp/vector_basic/.
First, ai makegeojson CLI command triggers the GeoJsonStrategy in ai/makegeojson_startegy.py.
Since it is not a default raster data, it pickes up a custom module inside the AIKP ocli/aikp/vector_basic/make_geo_json.py.
This module contains execute() that creates (in vector_basic AIKP example) AssembleVectorData object using the current task and calls its run() method.
AssembleVectorData object is defined in the AIKP itself (as it can be specific for AIKP) and example can be found in ocli/aikp/vector_basic/assemble_recipe.py.
AIKP developers steps
If you’re working with raster data and want to use the default processing path
make sure your final output is prepared as a .tiff or ENVI file so that the
ai makecogcommand can convert it into a COG using the predefined input and output namesai makegeojsoncommand will automatically generate the associated GeoJSON metadata by invoking the standardmake_geo_json()function, which extracts key raster metadata and constructs a structured GeoJSON object
If you need custom logic for creating GeoJSON—for vector or other data—you have 2 options
Option 1
create a custom module named
make_geo_json.pywithin your AIKP templatemake_go_json.pymodule must containexecute()method with passed Repo and Task parameters:
@pass_task
@pass_repo
def execute(repo: Repo, task: Task) -> None:
# your custom logic here
GeoJsonStrategywill detect this custom module and execute itsexecute()method, replacing the default behavior with your custom GeoJSON generation process.RECIPE_DEFAULTSdictionary inconfig.pyof your AIKP should specify the module name containing theexecute()method:
RECIPE_DEFAULTS = {
'makegeojson': 'make_geo_json', # make_geo_json.py
# this name is up to you as a developer
# for example
'makegeojson': 'example_module' # and this name coresponds to the example_module.py inside of AIKP directory that has execute method
...}
Option 2
Implement makegeojson(cls, task: Task) function inside your TaskTemplate implementation