Work with raster and imagery data including ImageryLayer, ImageryTileLayer, multidimensional data, pixel filtering, and raster analysis. Use for satellite imagery, elevation data, and scientific raster datasets.
Install
npx skillscat add saschabrunnerch/arcgis-maps-sdk-js-ai-context/arcgis-imagery Install via the SkillsCat registry.
SKILL.md
ArcGIS Imagery
Use this skill for working with raster imagery, pixel-level operations, and multidimensional data.
ImageryLayer
Basic ImageryLayer
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
const imageryLayer = new ImageryLayer({
url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/ScientificData/SeaTemperature/ImageServer"
});
map.add(imageryLayer);ImageryLayer with Popup
const imageryLayer = new ImageryLayer({
url: "...",
popupTemplate: {
title: "Raster Value",
content: "{Raster.ServicePixelValue}"
}
});ImageryTileLayer
Basic ImageryTileLayer
import ImageryTileLayer from "@arcgis/core/layers/ImageryTileLayer.js";
const imageryTileLayer = new ImageryTileLayer({
url: "https://tiledimageservices.arcgis.com/..."
});
map.add(imageryTileLayer);Cloud Optimized GeoTIFF (COG)
const imageryTileLayer = new ImageryTileLayer({
url: "https://example.com/image.tif",
title: "COG Layer"
});Multidimensional Data
DimensionalDefinition
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
import DimensionalDefinition from "@arcgis/core/layers/support/DimensionalDefinition.js";
import MosaicRule from "@arcgis/core/layers/support/MosaicRule.js";
// Define dimensions (depth, time, etc.)
const dimInfo = [];
// Depth dimension
dimInfo.push(new DimensionalDefinition({
dimensionName: "StdZ",
values: [0], // Surface level
isSlice: true
}));
// Time dimension
dimInfo.push(new DimensionalDefinition({
dimensionName: "StdTime",
values: [1396828800000], // Timestamp in milliseconds
isSlice: true
}));
const mosaicRule = new MosaicRule({
multidimensionalDefinition: dimInfo
});
const layer = new ImageryLayer({
url: "...",
mosaicRule: mosaicRule
});Accessing Multidimensional Info
await imageryLayer.load();
// Get available dimensions
const dimensions = imageryLayer.multidimensionalInfo.dimensions;
dimensions.forEach(dim => {
console.log("Dimension:", dim.name);
console.log("Values:", dim.values);
console.log("Unit:", dim.unit);
});Pixel Filtering
Custom Pixel Filter
const imageryLayer = new ImageryLayer({
url: "...",
pixelFilter: processPixels
});
function processPixels(pixelData) {
if (!pixelData || !pixelData.pixelBlock) return;
const pixelBlock = pixelData.pixelBlock;
const pixels = pixelBlock.pixels;
let mask = pixelBlock.mask;
const numPixels = pixelBlock.width * pixelBlock.height;
// Get statistics
const minVal = pixelBlock.statistics[0].minValue;
const maxVal = pixelBlock.statistics[0].maxValue;
const factor = 255 / (maxVal - minVal);
// Original single-band data
const band = pixels[0];
// Create RGB bands
const rBand = new Uint8Array(numPixels);
const gBand = new Uint8Array(numPixels);
const bBand = new Uint8Array(numPixels);
if (!mask) {
mask = new Uint8Array(numPixels);
mask.fill(1);
pixelBlock.mask = mask;
}
// Process each pixel
for (let i = 0; i < numPixels; i++) {
if (mask[i] === 0) continue;
const value = band[i];
const normalized = (value - minVal) * factor;
// Create color ramp (blue to red)
rBand[i] = normalized;
gBand[i] = 0;
bBand[i] = 255 - normalized;
}
// Update pixel block
pixelData.pixelBlock.pixels = [rBand, gBand, bBand];
pixelData.pixelBlock.statistics = null;
pixelData.pixelBlock.pixelType = "u8";
}Masking Pixels by Value
let minThreshold = 0;
let maxThreshold = 100;
function maskPixels(pixelData) {
if (!pixelData || !pixelData.pixelBlock) return;
const pixelBlock = pixelData.pixelBlock;
const pixels = pixelBlock.pixels[0];
let mask = pixelBlock.mask;
if (!mask) {
mask = new Uint8Array(pixels.length);
mask.fill(1);
pixelBlock.mask = mask;
}
for (let i = 0; i < pixels.length; i++) {
// Hide pixels outside threshold range
mask[i] = (pixels[i] >= minThreshold && pixels[i] <= maxThreshold) ? 1 : 0;
}
}
// Update thresholds and redraw
function updateThresholds(min, max) {
minThreshold = min;
maxThreshold = max;
imageryLayer.redraw();
}Rendering Rules
Apply Rendering Rule
import RasterFunction from "@arcgis/core/layers/support/RasterFunction.js";
// Hillshade rendering
const hillshadeFunction = new RasterFunction({
functionName: "Hillshade",
functionArguments: {
azimuth: 315,
altitude: 45,
zFactor: 1
}
});
imageryLayer.rasterFunction = hillshadeFunction;Common Rendering Rules
// Stretch
const stretchFunction = new RasterFunction({
functionName: "Stretch",
functionArguments: {
stretchType: 3, // Standard Deviation
numberOfStandardDeviations: 2
}
});
// Colormap
const colormapFunction = new RasterFunction({
functionName: "Colormap",
functionArguments: {
colormap: [[1, 255, 0, 0], [2, 0, 255, 0], [3, 0, 0, 255]]
}
});
// NDVI
const ndviFunction = new RasterFunction({
functionName: "NDVI",
functionArguments: {
visibleBandID: 3,
infraredBandID: 4
}
});Band Combinations
// Select specific bands
imageryLayer.bandIds = [4, 3, 2]; // NIR, Red, Green (False color)
// Common band combinations
// Natural color: [1, 2, 3] (R, G, B)
// False color: [4, 3, 2] (NIR, R, G)
// SWIR: [7, 5, 4] (SWIR, NIR, R)Identify (Query Pixel Values)
view.on("click", async (event) => {
const result = await imageryLayer.identify({
geometry: event.mapPoint,
returnGeometry: false,
returnCatalogItems: true
});
console.log("Pixel value:", result.value);
console.log("Catalog items:", result.catalogItems);
});Export Image
// Export visible extent as image
const imageParams = {
bbox: view.extent,
width: view.width,
height: view.height,
format: "png",
f: "image"
};
const imageUrl = imageryLayer.url + "/exportImage?" +
Object.entries(imageParams).map(([k, v]) => `${k}=${v}`).join("&");Raster Statistics
await imageryLayer.load();
// Get layer statistics from serviceRasterInfo
const stats = imageryLayer.serviceRasterInfo.statistics;
console.log("Min:", stats[0].min);
console.log("Max:", stats[0].max);
console.log("Mean:", stats[0].avg);
console.log("StdDev:", stats[0].stddev);Imagery Components
| Component | Purpose |
|---|---|
arcgis-oriented-imagery-viewer |
View and navigate oriented imagery |
arcgis-video-player |
Play video feeds from video services |
Reference Samples
layers-imagerylayer- Basic ImageryLayer usagelayers-imagery-pixelvalues- Querying pixel values from imagerylayers-imagery-multidimensional- Multidimensional imagery datalayers-imagerytilelayer- ImageryTileLayer usagelayers-imagerytilelayer-cog- Cloud-Optimized GeoTIFF with ImageryTileLayer
Common Pitfalls
Pixel filter performance: Complex pixel filters can slow rendering - optimize loops
Band array indices: Band IDs are often 1-based in services but 0-based in arrays
Coordinate systems: Imagery may need reprojection to match the view
Memory with large images: Use tiled imagery layers for large datasets
Pixel type conversion: Be careful when changing pixelType in pixel filters