Source code for satorbis_kit.visualization.visualizer

"""Simple STAC visualizer using leafmap and TiTiler-pgSTAC."""

from typing import List, Optional
from urllib.parse import urlencode

import leafmap


[docs] class STACVisualizer: """Visualize STAC data using leafmap and TiTiler-pgSTAC. Simple wrapper around leafmap to add TiTiler-pgSTAC raster tiles. Example: >>> viz = STACVisualizer( ... titiler_endpoint="http://0.0.0.0:8081", ... api_key="your-api-key" ... ) >>> >>> m = viz.visualize( ... collection="TCX8021", ... assets="asset", ... center=[23.750, 77.698], ... zoom=13, ... colormap_name="ndvi", ... rescale="50,200" ... ) >>> m """ def __init__( self, titiler_endpoint: str, api_key: Optional[str] = None, tile_matrix_set: str = "WebMercatorQuad", api_key_param_name: str = "api_key", ): """Initialize the visualizer. Args: titiler_endpoint: TiTiler-pgSTAC base URL (e.g., 'http://0.0.0.0:8081') api_key: Optional API key for authentication (added to tile URLs as query parameter) tile_matrix_set: Tile matrix set (default: WebMercatorQuad) api_key_param_name: Query parameter name for API key (default: 'api_key') """ self.endpoint = titiler_endpoint.rstrip("/") self.api_key = api_key self.tile_matrix_set = tile_matrix_set self.api_key_param_name = api_key_param_name
[docs] def build_tile_url(self, collection: str, assets: str, **params) -> str: """Build TiTiler tile URL. Args: collection: STAC collection ID assets: Asset name(s) - comma-separated for multiple **params: Additional TiTiler parameters (colormap_name, rescale, etc.) Returns: Tile URL template Example: >>> viz = STACVisualizer("http://0.0.0.0:8081") >>> url = viz.build_tile_url( ... collection="TCX8021", ... assets="asset", ... colormap_name="ndvi", ... rescale="50,200" ... ) """ # Base tile URL base_url = ( f"{self.endpoint}/collections/{collection}/" f"tiles/{self.tile_matrix_set}/{{z}}/{{x}}/{{y}}" ) # Build query parameters query_params = {"assets": assets} query_params.update(params) # Add API key if provided (as query parameter) if self.api_key: query_params[self.api_key_param_name] = self.api_key # Build final URL query_string = urlencode(query_params) return f"{base_url}?{query_string}"
[docs] def visualize( self, collection: str, assets: str, center: List[float], zoom: int = 10, layer_name: Optional[str] = None, opacity: float = 0.8, basemap: str = "OpenStreetMap", **titiler_params, ) -> leafmap.Map: """Visualize a STAC collection. Args: collection: STAC collection ID assets: Asset name(s) to visualize center: Map center [lat, lon] zoom: Map zoom level layer_name: Custom layer name (default: collection ID) opacity: Layer opacity (0-1) basemap: Basemap name **titiler_params: Additional TiTiler parameters (colormap_name, rescale, etc.) Returns: leafmap.Map instance Example: >>> viz = STACVisualizer("http://0.0.0.0:8081") >>> m = viz.visualize( ... collection="TCX8021", ... assets="asset", ... center=[23.750, 77.698], ... zoom=13, ... colormap_name="ndvi", ... rescale="50,200" ... ) >>> m """ # Create map m = leafmap.Map(center=center, zoom=zoom) # Add basemap if basemap: m.add_basemap(basemap) # Build tile URL tile_url = self.build_tile_url(collection=collection, assets=assets, **titiler_params) # Add TiTiler raster tiles m.add_tile_layer( url=tile_url, name=layer_name or collection, attribution="TiTiler-pgSTAC", opacity=opacity, ) return m
[docs] def add_layer( self, map_instance: leafmap.Map, collection: str, assets: str, layer_name: Optional[str] = None, opacity: float = 0.8, **titiler_params, ) -> leafmap.Map: """Add a layer to an existing map. Args: map_instance: Existing leafmap.Map instance collection: STAC collection ID assets: Asset name(s) to visualize layer_name: Custom layer name opacity: Layer opacity (0-1) **titiler_params: Additional TiTiler parameters Returns: Updated leafmap.Map instance Example: >>> viz = STACVisualizer("http://0.0.0.0:8081") >>> m = leafmap.Map(center=[23.750, 77.698], zoom=13) >>> m = viz.add_layer( ... m, ... collection="TCX8021", ... assets="asset", ... colormap_name="ndvi" ... ) """ # Build tile URL tile_url = self.build_tile_url(collection=collection, assets=assets, **titiler_params) # Add layer map_instance.add_tile_layer( url=tile_url, name=layer_name or collection, attribution="TiTiler-pgSTAC", opacity=opacity, ) return map_instance