Layers

Raster Layers

Cloud-Optimized GeoTIFF and satellite imagery visualization
Live Demo - GPU-accelerated COG visualization with Sentinel-2 imagery

COGLayer

Live Demo

GPU-accelerated Cloud-Optimized GeoTIFF visualization with automatic reprojection.

Installation

bun add @developmentseed/deck.gl-raster geotiff-geokeys-to-proj4

Features

  • Fully client-side (no server required)
  • GPU-accelerated rendering
  • Automatic CRS reprojection
  • Intelligent tile streaming
  • Overview level selection
  • Support for multi-band imagery

Basic Usage

<script setup lang="ts">
  import { VMap, VLayerDeckglCOG } from '@geoql/v-maplibre';

  const mapOptions = {
    style: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json',
    center: [31.5, 30.0],
    zoom: 8,
  };

  // Sentinel-2 RGB imagery COG
  const COG_URL = 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/36/Q/WD/2020/7/S2A_36QWD_20200701_0_L2A/TCI.tif';
</script>

<template>
  <VMap :options="mapOptions" style="height: 500px">
    <VLayerDeckglCOG
      id="cog-layer"
      :geotiff="COG_URL"
      @geotiff-load="(tiff, { geographicBounds }) => console.log('Loaded:', geographicBounds)"
    />
  </VMap>
</template>

Props

PropTypeDefaultDescription
idstringrequiredUnique layer identifier
geotiffstring | ArrayBuffer | BlobrequiredGeoTIFF source URL or data
tileSizenumber256Tile size in pixels
maxZoomnumber-Maximum zoom level
minZoomnumber0Minimum zoom level
opacitynumber1Layer opacity (0-1)
visiblebooleantrueLayer visibility
pickablebooleanfalseEnable picking
debugbooleanfalseShow debug overlay

Events

EventPayloadDescription
@geotiff-load(tiff, { geographicBounds })GeoTIFF loaded with bounds
@clickPickingInfoClicked on layer
@hoverPickingInfoHovering over layer

Fit to Bounds

<script setup lang="ts">
  import { shallowRef } from 'vue';
  import type { Map } from 'maplibre-gl';

  const mapInstance = shallowRef<Map | null>(null);

  const handleGeotiffLoad = (
    _tiff: unknown,
    { geographicBounds }: { geographicBounds: { west: number; south: number; east: number; north: number } }
  ) => {
    const { west, south, east, north } = geographicBounds;
    mapInstance.value?.fitBounds(
      [[west, south], [east, north]],
      { padding: 40, duration: 1000 }
    );
  };
</script>

<template>
  <VMap :options="mapOptions" @loaded="(map) => mapInstance = map">
    <VLayerDeckglCOG
      id="cog"
      :geotiff="cogUrl"
      @geotiff-load="handleGeotiffLoad"
    />
  </VMap>
</template>

Land Cover Example

Live Demo

Visualize NLCD land use classification data:

<VLayerDeckglCOG
  id="landcover"
  :geotiff="nlcdUrl"
  :opacity="0.7"
/>

MosaicLayer

Live Demo

Client-side COG mosaic layer that renders multiple Cloud-Optimized GeoTIFFs from STAC items. All rendering happens in the browser with no server required.

Installation

bun add @developmentseed/deck.gl-raster @developmentseed/deck.gl-geotiff geotiff flatbush proj4

Features

  • Fully client-side mosaicking (no tile server required)
  • STAC API integration for discovering imagery
  • Multiple render modes: True Color, False Color Infrared, NDVI
  • GPU-accelerated rendering with automatic reprojection
  • Spatial indexing for efficient tile loading
  • Support for 4-band imagery (RGBN)

Basic Usage

<script setup lang="ts">
  import { ref, onMounted } from 'vue';
  import {
    VMap,
    VLayerDeckglMosaic,
    type MosaicSource,
    type MosaicRenderMode,
  } from '@geoql/v-maplibre';

  const mapOptions = {
    style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
    center: [-104.9903, 39.7392],
    zoom: 10,
  };

  const renderMode = ref<MosaicRenderMode>('trueColor');
  const stacItems = ref<MosaicSource[]>([]);

  // Fetch STAC items from Microsoft Planetary Computer
  async function fetchSTACItems() {
    const params = {
      collections: 'naip',
      bbox: '-106.6,38.7,-104.6,40.4',
      datetime: '2023-01-01/2023-12-31',
      limit: '1000',
    };

    const response = await fetch(
      'https://planetarycomputer.microsoft.com/api/stac/v1/search?' +
      new URLSearchParams(params)
    );
    const { features } = await response.json();
    stacItems.value = features;
  }

  onMounted(fetchSTACItems);
</script>

<template>
  <VMap :options="mapOptions" style="height: 500px">
    <VLayerDeckglMosaic
      v-if="stacItems.length > 0"
      id="naip-mosaic"
      :sources="stacItems"
      :render-mode="renderMode"
    />
  </VMap>
</template>

Props

PropTypeDefaultDescription
idstringrequiredUnique layer identifier
sourcesMosaicSource[]requiredArray of STAC-like items with bbox and COG asset URLs
renderMode'trueColor' | 'falseColor' | 'ndvi' | 'custom''trueColor'Render mode for band combination
customRenderModulesFunction-Custom render modules (only used when renderMode is 'custom')
colormapDataUint8ClampedArraycfastieCustom colormap texture data for NDVI (256 RGBA colors)
maxCacheSizenumberInfinityMaximum number of tiles to cache
beforeIdstring-Insert layer before this layer ID
opacitynumber1Layer opacity (0-1)
visiblebooleantrueLayer visibility
pickablebooleanfalseEnable picking

Events

EventPayloadDescription
@source-loadMosaicSourceCOG source loaded successfully
@error(Error, MosaicSource?)Error loading a COG source
@clickPickingInfoClicked on layer
@hoverPickingInfoHovering over layer

Render Modes

ModeDescription
trueColorRGB composite (bands 1, 2, 3)
falseColorFalse Color Infrared - NIR, Red, Green (bands 4, 1, 2) - highlights vegetation
ndviNormalized Difference Vegetation Index with cfastie colormap
customUse customRenderModules prop for custom band math

MosaicSource Type

interface MosaicSource {
  bbox: [number, number, number, number]; // [west, south, east, north]
  assets: {
    image: {
      href: string; // URL to the COG file
    };
  };
}

This matches the STAC Item format, so you can pass STAC search results directly.

Supported CRS

The component includes built-in support for:

  • EPSG:4326 (WGS84)
  • EPSG:3857 (Web Mercator)
  • EPSG:26910-26919 (NAD83 / UTM zones 10-19 for continental US)

For other CRS, you'll need to register them with proj4 before using.

IDW Interpolation Heatmap

Live Demo

For Inverse Distance Weighting interpolation (temperature, pollution, continuous values), use maplibre-gl-interpolate-heatmap:

bun add maplibre-gl-interpolate-heatmap

This is different from deck.gl's density heatmap - it calculates weighted averages rather than point density. See the live example for implementation details.