@saschabrunnerch/arcgis-maps-sdk-js-ai-context 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -203
- package/bin/cli.js +157 -173
- package/contexts/4.34/{claude → skills}/arcgis-3d-advanced/SKILL.md +586 -586
- package/contexts/4.34/{claude → skills}/arcgis-advanced-layers/SKILL.md +431 -431
- package/contexts/4.34/{claude → skills}/arcgis-analysis-services/SKILL.md +607 -607
- package/contexts/4.34/{claude → skills}/arcgis-authentication/SKILL.md +301 -301
- package/contexts/4.34/{claude → skills}/arcgis-cim-symbols/SKILL.md +486 -486
- package/contexts/4.34/{claude → skills}/arcgis-coordinates-projection/SKILL.md +406 -406
- package/contexts/4.34/{claude → skills}/arcgis-core-maps/SKILL.md +739 -739
- package/contexts/4.34/{claude → skills}/arcgis-core-utilities/SKILL.md +732 -732
- package/contexts/4.34/{claude → skills}/arcgis-custom-rendering/SKILL.md +445 -445
- package/contexts/4.34/{claude → skills}/arcgis-editing-advanced/SKILL.md +702 -702
- package/contexts/4.34/{claude → skills}/arcgis-feature-effects/SKILL.md +393 -393
- package/contexts/4.34/{claude → skills}/arcgis-geometry-operations/SKILL.md +489 -489
- package/contexts/4.34/{claude → skills}/arcgis-imagery/SKILL.md +307 -307
- package/contexts/4.34/{claude → skills}/arcgis-interaction/SKILL.md +572 -572
- package/contexts/4.34/{claude → skills}/arcgis-knowledge-graphs/SKILL.md +582 -582
- package/contexts/4.34/{claude → skills}/arcgis-layers/SKILL.md +601 -601
- package/contexts/4.34/{claude → skills}/arcgis-map-tools/SKILL.md +668 -668
- package/contexts/4.34/{claude → skills}/arcgis-media-layers/SKILL.md +290 -290
- package/contexts/4.34/{claude → skills}/arcgis-portal-content/SKILL.md +679 -679
- package/contexts/4.34/{claude → skills}/arcgis-scene-effects/SKILL.md +512 -512
- package/contexts/4.34/{claude → skills}/arcgis-smart-mapping/SKILL.md +686 -686
- package/contexts/4.34/{claude → skills}/arcgis-starter-app-extended/SKILL.md +649 -649
- package/contexts/4.34/{claude → skills}/arcgis-tables-forms/SKILL.md +877 -877
- package/contexts/4.34/{claude → skills}/arcgis-time-animation/SKILL.md +722 -722
- package/contexts/4.34/{claude → skills}/arcgis-utility-networks/SKILL.md +301 -301
- package/contexts/4.34/{claude → skills}/arcgis-visualization/SKILL.md +580 -580
- package/contexts/4.34/{claude → skills}/arcgis-widgets-ui/SKILL.md +574 -574
- package/lib/installer.js +19 -104
- package/package.json +45 -45
- package/contexts/4.34/copilot/arcgis-3d.instructions.md +0 -267
- package/contexts/4.34/copilot/arcgis-analysis.instructions.md +0 -294
- package/contexts/4.34/copilot/arcgis-arcade.instructions.md +0 -234
- package/contexts/4.34/copilot/arcgis-authentication.instructions.md +0 -187
- package/contexts/4.34/copilot/arcgis-cim-symbols.instructions.md +0 -177
- package/contexts/4.34/copilot/arcgis-core-maps.instructions.md +0 -246
- package/contexts/4.34/copilot/arcgis-core-utilities.instructions.md +0 -247
- package/contexts/4.34/copilot/arcgis-editing.instructions.md +0 -262
- package/contexts/4.34/copilot/arcgis-geometry.instructions.md +0 -225
- package/contexts/4.34/copilot/arcgis-layers.instructions.md +0 -278
- package/contexts/4.34/copilot/arcgis-popup-templates.instructions.md +0 -266
- package/contexts/4.34/copilot/arcgis-portal-advanced.instructions.md +0 -275
- package/contexts/4.34/copilot/arcgis-smart-mapping.instructions.md +0 -184
- package/contexts/4.34/copilot/arcgis-starter-app-extended.instructions.md +0 -643
- package/contexts/4.34/copilot/arcgis-starter-app.instructions.md +0 -268
- package/contexts/4.34/copilot/arcgis-time-animation.instructions.md +0 -112
- package/contexts/4.34/copilot/arcgis-visualization.instructions.md +0 -321
- package/contexts/4.34/copilot/arcgis-widgets-ui.instructions.md +0 -277
- /package/contexts/4.34/{claude → skills}/arcgis-arcade/SKILL.md +0 -0
- /package/contexts/4.34/{claude → skills}/arcgis-popup-templates/SKILL.md +0 -0
- /package/contexts/4.34/{claude → skills}/arcgis-starter-app/SKILL.md +0 -0
|
@@ -1,307 +1,307 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arcgis-imagery
|
|
3
|
-
description: 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.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# ArcGIS Imagery
|
|
7
|
-
|
|
8
|
-
Use this skill for working with raster imagery, pixel-level operations, and multidimensional data.
|
|
9
|
-
|
|
10
|
-
## ImageryLayer
|
|
11
|
-
|
|
12
|
-
### Basic ImageryLayer
|
|
13
|
-
```javascript
|
|
14
|
-
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
|
|
15
|
-
|
|
16
|
-
const imageryLayer = new ImageryLayer({
|
|
17
|
-
url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/ScientificData/SeaTemperature/ImageServer"
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
map.add(imageryLayer);
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### ImageryLayer with Popup
|
|
24
|
-
```javascript
|
|
25
|
-
const imageryLayer = new ImageryLayer({
|
|
26
|
-
url: "...",
|
|
27
|
-
popupTemplate: {
|
|
28
|
-
title: "Raster Value",
|
|
29
|
-
content: "{Raster.ServicePixelValue}"
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## ImageryTileLayer
|
|
35
|
-
|
|
36
|
-
### Basic ImageryTileLayer
|
|
37
|
-
```javascript
|
|
38
|
-
import ImageryTileLayer from "@arcgis/core/layers/ImageryTileLayer.js";
|
|
39
|
-
|
|
40
|
-
const imageryTileLayer = new ImageryTileLayer({
|
|
41
|
-
url: "https://tiledimageservices.arcgis.com/..."
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
map.add(imageryTileLayer);
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Cloud Optimized GeoTIFF (COG)
|
|
48
|
-
```javascript
|
|
49
|
-
const imageryTileLayer = new ImageryTileLayer({
|
|
50
|
-
url: "https://example.com/image.tif",
|
|
51
|
-
title: "COG Layer"
|
|
52
|
-
});
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Multidimensional Data
|
|
56
|
-
|
|
57
|
-
### DimensionalDefinition
|
|
58
|
-
```javascript
|
|
59
|
-
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
|
|
60
|
-
import DimensionalDefinition from "@arcgis/core/layers/support/DimensionalDefinition.js";
|
|
61
|
-
import MosaicRule from "@arcgis/core/layers/support/MosaicRule.js";
|
|
62
|
-
|
|
63
|
-
// Define dimensions (depth, time, etc.)
|
|
64
|
-
const dimInfo = [];
|
|
65
|
-
|
|
66
|
-
// Depth dimension
|
|
67
|
-
dimInfo.push(new DimensionalDefinition({
|
|
68
|
-
dimensionName: "StdZ",
|
|
69
|
-
values: [0], // Surface level
|
|
70
|
-
isSlice: true
|
|
71
|
-
}));
|
|
72
|
-
|
|
73
|
-
// Time dimension
|
|
74
|
-
dimInfo.push(new DimensionalDefinition({
|
|
75
|
-
dimensionName: "StdTime",
|
|
76
|
-
values: [1396828800000], // Timestamp in milliseconds
|
|
77
|
-
isSlice: true
|
|
78
|
-
}));
|
|
79
|
-
|
|
80
|
-
const mosaicRule = new MosaicRule({
|
|
81
|
-
multidimensionalDefinition: dimInfo
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const layer = new ImageryLayer({
|
|
85
|
-
url: "...",
|
|
86
|
-
mosaicRule: mosaicRule
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Accessing Multidimensional Info
|
|
91
|
-
```javascript
|
|
92
|
-
await imageryLayer.load();
|
|
93
|
-
|
|
94
|
-
// Get available dimensions
|
|
95
|
-
const dimensions = imageryLayer.multidimensionalInfo.dimensions;
|
|
96
|
-
|
|
97
|
-
dimensions.forEach(dim => {
|
|
98
|
-
console.log("Dimension:", dim.name);
|
|
99
|
-
console.log("Values:", dim.values);
|
|
100
|
-
console.log("Unit:", dim.unit);
|
|
101
|
-
});
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Pixel Filtering
|
|
105
|
-
|
|
106
|
-
### Custom Pixel Filter
|
|
107
|
-
```javascript
|
|
108
|
-
const imageryLayer = new ImageryLayer({
|
|
109
|
-
url: "...",
|
|
110
|
-
pixelFilter: processPixels
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
function processPixels(pixelData) {
|
|
114
|
-
if (!pixelData || !pixelData.pixelBlock) return;
|
|
115
|
-
|
|
116
|
-
const pixelBlock = pixelData.pixelBlock;
|
|
117
|
-
const pixels = pixelBlock.pixels;
|
|
118
|
-
let mask = pixelBlock.mask;
|
|
119
|
-
const numPixels = pixelBlock.width * pixelBlock.height;
|
|
120
|
-
|
|
121
|
-
// Get statistics
|
|
122
|
-
const minVal = pixelBlock.statistics[0].minValue;
|
|
123
|
-
const maxVal = pixelBlock.statistics[0].maxValue;
|
|
124
|
-
const factor = 255 / (maxVal - minVal);
|
|
125
|
-
|
|
126
|
-
// Original single-band data
|
|
127
|
-
const band = pixels[0];
|
|
128
|
-
|
|
129
|
-
// Create RGB bands
|
|
130
|
-
const rBand = new Uint8Array(numPixels);
|
|
131
|
-
const gBand = new Uint8Array(numPixels);
|
|
132
|
-
const bBand = new Uint8Array(numPixels);
|
|
133
|
-
|
|
134
|
-
if (!mask) {
|
|
135
|
-
mask = new Uint8Array(numPixels);
|
|
136
|
-
mask.fill(1);
|
|
137
|
-
pixelBlock.mask = mask;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Process each pixel
|
|
141
|
-
for (let i = 0; i < numPixels; i++) {
|
|
142
|
-
if (mask[i] === 0) continue;
|
|
143
|
-
|
|
144
|
-
const value = band[i];
|
|
145
|
-
const normalized = (value - minVal) * factor;
|
|
146
|
-
|
|
147
|
-
// Create color ramp (blue to red)
|
|
148
|
-
rBand[i] = normalized;
|
|
149
|
-
gBand[i] = 0;
|
|
150
|
-
bBand[i] = 255 - normalized;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Update pixel block
|
|
154
|
-
pixelData.pixelBlock.pixels = [rBand, gBand, bBand];
|
|
155
|
-
pixelData.pixelBlock.statistics = null;
|
|
156
|
-
pixelData.pixelBlock.pixelType = "u8";
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Masking Pixels by Value
|
|
161
|
-
```javascript
|
|
162
|
-
let minThreshold = 0;
|
|
163
|
-
let maxThreshold = 100;
|
|
164
|
-
|
|
165
|
-
function maskPixels(pixelData) {
|
|
166
|
-
if (!pixelData || !pixelData.pixelBlock) return;
|
|
167
|
-
|
|
168
|
-
const pixelBlock = pixelData.pixelBlock;
|
|
169
|
-
const pixels = pixelBlock.pixels[0];
|
|
170
|
-
let mask = pixelBlock.mask;
|
|
171
|
-
|
|
172
|
-
if (!mask) {
|
|
173
|
-
mask = new Uint8Array(pixels.length);
|
|
174
|
-
mask.fill(1);
|
|
175
|
-
pixelBlock.mask = mask;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
for (let i = 0; i < pixels.length; i++) {
|
|
179
|
-
// Hide pixels outside threshold range
|
|
180
|
-
mask[i] = (pixels[i] >= minThreshold && pixels[i] <= maxThreshold) ? 1 : 0;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Update thresholds and redraw
|
|
185
|
-
function updateThresholds(min, max) {
|
|
186
|
-
minThreshold = min;
|
|
187
|
-
maxThreshold = max;
|
|
188
|
-
imageryLayer.redraw();
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
## Rendering Rules
|
|
193
|
-
|
|
194
|
-
### Apply Rendering Rule
|
|
195
|
-
```javascript
|
|
196
|
-
import RasterFunction from "@arcgis/core/layers/support/RasterFunction.js";
|
|
197
|
-
|
|
198
|
-
// Hillshade rendering
|
|
199
|
-
const hillshadeFunction = new RasterFunction({
|
|
200
|
-
functionName: "Hillshade",
|
|
201
|
-
functionArguments: {
|
|
202
|
-
azimuth: 315,
|
|
203
|
-
altitude: 45,
|
|
204
|
-
zFactor: 1
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
imageryLayer.renderingRule = hillshadeFunction;
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Common Rendering Rules
|
|
212
|
-
```javascript
|
|
213
|
-
// Stretch
|
|
214
|
-
const stretchFunction = new RasterFunction({
|
|
215
|
-
functionName: "Stretch",
|
|
216
|
-
functionArguments: {
|
|
217
|
-
stretchType: 3, // Standard Deviation
|
|
218
|
-
numberOfStandardDeviations: 2
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Colormap
|
|
223
|
-
const colormapFunction = new RasterFunction({
|
|
224
|
-
functionName: "Colormap",
|
|
225
|
-
functionArguments: {
|
|
226
|
-
colormap: [[1, 255, 0, 0], [2, 0, 255, 0], [3, 0, 0, 255]]
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// NDVI
|
|
231
|
-
const ndviFunction = new RasterFunction({
|
|
232
|
-
functionName: "NDVI",
|
|
233
|
-
functionArguments: {
|
|
234
|
-
visibleBandID: 3,
|
|
235
|
-
infraredBandID: 4
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## Band Combinations
|
|
241
|
-
|
|
242
|
-
```javascript
|
|
243
|
-
// Select specific bands
|
|
244
|
-
imageryLayer.bandIds = [4, 3, 2]; // NIR, Red, Green (False color)
|
|
245
|
-
|
|
246
|
-
// Common band combinations
|
|
247
|
-
// Natural color: [1, 2, 3] (R, G, B)
|
|
248
|
-
// False color: [4, 3, 2] (NIR, R, G)
|
|
249
|
-
// SWIR: [7, 5, 4] (SWIR, NIR, R)
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Identify (Query Pixel Values)
|
|
253
|
-
|
|
254
|
-
```javascript
|
|
255
|
-
view.on("click", async (event) => {
|
|
256
|
-
const result = await imageryLayer.identify({
|
|
257
|
-
geometry: event.mapPoint,
|
|
258
|
-
returnGeometry: false,
|
|
259
|
-
returnCatalogItems: true
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
console.log("Pixel value:", result.value);
|
|
263
|
-
console.log("Catalog items:", result.catalogItems);
|
|
264
|
-
});
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Export Image
|
|
268
|
-
|
|
269
|
-
```javascript
|
|
270
|
-
// Export visible extent as image
|
|
271
|
-
const imageParams = {
|
|
272
|
-
bbox: view.extent,
|
|
273
|
-
width: view.width,
|
|
274
|
-
height: view.height,
|
|
275
|
-
format: "png",
|
|
276
|
-
f: "image"
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const imageUrl = imageryLayer.url + "/exportImage?" +
|
|
280
|
-
Object.entries(imageParams).map(([k, v]) => `${k}=${v}`).join("&");
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Raster Statistics
|
|
284
|
-
|
|
285
|
-
```javascript
|
|
286
|
-
await imageryLayer.load();
|
|
287
|
-
|
|
288
|
-
// Get layer statistics
|
|
289
|
-
const stats = imageryLayer.statistics;
|
|
290
|
-
console.log("Min:", stats[0].min);
|
|
291
|
-
console.log("Max:", stats[0].max);
|
|
292
|
-
console.log("Mean:", stats[0].mean);
|
|
293
|
-
console.log("StdDev:", stats[0].stddev);
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
## Common Pitfalls
|
|
297
|
-
|
|
298
|
-
1. **Pixel filter performance**: Complex pixel filters can slow rendering - optimize loops
|
|
299
|
-
|
|
300
|
-
2. **Band array indices**: Band IDs are often 1-based in services but 0-based in arrays
|
|
301
|
-
|
|
302
|
-
3. **Coordinate systems**: Imagery may need reprojection to match the view
|
|
303
|
-
|
|
304
|
-
4. **Memory with large images**: Use tiled imagery layers for large datasets
|
|
305
|
-
|
|
306
|
-
5. **Pixel type conversion**: Be careful when changing pixelType in pixel filters
|
|
307
|
-
|
|
1
|
+
---
|
|
2
|
+
name: arcgis-imagery
|
|
3
|
+
description: 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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ArcGIS Imagery
|
|
7
|
+
|
|
8
|
+
Use this skill for working with raster imagery, pixel-level operations, and multidimensional data.
|
|
9
|
+
|
|
10
|
+
## ImageryLayer
|
|
11
|
+
|
|
12
|
+
### Basic ImageryLayer
|
|
13
|
+
```javascript
|
|
14
|
+
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
|
|
15
|
+
|
|
16
|
+
const imageryLayer = new ImageryLayer({
|
|
17
|
+
url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/ScientificData/SeaTemperature/ImageServer"
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
map.add(imageryLayer);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### ImageryLayer with Popup
|
|
24
|
+
```javascript
|
|
25
|
+
const imageryLayer = new ImageryLayer({
|
|
26
|
+
url: "...",
|
|
27
|
+
popupTemplate: {
|
|
28
|
+
title: "Raster Value",
|
|
29
|
+
content: "{Raster.ServicePixelValue}"
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## ImageryTileLayer
|
|
35
|
+
|
|
36
|
+
### Basic ImageryTileLayer
|
|
37
|
+
```javascript
|
|
38
|
+
import ImageryTileLayer from "@arcgis/core/layers/ImageryTileLayer.js";
|
|
39
|
+
|
|
40
|
+
const imageryTileLayer = new ImageryTileLayer({
|
|
41
|
+
url: "https://tiledimageservices.arcgis.com/..."
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
map.add(imageryTileLayer);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Cloud Optimized GeoTIFF (COG)
|
|
48
|
+
```javascript
|
|
49
|
+
const imageryTileLayer = new ImageryTileLayer({
|
|
50
|
+
url: "https://example.com/image.tif",
|
|
51
|
+
title: "COG Layer"
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Multidimensional Data
|
|
56
|
+
|
|
57
|
+
### DimensionalDefinition
|
|
58
|
+
```javascript
|
|
59
|
+
import ImageryLayer from "@arcgis/core/layers/ImageryLayer.js";
|
|
60
|
+
import DimensionalDefinition from "@arcgis/core/layers/support/DimensionalDefinition.js";
|
|
61
|
+
import MosaicRule from "@arcgis/core/layers/support/MosaicRule.js";
|
|
62
|
+
|
|
63
|
+
// Define dimensions (depth, time, etc.)
|
|
64
|
+
const dimInfo = [];
|
|
65
|
+
|
|
66
|
+
// Depth dimension
|
|
67
|
+
dimInfo.push(new DimensionalDefinition({
|
|
68
|
+
dimensionName: "StdZ",
|
|
69
|
+
values: [0], // Surface level
|
|
70
|
+
isSlice: true
|
|
71
|
+
}));
|
|
72
|
+
|
|
73
|
+
// Time dimension
|
|
74
|
+
dimInfo.push(new DimensionalDefinition({
|
|
75
|
+
dimensionName: "StdTime",
|
|
76
|
+
values: [1396828800000], // Timestamp in milliseconds
|
|
77
|
+
isSlice: true
|
|
78
|
+
}));
|
|
79
|
+
|
|
80
|
+
const mosaicRule = new MosaicRule({
|
|
81
|
+
multidimensionalDefinition: dimInfo
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const layer = new ImageryLayer({
|
|
85
|
+
url: "...",
|
|
86
|
+
mosaicRule: mosaicRule
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Accessing Multidimensional Info
|
|
91
|
+
```javascript
|
|
92
|
+
await imageryLayer.load();
|
|
93
|
+
|
|
94
|
+
// Get available dimensions
|
|
95
|
+
const dimensions = imageryLayer.multidimensionalInfo.dimensions;
|
|
96
|
+
|
|
97
|
+
dimensions.forEach(dim => {
|
|
98
|
+
console.log("Dimension:", dim.name);
|
|
99
|
+
console.log("Values:", dim.values);
|
|
100
|
+
console.log("Unit:", dim.unit);
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Pixel Filtering
|
|
105
|
+
|
|
106
|
+
### Custom Pixel Filter
|
|
107
|
+
```javascript
|
|
108
|
+
const imageryLayer = new ImageryLayer({
|
|
109
|
+
url: "...",
|
|
110
|
+
pixelFilter: processPixels
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
function processPixels(pixelData) {
|
|
114
|
+
if (!pixelData || !pixelData.pixelBlock) return;
|
|
115
|
+
|
|
116
|
+
const pixelBlock = pixelData.pixelBlock;
|
|
117
|
+
const pixels = pixelBlock.pixels;
|
|
118
|
+
let mask = pixelBlock.mask;
|
|
119
|
+
const numPixels = pixelBlock.width * pixelBlock.height;
|
|
120
|
+
|
|
121
|
+
// Get statistics
|
|
122
|
+
const minVal = pixelBlock.statistics[0].minValue;
|
|
123
|
+
const maxVal = pixelBlock.statistics[0].maxValue;
|
|
124
|
+
const factor = 255 / (maxVal - minVal);
|
|
125
|
+
|
|
126
|
+
// Original single-band data
|
|
127
|
+
const band = pixels[0];
|
|
128
|
+
|
|
129
|
+
// Create RGB bands
|
|
130
|
+
const rBand = new Uint8Array(numPixels);
|
|
131
|
+
const gBand = new Uint8Array(numPixels);
|
|
132
|
+
const bBand = new Uint8Array(numPixels);
|
|
133
|
+
|
|
134
|
+
if (!mask) {
|
|
135
|
+
mask = new Uint8Array(numPixels);
|
|
136
|
+
mask.fill(1);
|
|
137
|
+
pixelBlock.mask = mask;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Process each pixel
|
|
141
|
+
for (let i = 0; i < numPixels; i++) {
|
|
142
|
+
if (mask[i] === 0) continue;
|
|
143
|
+
|
|
144
|
+
const value = band[i];
|
|
145
|
+
const normalized = (value - minVal) * factor;
|
|
146
|
+
|
|
147
|
+
// Create color ramp (blue to red)
|
|
148
|
+
rBand[i] = normalized;
|
|
149
|
+
gBand[i] = 0;
|
|
150
|
+
bBand[i] = 255 - normalized;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Update pixel block
|
|
154
|
+
pixelData.pixelBlock.pixels = [rBand, gBand, bBand];
|
|
155
|
+
pixelData.pixelBlock.statistics = null;
|
|
156
|
+
pixelData.pixelBlock.pixelType = "u8";
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Masking Pixels by Value
|
|
161
|
+
```javascript
|
|
162
|
+
let minThreshold = 0;
|
|
163
|
+
let maxThreshold = 100;
|
|
164
|
+
|
|
165
|
+
function maskPixels(pixelData) {
|
|
166
|
+
if (!pixelData || !pixelData.pixelBlock) return;
|
|
167
|
+
|
|
168
|
+
const pixelBlock = pixelData.pixelBlock;
|
|
169
|
+
const pixels = pixelBlock.pixels[0];
|
|
170
|
+
let mask = pixelBlock.mask;
|
|
171
|
+
|
|
172
|
+
if (!mask) {
|
|
173
|
+
mask = new Uint8Array(pixels.length);
|
|
174
|
+
mask.fill(1);
|
|
175
|
+
pixelBlock.mask = mask;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (let i = 0; i < pixels.length; i++) {
|
|
179
|
+
// Hide pixels outside threshold range
|
|
180
|
+
mask[i] = (pixels[i] >= minThreshold && pixels[i] <= maxThreshold) ? 1 : 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Update thresholds and redraw
|
|
185
|
+
function updateThresholds(min, max) {
|
|
186
|
+
minThreshold = min;
|
|
187
|
+
maxThreshold = max;
|
|
188
|
+
imageryLayer.redraw();
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Rendering Rules
|
|
193
|
+
|
|
194
|
+
### Apply Rendering Rule
|
|
195
|
+
```javascript
|
|
196
|
+
import RasterFunction from "@arcgis/core/layers/support/RasterFunction.js";
|
|
197
|
+
|
|
198
|
+
// Hillshade rendering
|
|
199
|
+
const hillshadeFunction = new RasterFunction({
|
|
200
|
+
functionName: "Hillshade",
|
|
201
|
+
functionArguments: {
|
|
202
|
+
azimuth: 315,
|
|
203
|
+
altitude: 45,
|
|
204
|
+
zFactor: 1
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
imageryLayer.renderingRule = hillshadeFunction;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Common Rendering Rules
|
|
212
|
+
```javascript
|
|
213
|
+
// Stretch
|
|
214
|
+
const stretchFunction = new RasterFunction({
|
|
215
|
+
functionName: "Stretch",
|
|
216
|
+
functionArguments: {
|
|
217
|
+
stretchType: 3, // Standard Deviation
|
|
218
|
+
numberOfStandardDeviations: 2
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Colormap
|
|
223
|
+
const colormapFunction = new RasterFunction({
|
|
224
|
+
functionName: "Colormap",
|
|
225
|
+
functionArguments: {
|
|
226
|
+
colormap: [[1, 255, 0, 0], [2, 0, 255, 0], [3, 0, 0, 255]]
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// NDVI
|
|
231
|
+
const ndviFunction = new RasterFunction({
|
|
232
|
+
functionName: "NDVI",
|
|
233
|
+
functionArguments: {
|
|
234
|
+
visibleBandID: 3,
|
|
235
|
+
infraredBandID: 4
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Band Combinations
|
|
241
|
+
|
|
242
|
+
```javascript
|
|
243
|
+
// Select specific bands
|
|
244
|
+
imageryLayer.bandIds = [4, 3, 2]; // NIR, Red, Green (False color)
|
|
245
|
+
|
|
246
|
+
// Common band combinations
|
|
247
|
+
// Natural color: [1, 2, 3] (R, G, B)
|
|
248
|
+
// False color: [4, 3, 2] (NIR, R, G)
|
|
249
|
+
// SWIR: [7, 5, 4] (SWIR, NIR, R)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Identify (Query Pixel Values)
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
view.on("click", async (event) => {
|
|
256
|
+
const result = await imageryLayer.identify({
|
|
257
|
+
geometry: event.mapPoint,
|
|
258
|
+
returnGeometry: false,
|
|
259
|
+
returnCatalogItems: true
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
console.log("Pixel value:", result.value);
|
|
263
|
+
console.log("Catalog items:", result.catalogItems);
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Export Image
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
// Export visible extent as image
|
|
271
|
+
const imageParams = {
|
|
272
|
+
bbox: view.extent,
|
|
273
|
+
width: view.width,
|
|
274
|
+
height: view.height,
|
|
275
|
+
format: "png",
|
|
276
|
+
f: "image"
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const imageUrl = imageryLayer.url + "/exportImage?" +
|
|
280
|
+
Object.entries(imageParams).map(([k, v]) => `${k}=${v}`).join("&");
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Raster Statistics
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
await imageryLayer.load();
|
|
287
|
+
|
|
288
|
+
// Get layer statistics
|
|
289
|
+
const stats = imageryLayer.statistics;
|
|
290
|
+
console.log("Min:", stats[0].min);
|
|
291
|
+
console.log("Max:", stats[0].max);
|
|
292
|
+
console.log("Mean:", stats[0].mean);
|
|
293
|
+
console.log("StdDev:", stats[0].stddev);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Common Pitfalls
|
|
297
|
+
|
|
298
|
+
1. **Pixel filter performance**: Complex pixel filters can slow rendering - optimize loops
|
|
299
|
+
|
|
300
|
+
2. **Band array indices**: Band IDs are often 1-based in services but 0-based in arrays
|
|
301
|
+
|
|
302
|
+
3. **Coordinate systems**: Imagery may need reprojection to match the view
|
|
303
|
+
|
|
304
|
+
4. **Memory with large images**: Use tiled imagery layers for large datasets
|
|
305
|
+
|
|
306
|
+
5. **Pixel type conversion**: Be careful when changing pixelType in pixel filters
|
|
307
|
+
|