@saschabrunnerch/arcgis-maps-sdk-js-ai-context 0.0.1 → 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 -201
- 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/skills/arcgis-starter-app/SKILL.md +273 -0
- package/contexts/4.34/skills/arcgis-starter-app-extended/SKILL.md +649 -0
- 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 +294 -379
- 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-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
|
@@ -1,739 +1,739 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arcgis-core-maps
|
|
3
|
-
description: Create 2D and 3D maps using ArcGIS Maps SDK for JavaScript. Use for initializing maps, scenes, views, and navigation. Supports both Map Components (web components) and Core API approaches.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# ArcGIS Core Maps
|
|
7
|
-
|
|
8
|
-
Use this skill when creating 2D maps (MapView) or 3D scenes (SceneView) with the ArcGIS Maps SDK for JavaScript.
|
|
9
|
-
|
|
10
|
-
## Import Patterns
|
|
11
|
-
|
|
12
|
-
### Direct ESM Imports (Recommended for Build Tools)
|
|
13
|
-
Use with Vite, webpack, Rollup, or other build tools:
|
|
14
|
-
```javascript
|
|
15
|
-
import Map from "@arcgis/core/Map.js";
|
|
16
|
-
import MapView from "@arcgis/core/views/MapView.js";
|
|
17
|
-
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
18
|
-
```
|
|
19
|
-
- Tree-shakeable
|
|
20
|
-
- Standard JavaScript modules
|
|
21
|
-
- Best for production applications
|
|
22
|
-
|
|
23
|
-
### Dynamic Imports (CDN / No Build Tools)
|
|
24
|
-
Use with CDN script tags when no build step is available:
|
|
25
|
-
```javascript
|
|
26
|
-
const Map = await $arcgis.import("@arcgis/core/Map.js");
|
|
27
|
-
const MapView = await $arcgis.import("@arcgis/core/views/MapView.js");
|
|
28
|
-
|
|
29
|
-
// Multiple imports
|
|
30
|
-
const [FeatureLayer, Graphic] = await $arcgis.import([
|
|
31
|
-
"@arcgis/core/layers/FeatureLayer.js",
|
|
32
|
-
"@arcgis/core/Graphic.js"
|
|
33
|
-
]);
|
|
34
|
-
```
|
|
35
|
-
- Works with Map Components (web components)
|
|
36
|
-
- No build step required
|
|
37
|
-
- Good for quick prototypes and demos
|
|
38
|
-
- Requires `<script src="https://js.arcgis.com/4.34/"></script>` in HTML
|
|
39
|
-
|
|
40
|
-
> **Note:** The examples in this skill use Direct ESM imports. For CDN usage, replace `import X from "path"` with `const X = await $arcgis.import("path")`.
|
|
41
|
-
|
|
42
|
-
## Autocasting vs Explicit Classes (TypeScript)
|
|
43
|
-
|
|
44
|
-
The ArcGIS SDK supports [autocasting](https://developers.arcgis.com/javascript/latest/autocasting/) - passing plain objects instead of class instances. Understanding when to use each approach is important for TypeScript projects.
|
|
45
|
-
|
|
46
|
-
### When to Use Explicit Classes (Non-Autocast)
|
|
47
|
-
|
|
48
|
-
Use `new SimpleRenderer()`, `new Point()`, etc. when:
|
|
49
|
-
|
|
50
|
-
- **You need instance methods or `instanceof` checks**
|
|
51
|
-
- **Building shared internal libraries** - constructor APIs surface breaking changes at compile time
|
|
52
|
-
- **You want strong editor discoverability** - `new SimpleRenderer({ ... })` exposes properties clearly
|
|
53
|
-
- **You mutate objects incrementally** - long-lived instances are clearer as real classes
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer.js";
|
|
57
|
-
import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol.js";
|
|
58
|
-
|
|
59
|
-
const renderer = new SimpleRenderer({
|
|
60
|
-
symbol: new SimpleMarkerSymbol({
|
|
61
|
-
color: [226, 119, 40],
|
|
62
|
-
size: 8
|
|
63
|
-
})
|
|
64
|
-
});
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### When to Use Autocasting
|
|
68
|
-
|
|
69
|
-
Use plain objects with `type` property when:
|
|
70
|
-
|
|
71
|
-
- **Configuration-heavy code** - renderers, symbols, popups are usually data, not behavior
|
|
72
|
-
- **UI-driven configuration** - React state → plain objects → SDK properties is simpler
|
|
73
|
-
- **Serialization and reuse matter** - configs can be stored, diffed, tested, reused
|
|
74
|
-
- **Property updates after creation** - `layer.renderer = { ... }` works cleanly in React `useEffect`
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
// Use 'as const' or 'satisfies' to keep discriminated unions narrow
|
|
78
|
-
const renderer = {
|
|
79
|
-
type: "simple",
|
|
80
|
-
symbol: {
|
|
81
|
-
type: "simple-marker",
|
|
82
|
-
color: [226, 119, 40],
|
|
83
|
-
size: 8
|
|
84
|
-
}
|
|
85
|
-
} as const;
|
|
86
|
-
|
|
87
|
-
// Or with satisfies for better type inference
|
|
88
|
-
import type { SimpleRenderer } from "@arcgis/core/renderers/SimpleRenderer.js";
|
|
89
|
-
|
|
90
|
-
const renderer = {
|
|
91
|
-
type: "simple",
|
|
92
|
-
symbol: {
|
|
93
|
-
type: "simple-marker",
|
|
94
|
-
color: [226, 119, 40],
|
|
95
|
-
size: 8
|
|
96
|
-
}
|
|
97
|
-
} satisfies __esri.SimpleRendererProperties;
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### TypeScript Best Practices
|
|
101
|
-
|
|
102
|
-
The real TypeScript concern is keeping discriminated unions narrow:
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
// ❌ BAD - type widens to string
|
|
106
|
-
const symbol = { type: "simple-marker", color: "red" };
|
|
107
|
-
|
|
108
|
-
// ✅ GOOD - type stays literal
|
|
109
|
-
const symbol = { type: "simple-marker", color: "red" } as const;
|
|
110
|
-
|
|
111
|
-
// ✅ GOOD - explicit type annotation
|
|
112
|
-
const symbol: __esri.SimpleMarkerSymbolProperties = {
|
|
113
|
-
type: "simple-marker",
|
|
114
|
-
color: "red"
|
|
115
|
-
};
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Recommended Default
|
|
119
|
-
|
|
120
|
-
- **Autocast for configuration** (renderers, symbols, popups, labels)
|
|
121
|
-
- **Explicit classes for behavior** (when you need methods or instanceof)
|
|
122
|
-
- **Use `as const` or `satisfies`** to maintain type safety with autocasting
|
|
123
|
-
|
|
124
|
-
## Two Approaches
|
|
125
|
-
|
|
126
|
-
### 1. Map Components (Modern - Recommended)
|
|
127
|
-
Web components approach using `<arcgis-map>` and `<arcgis-scene>`.
|
|
128
|
-
|
|
129
|
-
### 2. Core API
|
|
130
|
-
Traditional JavaScript approach using `Map`, `MapView`, and `SceneView` classes.
|
|
131
|
-
|
|
132
|
-
## CDN Setup
|
|
133
|
-
|
|
134
|
-
### Map Components Approach
|
|
135
|
-
```html
|
|
136
|
-
<!DOCTYPE html>
|
|
137
|
-
<html lang="en">
|
|
138
|
-
<head>
|
|
139
|
-
<meta charset="utf-8" />
|
|
140
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
141
|
-
<title>ArcGIS Map</title>
|
|
142
|
-
<style>
|
|
143
|
-
html, body { height: 100%; margin: 0; }
|
|
144
|
-
</style>
|
|
145
|
-
<!-- Load Calcite components -->
|
|
146
|
-
<script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script>
|
|
147
|
-
<!-- Load ArcGIS Maps SDK -->
|
|
148
|
-
<script src="https://js.arcgis.com/4.34/"></script>
|
|
149
|
-
<!-- Load Map components -->
|
|
150
|
-
<script type="module" src="https://js.arcgis.com/4.34/map-components/"></script>
|
|
151
|
-
</head>
|
|
152
|
-
<body>
|
|
153
|
-
<arcgis-map basemap="topo-vector" center="-118.24,34.05" zoom="12">
|
|
154
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
155
|
-
</arcgis-map>
|
|
156
|
-
</body>
|
|
157
|
-
</html>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Core API Approach
|
|
161
|
-
```html
|
|
162
|
-
<!DOCTYPE html>
|
|
163
|
-
<html lang="en">
|
|
164
|
-
<head>
|
|
165
|
-
<meta charset="utf-8" />
|
|
166
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
167
|
-
<title>ArcGIS Map</title>
|
|
168
|
-
<style>
|
|
169
|
-
html, body, #viewDiv { height: 100%; margin: 0; }
|
|
170
|
-
</style>
|
|
171
|
-
<!-- REQUIRED: main.css for Core API -->
|
|
172
|
-
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
|
|
173
|
-
<script src="https://js.arcgis.com/4.34/"></script>
|
|
174
|
-
</head>
|
|
175
|
-
<body>
|
|
176
|
-
<div id="viewDiv"></div>
|
|
177
|
-
<script type="module">
|
|
178
|
-
import Map from "@arcgis/core/Map.js";
|
|
179
|
-
import MapView from "@arcgis/core/views/MapView.js";
|
|
180
|
-
|
|
181
|
-
const map = new Map({ basemap: "topo-vector" });
|
|
182
|
-
const view = new MapView({
|
|
183
|
-
container: "viewDiv",
|
|
184
|
-
map: map,
|
|
185
|
-
center: [-118.24, 34.05], // [longitude, latitude]
|
|
186
|
-
zoom: 12
|
|
187
|
-
});
|
|
188
|
-
</script>
|
|
189
|
-
</body>
|
|
190
|
-
</html>
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## 2D Maps
|
|
194
|
-
|
|
195
|
-
### Map Components
|
|
196
|
-
```html
|
|
197
|
-
<arcgis-map basemap="topo-vector" center="-118.24,34.05" zoom="12">
|
|
198
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
199
|
-
<arcgis-compass slot="top-left"></arcgis-compass>
|
|
200
|
-
<arcgis-home slot="top-left"></arcgis-home>
|
|
201
|
-
<arcgis-locate slot="top-left"></arcgis-locate>
|
|
202
|
-
</arcgis-map>
|
|
203
|
-
|
|
204
|
-
<script type="module">
|
|
205
|
-
const mapElement = document.querySelector("arcgis-map");
|
|
206
|
-
await mapElement.viewOnReady(); // Wait for view to be ready
|
|
207
|
-
const view = mapElement.view; // Access the MapView
|
|
208
|
-
const map = mapElement.map; // Access the Map
|
|
209
|
-
</script>
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Core API
|
|
213
|
-
```javascript
|
|
214
|
-
import Map from "@arcgis/core/Map.js";
|
|
215
|
-
import MapView from "@arcgis/core/views/MapView.js";
|
|
216
|
-
|
|
217
|
-
const map = new Map({ basemap: "streets-vector" });
|
|
218
|
-
|
|
219
|
-
const view = new MapView({
|
|
220
|
-
container: "viewDiv",
|
|
221
|
-
map: map,
|
|
222
|
-
center: [-118.24, 34.05],
|
|
223
|
-
zoom: 12,
|
|
224
|
-
// Optional constraints
|
|
225
|
-
constraints: {
|
|
226
|
-
minZoom: 5,
|
|
227
|
-
maxZoom: 18,
|
|
228
|
-
rotationEnabled: false
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## 3D Scenes
|
|
234
|
-
|
|
235
|
-
### Map Components
|
|
236
|
-
```html
|
|
237
|
-
<arcgis-scene basemap="topo-3d" ground="world-elevation">
|
|
238
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
239
|
-
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
|
|
240
|
-
</arcgis-scene>
|
|
241
|
-
|
|
242
|
-
<script type="module">
|
|
243
|
-
const sceneElement = document.querySelector("arcgis-scene");
|
|
244
|
-
await sceneElement.viewOnReady();
|
|
245
|
-
const view = sceneElement.view; // SceneView
|
|
246
|
-
</script>
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Core API
|
|
250
|
-
```javascript
|
|
251
|
-
import Map from "@arcgis/core/Map.js";
|
|
252
|
-
import SceneView from "@arcgis/core/views/SceneView.js";
|
|
253
|
-
|
|
254
|
-
const map = new Map({
|
|
255
|
-
basemap: "topo-3d",
|
|
256
|
-
ground: "world-elevation"
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
const view = new SceneView({
|
|
260
|
-
container: "viewDiv",
|
|
261
|
-
map: map,
|
|
262
|
-
camera: {
|
|
263
|
-
position: {
|
|
264
|
-
longitude: -118.24,
|
|
265
|
-
latitude: 34.05,
|
|
266
|
-
z: 25000 // altitude in meters
|
|
267
|
-
},
|
|
268
|
-
heading: 0, // compass direction
|
|
269
|
-
tilt: 45 // 0 = straight down, 90 = horizon
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## Loading WebMaps and WebScenes
|
|
275
|
-
|
|
276
|
-
### WebMap (2D)
|
|
277
|
-
```html
|
|
278
|
-
<!-- Map Components -->
|
|
279
|
-
<arcgis-map item-id="f2e9b762544945f390ca4ac3671cfa72">
|
|
280
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
281
|
-
</arcgis-map>
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
```javascript
|
|
285
|
-
// Core API
|
|
286
|
-
import MapView from "@arcgis/core/views/MapView.js";
|
|
287
|
-
import WebMap from "@arcgis/core/WebMap.js";
|
|
288
|
-
|
|
289
|
-
const webmap = new WebMap({
|
|
290
|
-
portalItem: { id: "f2e9b762544945f390ca4ac3671cfa72" }
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
const view = new MapView({
|
|
294
|
-
map: webmap,
|
|
295
|
-
container: "viewDiv"
|
|
296
|
-
});
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### WebScene (3D)
|
|
300
|
-
```html
|
|
301
|
-
<!-- Map Components -->
|
|
302
|
-
<arcgis-scene item-id="YOUR_WEBSCENE_ID">
|
|
303
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
304
|
-
</arcgis-scene>
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
```javascript
|
|
308
|
-
// Core API
|
|
309
|
-
import SceneView from "@arcgis/core/views/SceneView.js";
|
|
310
|
-
import WebScene from "@arcgis/core/WebScene.js";
|
|
311
|
-
|
|
312
|
-
const webscene = new WebScene({
|
|
313
|
-
portalItem: { id: "YOUR_WEBSCENE_ID" }
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
const view = new SceneView({
|
|
317
|
-
map: webscene,
|
|
318
|
-
container: "viewDiv"
|
|
319
|
-
});
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
## Navigation Components
|
|
323
|
-
|
|
324
|
-
| Component | Purpose |
|
|
325
|
-
|-----------|---------|
|
|
326
|
-
| `arcgis-zoom` | Zoom in/out buttons |
|
|
327
|
-
| `arcgis-compass` | Orientation indicator, click to reset north |
|
|
328
|
-
| `arcgis-home` | Return to initial extent |
|
|
329
|
-
| `arcgis-locate` | Find user's location |
|
|
330
|
-
| `arcgis-navigation-toggle` | Switch between pan/rotate modes (3D) |
|
|
331
|
-
| `arcgis-fullscreen` | Toggle fullscreen mode |
|
|
332
|
-
| `arcgis-scale-bar` | Display map scale |
|
|
333
|
-
|
|
334
|
-
### Slot Positions
|
|
335
|
-
```html
|
|
336
|
-
<arcgis-map basemap="streets-vector">
|
|
337
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
338
|
-
<arcgis-home slot="top-left"></arcgis-home>
|
|
339
|
-
<arcgis-search slot="top-right"></arcgis-search>
|
|
340
|
-
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
341
|
-
<arcgis-scale-bar slot="bottom-right"></arcgis-scale-bar>
|
|
342
|
-
</arcgis-map>
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
Available slots: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `manual`
|
|
346
|
-
|
|
347
|
-
## View Configuration
|
|
348
|
-
|
|
349
|
-
### Setting Initial Extent
|
|
350
|
-
```javascript
|
|
351
|
-
// By center and zoom
|
|
352
|
-
const view = new MapView({
|
|
353
|
-
container: "viewDiv",
|
|
354
|
-
map: map,
|
|
355
|
-
center: [-118.24, 34.05],
|
|
356
|
-
zoom: 12
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
// By scale
|
|
360
|
-
const view = new MapView({
|
|
361
|
-
container: "viewDiv",
|
|
362
|
-
map: map,
|
|
363
|
-
center: [-118.24, 34.05],
|
|
364
|
-
scale: 50000 // 1:50,000
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
// By extent
|
|
368
|
-
const view = new MapView({
|
|
369
|
-
container: "viewDiv",
|
|
370
|
-
map: map,
|
|
371
|
-
extent: {
|
|
372
|
-
xmin: -118.5,
|
|
373
|
-
ymin: 33.8,
|
|
374
|
-
xmax: -117.9,
|
|
375
|
-
ymax: 34.3,
|
|
376
|
-
spatialReference: { wkid: 4326 }
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### Programmatic Navigation
|
|
382
|
-
```javascript
|
|
383
|
-
// Go to location
|
|
384
|
-
await view.goTo({
|
|
385
|
-
center: [-118.24, 34.05],
|
|
386
|
-
zoom: 15
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// Animated navigation
|
|
390
|
-
await view.goTo(
|
|
391
|
-
{ center: [-118.24, 34.05], zoom: 15 },
|
|
392
|
-
{ duration: 2000, easing: "ease-in-out" }
|
|
393
|
-
);
|
|
394
|
-
|
|
395
|
-
// Go to extent
|
|
396
|
-
await view.goTo(layer.fullExtent);
|
|
397
|
-
|
|
398
|
-
// Go to features
|
|
399
|
-
await view.goTo(featureSet.features);
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### View Constraints
|
|
403
|
-
```javascript
|
|
404
|
-
// Constrain zoom levels
|
|
405
|
-
view.constraints = {
|
|
406
|
-
minZoom: 5,
|
|
407
|
-
maxZoom: 18
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
// Constrain to area
|
|
411
|
-
view.constraints = {
|
|
412
|
-
geometry: layer.fullExtent,
|
|
413
|
-
minScale: 500000
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// Disable rotation
|
|
417
|
-
view.constraints = {
|
|
418
|
-
rotationEnabled: false
|
|
419
|
-
};
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
## Event Handling
|
|
423
|
-
|
|
424
|
-
```javascript
|
|
425
|
-
// View ready
|
|
426
|
-
view.when(() => {
|
|
427
|
-
console.log("View is ready");
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
// Click event
|
|
431
|
-
view.on("click", (event) => {
|
|
432
|
-
console.log("Clicked at:", event.mapPoint);
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
// Pointer move
|
|
436
|
-
view.on("pointer-move", (event) => {
|
|
437
|
-
const point = view.toMap(event);
|
|
438
|
-
console.log("Mouse at:", point.longitude, point.latitude);
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
// Extent change
|
|
442
|
-
view.watch("extent", (extent) => {
|
|
443
|
-
console.log("Extent changed:", extent);
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
// Stationary (after pan/zoom completes)
|
|
447
|
-
view.watch("stationary", (isStationary) => {
|
|
448
|
-
if (isStationary) {
|
|
449
|
-
console.log("Navigation complete");
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
## Module Imports
|
|
455
|
-
|
|
456
|
-
```javascript
|
|
457
|
-
// Single import
|
|
458
|
-
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
459
|
-
|
|
460
|
-
// Multiple imports
|
|
461
|
-
import Map from "@arcgis/core/Map.js";
|
|
462
|
-
import MapView from "@arcgis/core/views/MapView.js";
|
|
463
|
-
import Graphic from "@arcgis/core/Graphic.js";
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
## Common Basemaps
|
|
467
|
-
|
|
468
|
-
| Basemap ID | Description |
|
|
469
|
-
|------------|-------------|
|
|
470
|
-
| `streets-vector` | Street map |
|
|
471
|
-
| `topo-vector` | Topographic |
|
|
472
|
-
| `satellite` | Satellite imagery |
|
|
473
|
-
| `hybrid` | Satellite with labels |
|
|
474
|
-
| `dark-gray-vector` | Dark gray canvas |
|
|
475
|
-
| `gray-vector` | Light gray canvas |
|
|
476
|
-
| `osm` | OpenStreetMap |
|
|
477
|
-
| `topo-3d` | 3D topographic (SceneView) |
|
|
478
|
-
|
|
479
|
-
## esriRequest (HTTP Requests)
|
|
480
|
-
|
|
481
|
-
### Basic Request
|
|
482
|
-
```javascript
|
|
483
|
-
import esriRequest from "@arcgis/core/request.js";
|
|
484
|
-
|
|
485
|
-
// GET request with JSON response
|
|
486
|
-
const response = await esriRequest(url, {
|
|
487
|
-
query: { f: "json" },
|
|
488
|
-
responseType: "json"
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
console.log("Status:", response.httpStatus);
|
|
492
|
-
console.log("Data:", response.data);
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### Request with Options
|
|
496
|
-
```javascript
|
|
497
|
-
const response = await esriRequest(url, {
|
|
498
|
-
query: {
|
|
499
|
-
f: "json",
|
|
500
|
-
param1: "value1"
|
|
501
|
-
},
|
|
502
|
-
responseType: "json", // "json", "text", "array-buffer", "blob", "image"
|
|
503
|
-
method: "post", // "auto", "get", "post"
|
|
504
|
-
body: formData, // For POST requests
|
|
505
|
-
timeout: 30000, // Timeout in ms
|
|
506
|
-
headers: {
|
|
507
|
-
"X-Custom-Header": "value"
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
### Download Binary Data
|
|
513
|
-
```javascript
|
|
514
|
-
// Image response
|
|
515
|
-
const imageResponse = await esriRequest(imageUrl, {
|
|
516
|
-
responseType: "image"
|
|
517
|
-
});
|
|
518
|
-
const imageElement = imageResponse.data;
|
|
519
|
-
|
|
520
|
-
// Binary data
|
|
521
|
-
const binaryResponse = await esriRequest(fileUrl, {
|
|
522
|
-
responseType: "array-buffer"
|
|
523
|
-
});
|
|
524
|
-
const arrayBuffer = binaryResponse.data;
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
## Planetary Visualization (Mars)
|
|
528
|
-
|
|
529
|
-
### Mars Scene
|
|
530
|
-
```html
|
|
531
|
-
<arcgis-scene>
|
|
532
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
533
|
-
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
|
|
534
|
-
</arcgis-scene>
|
|
535
|
-
|
|
536
|
-
<script type="module">
|
|
537
|
-
import ElevationLayer from "@arcgis/core/layers/ElevationLayer.js";
|
|
538
|
-
import TileLayer from "@arcgis/core/layers/TileLayer.js";
|
|
539
|
-
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
540
|
-
|
|
541
|
-
const viewElement = document.querySelector("arcgis-scene");
|
|
542
|
-
|
|
543
|
-
// Set Mars spatial reference
|
|
544
|
-
viewElement.spatialReference = { wkid: 104971 }; // Mars 2000
|
|
545
|
-
|
|
546
|
-
// Configure camera for Mars
|
|
547
|
-
viewElement.camera = {
|
|
548
|
-
position: {
|
|
549
|
-
x: 27.63423,
|
|
550
|
-
y: -6.34466,
|
|
551
|
-
z: 1281525,
|
|
552
|
-
spatialReference: { wkid: 104971 }
|
|
553
|
-
},
|
|
554
|
-
heading: 332,
|
|
555
|
-
tilt: 37
|
|
556
|
-
};
|
|
557
|
-
|
|
558
|
-
await viewElement.viewOnReady();
|
|
559
|
-
|
|
560
|
-
// Mars elevation
|
|
561
|
-
const marsElevation = new ElevationLayer({
|
|
562
|
-
url: "https://astro.arcgis.com/arcgis/rest/services/OnMars/MDEM200M/ImageServer"
|
|
563
|
-
});
|
|
564
|
-
viewElement.ground = { layers: [marsElevation] };
|
|
565
|
-
|
|
566
|
-
// Mars imagery
|
|
567
|
-
const marsImagery = new TileLayer({
|
|
568
|
-
url: "https://astro.arcgis.com/arcgis/rest/services/OnMars/MDIM/MapServer",
|
|
569
|
-
title: "Mars Imagery"
|
|
570
|
-
});
|
|
571
|
-
viewElement.map.add(marsImagery);
|
|
572
|
-
</script>
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
## Overview Map (Synchronized Views)
|
|
576
|
-
|
|
577
|
-
### Overview Map with Scene
|
|
578
|
-
```html
|
|
579
|
-
<arcgis-scene basemap="hybrid" ground="world-elevation">
|
|
580
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
581
|
-
<!-- Embed overview map inside scene -->
|
|
582
|
-
<arcgis-map basemap="topo-vector" id="overviewDiv" slot="top-right"></arcgis-map>
|
|
583
|
-
</arcgis-scene>
|
|
584
|
-
|
|
585
|
-
<style>
|
|
586
|
-
#overviewDiv { width: 300px; height: 200px; border: 1px solid black; }
|
|
587
|
-
</style>
|
|
588
|
-
|
|
589
|
-
<script type="module">
|
|
590
|
-
import Graphic from "@arcgis/core/Graphic.js";
|
|
591
|
-
import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
|
|
592
|
-
|
|
593
|
-
const sceneElement = document.querySelector("arcgis-scene");
|
|
594
|
-
const overviewElement = document.querySelector("arcgis-map");
|
|
595
|
-
|
|
596
|
-
await sceneElement.viewOnReady();
|
|
597
|
-
await overviewElement.viewOnReady();
|
|
598
|
-
|
|
599
|
-
// Disable rotation on overview
|
|
600
|
-
overviewElement.constraints.rotationEnabled = false;
|
|
601
|
-
overviewElement.view.ui.components = [];
|
|
602
|
-
|
|
603
|
-
// Add visible area graphic
|
|
604
|
-
const visibleAreaGraphic = new Graphic({
|
|
605
|
-
symbol: {
|
|
606
|
-
type: "simple-fill",
|
|
607
|
-
color: [0, 0, 0, 0.5],
|
|
608
|
-
outline: null
|
|
609
|
-
}
|
|
610
|
-
});
|
|
611
|
-
overviewElement.graphics.add(visibleAreaGraphic);
|
|
612
|
-
|
|
613
|
-
// Sync overview with main scene
|
|
614
|
-
reactiveUtils.watch(
|
|
615
|
-
() => sceneElement.visibleArea,
|
|
616
|
-
async (visibleArea) => {
|
|
617
|
-
visibleAreaGraphic.geometry = visibleArea;
|
|
618
|
-
await overviewElement.goTo(visibleArea);
|
|
619
|
-
},
|
|
620
|
-
{ initial: true }
|
|
621
|
-
);
|
|
622
|
-
</script>
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
## promiseUtils (Async Utilities)
|
|
626
|
-
|
|
627
|
-
### Debounce
|
|
628
|
-
```javascript
|
|
629
|
-
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
630
|
-
|
|
631
|
-
// Create debounced function
|
|
632
|
-
const debouncedUpdate = promiseUtils.debounce(async () => {
|
|
633
|
-
// This only runs after 300ms of no calls
|
|
634
|
-
await updateFeatures();
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
view.on("pointer-move", () => {
|
|
638
|
-
debouncedUpdate();
|
|
639
|
-
});
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
### Abort Error Handling
|
|
643
|
-
```javascript
|
|
644
|
-
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
645
|
-
|
|
646
|
-
const abortController = new AbortController();
|
|
647
|
-
|
|
648
|
-
try {
|
|
649
|
-
await someAsyncOperation({ signal: abortController.signal });
|
|
650
|
-
} catch (error) {
|
|
651
|
-
if (promiseUtils.isAbortError(error)) {
|
|
652
|
-
// Operation was intentionally cancelled
|
|
653
|
-
console.log("Operation cancelled");
|
|
654
|
-
} else {
|
|
655
|
-
// Real error
|
|
656
|
-
throw error;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// Cancel the operation
|
|
661
|
-
abortController.abort();
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
### Create Resolver
|
|
665
|
-
```javascript
|
|
666
|
-
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
667
|
-
|
|
668
|
-
// Create a promise that can be resolved/rejected externally
|
|
669
|
-
const { promise, resolve, reject } = promiseUtils.createResolver();
|
|
670
|
-
|
|
671
|
-
// Later, resolve or reject
|
|
672
|
-
resolve(result);
|
|
673
|
-
// or
|
|
674
|
-
reject(error);
|
|
675
|
-
|
|
676
|
-
// Use the promise
|
|
677
|
-
const result = await promise;
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
## reactiveUtils (Property Watching)
|
|
681
|
-
|
|
682
|
-
### Watch Properties
|
|
683
|
-
```javascript
|
|
684
|
-
import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
|
|
685
|
-
|
|
686
|
-
// Watch single property
|
|
687
|
-
reactiveUtils.watch(
|
|
688
|
-
() => view.scale,
|
|
689
|
-
(scale) => console.log("Scale:", scale)
|
|
690
|
-
);
|
|
691
|
-
|
|
692
|
-
// Watch with initial value
|
|
693
|
-
reactiveUtils.watch(
|
|
694
|
-
() => view.extent,
|
|
695
|
-
(extent) => console.log("Extent:", extent),
|
|
696
|
-
{ initial: true }
|
|
697
|
-
);
|
|
698
|
-
|
|
699
|
-
// Watch once
|
|
700
|
-
reactiveUtils.once(
|
|
701
|
-
() => view.stationary === true
|
|
702
|
-
).then(() => {
|
|
703
|
-
console.log("View became stationary");
|
|
704
|
-
});
|
|
705
|
-
|
|
706
|
-
// When condition becomes true
|
|
707
|
-
reactiveUtils.when(
|
|
708
|
-
() => layer.loaded,
|
|
709
|
-
() => console.log("Layer loaded")
|
|
710
|
-
);
|
|
711
|
-
```
|
|
712
|
-
|
|
713
|
-
## Common Pitfalls
|
|
714
|
-
|
|
715
|
-
1. **Missing CSS for Core API**: The Core API requires `main.css`:
|
|
716
|
-
```html
|
|
717
|
-
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
2. **Not awaiting viewOnReady()**: Always wait for the view before accessing properties:
|
|
721
|
-
```javascript
|
|
722
|
-
await mapElement.viewOnReady();
|
|
723
|
-
const view = mapElement.view; // Safe to access now
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
3. **Coordinate order**: ArcGIS uses `[longitude, latitude]`, not `[latitude, longitude]`
|
|
727
|
-
|
|
728
|
-
4. **Missing viewDiv height**: Ensure the container has height:
|
|
729
|
-
```css
|
|
730
|
-
html, body, #viewDiv { height: 100%; margin: 0; }
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
5. **Script type**: Use `type="module"` for async/await support:
|
|
734
|
-
```html
|
|
735
|
-
<script type="module">
|
|
736
|
-
// async/await works here
|
|
737
|
-
</script>
|
|
738
|
-
```
|
|
739
|
-
|
|
1
|
+
---
|
|
2
|
+
name: arcgis-core-maps
|
|
3
|
+
description: Create 2D and 3D maps using ArcGIS Maps SDK for JavaScript. Use for initializing maps, scenes, views, and navigation. Supports both Map Components (web components) and Core API approaches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ArcGIS Core Maps
|
|
7
|
+
|
|
8
|
+
Use this skill when creating 2D maps (MapView) or 3D scenes (SceneView) with the ArcGIS Maps SDK for JavaScript.
|
|
9
|
+
|
|
10
|
+
## Import Patterns
|
|
11
|
+
|
|
12
|
+
### Direct ESM Imports (Recommended for Build Tools)
|
|
13
|
+
Use with Vite, webpack, Rollup, or other build tools:
|
|
14
|
+
```javascript
|
|
15
|
+
import Map from "@arcgis/core/Map.js";
|
|
16
|
+
import MapView from "@arcgis/core/views/MapView.js";
|
|
17
|
+
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
18
|
+
```
|
|
19
|
+
- Tree-shakeable
|
|
20
|
+
- Standard JavaScript modules
|
|
21
|
+
- Best for production applications
|
|
22
|
+
|
|
23
|
+
### Dynamic Imports (CDN / No Build Tools)
|
|
24
|
+
Use with CDN script tags when no build step is available:
|
|
25
|
+
```javascript
|
|
26
|
+
const Map = await $arcgis.import("@arcgis/core/Map.js");
|
|
27
|
+
const MapView = await $arcgis.import("@arcgis/core/views/MapView.js");
|
|
28
|
+
|
|
29
|
+
// Multiple imports
|
|
30
|
+
const [FeatureLayer, Graphic] = await $arcgis.import([
|
|
31
|
+
"@arcgis/core/layers/FeatureLayer.js",
|
|
32
|
+
"@arcgis/core/Graphic.js"
|
|
33
|
+
]);
|
|
34
|
+
```
|
|
35
|
+
- Works with Map Components (web components)
|
|
36
|
+
- No build step required
|
|
37
|
+
- Good for quick prototypes and demos
|
|
38
|
+
- Requires `<script src="https://js.arcgis.com/4.34/"></script>` in HTML
|
|
39
|
+
|
|
40
|
+
> **Note:** The examples in this skill use Direct ESM imports. For CDN usage, replace `import X from "path"` with `const X = await $arcgis.import("path")`.
|
|
41
|
+
|
|
42
|
+
## Autocasting vs Explicit Classes (TypeScript)
|
|
43
|
+
|
|
44
|
+
The ArcGIS SDK supports [autocasting](https://developers.arcgis.com/javascript/latest/autocasting/) - passing plain objects instead of class instances. Understanding when to use each approach is important for TypeScript projects.
|
|
45
|
+
|
|
46
|
+
### When to Use Explicit Classes (Non-Autocast)
|
|
47
|
+
|
|
48
|
+
Use `new SimpleRenderer()`, `new Point()`, etc. when:
|
|
49
|
+
|
|
50
|
+
- **You need instance methods or `instanceof` checks**
|
|
51
|
+
- **Building shared internal libraries** - constructor APIs surface breaking changes at compile time
|
|
52
|
+
- **You want strong editor discoverability** - `new SimpleRenderer({ ... })` exposes properties clearly
|
|
53
|
+
- **You mutate objects incrementally** - long-lived instances are clearer as real classes
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer.js";
|
|
57
|
+
import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol.js";
|
|
58
|
+
|
|
59
|
+
const renderer = new SimpleRenderer({
|
|
60
|
+
symbol: new SimpleMarkerSymbol({
|
|
61
|
+
color: [226, 119, 40],
|
|
62
|
+
size: 8
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### When to Use Autocasting
|
|
68
|
+
|
|
69
|
+
Use plain objects with `type` property when:
|
|
70
|
+
|
|
71
|
+
- **Configuration-heavy code** - renderers, symbols, popups are usually data, not behavior
|
|
72
|
+
- **UI-driven configuration** - React state → plain objects → SDK properties is simpler
|
|
73
|
+
- **Serialization and reuse matter** - configs can be stored, diffed, tested, reused
|
|
74
|
+
- **Property updates after creation** - `layer.renderer = { ... }` works cleanly in React `useEffect`
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Use 'as const' or 'satisfies' to keep discriminated unions narrow
|
|
78
|
+
const renderer = {
|
|
79
|
+
type: "simple",
|
|
80
|
+
symbol: {
|
|
81
|
+
type: "simple-marker",
|
|
82
|
+
color: [226, 119, 40],
|
|
83
|
+
size: 8
|
|
84
|
+
}
|
|
85
|
+
} as const;
|
|
86
|
+
|
|
87
|
+
// Or with satisfies for better type inference
|
|
88
|
+
import type { SimpleRenderer } from "@arcgis/core/renderers/SimpleRenderer.js";
|
|
89
|
+
|
|
90
|
+
const renderer = {
|
|
91
|
+
type: "simple",
|
|
92
|
+
symbol: {
|
|
93
|
+
type: "simple-marker",
|
|
94
|
+
color: [226, 119, 40],
|
|
95
|
+
size: 8
|
|
96
|
+
}
|
|
97
|
+
} satisfies __esri.SimpleRendererProperties;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### TypeScript Best Practices
|
|
101
|
+
|
|
102
|
+
The real TypeScript concern is keeping discriminated unions narrow:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// ❌ BAD - type widens to string
|
|
106
|
+
const symbol = { type: "simple-marker", color: "red" };
|
|
107
|
+
|
|
108
|
+
// ✅ GOOD - type stays literal
|
|
109
|
+
const symbol = { type: "simple-marker", color: "red" } as const;
|
|
110
|
+
|
|
111
|
+
// ✅ GOOD - explicit type annotation
|
|
112
|
+
const symbol: __esri.SimpleMarkerSymbolProperties = {
|
|
113
|
+
type: "simple-marker",
|
|
114
|
+
color: "red"
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Recommended Default
|
|
119
|
+
|
|
120
|
+
- **Autocast for configuration** (renderers, symbols, popups, labels)
|
|
121
|
+
- **Explicit classes for behavior** (when you need methods or instanceof)
|
|
122
|
+
- **Use `as const` or `satisfies`** to maintain type safety with autocasting
|
|
123
|
+
|
|
124
|
+
## Two Approaches
|
|
125
|
+
|
|
126
|
+
### 1. Map Components (Modern - Recommended)
|
|
127
|
+
Web components approach using `<arcgis-map>` and `<arcgis-scene>`.
|
|
128
|
+
|
|
129
|
+
### 2. Core API
|
|
130
|
+
Traditional JavaScript approach using `Map`, `MapView`, and `SceneView` classes.
|
|
131
|
+
|
|
132
|
+
## CDN Setup
|
|
133
|
+
|
|
134
|
+
### Map Components Approach
|
|
135
|
+
```html
|
|
136
|
+
<!DOCTYPE html>
|
|
137
|
+
<html lang="en">
|
|
138
|
+
<head>
|
|
139
|
+
<meta charset="utf-8" />
|
|
140
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
141
|
+
<title>ArcGIS Map</title>
|
|
142
|
+
<style>
|
|
143
|
+
html, body { height: 100%; margin: 0; }
|
|
144
|
+
</style>
|
|
145
|
+
<!-- Load Calcite components -->
|
|
146
|
+
<script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script>
|
|
147
|
+
<!-- Load ArcGIS Maps SDK -->
|
|
148
|
+
<script src="https://js.arcgis.com/4.34/"></script>
|
|
149
|
+
<!-- Load Map components -->
|
|
150
|
+
<script type="module" src="https://js.arcgis.com/4.34/map-components/"></script>
|
|
151
|
+
</head>
|
|
152
|
+
<body>
|
|
153
|
+
<arcgis-map basemap="topo-vector" center="-118.24,34.05" zoom="12">
|
|
154
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
155
|
+
</arcgis-map>
|
|
156
|
+
</body>
|
|
157
|
+
</html>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Core API Approach
|
|
161
|
+
```html
|
|
162
|
+
<!DOCTYPE html>
|
|
163
|
+
<html lang="en">
|
|
164
|
+
<head>
|
|
165
|
+
<meta charset="utf-8" />
|
|
166
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
167
|
+
<title>ArcGIS Map</title>
|
|
168
|
+
<style>
|
|
169
|
+
html, body, #viewDiv { height: 100%; margin: 0; }
|
|
170
|
+
</style>
|
|
171
|
+
<!-- REQUIRED: main.css for Core API -->
|
|
172
|
+
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
|
|
173
|
+
<script src="https://js.arcgis.com/4.34/"></script>
|
|
174
|
+
</head>
|
|
175
|
+
<body>
|
|
176
|
+
<div id="viewDiv"></div>
|
|
177
|
+
<script type="module">
|
|
178
|
+
import Map from "@arcgis/core/Map.js";
|
|
179
|
+
import MapView from "@arcgis/core/views/MapView.js";
|
|
180
|
+
|
|
181
|
+
const map = new Map({ basemap: "topo-vector" });
|
|
182
|
+
const view = new MapView({
|
|
183
|
+
container: "viewDiv",
|
|
184
|
+
map: map,
|
|
185
|
+
center: [-118.24, 34.05], // [longitude, latitude]
|
|
186
|
+
zoom: 12
|
|
187
|
+
});
|
|
188
|
+
</script>
|
|
189
|
+
</body>
|
|
190
|
+
</html>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 2D Maps
|
|
194
|
+
|
|
195
|
+
### Map Components
|
|
196
|
+
```html
|
|
197
|
+
<arcgis-map basemap="topo-vector" center="-118.24,34.05" zoom="12">
|
|
198
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
199
|
+
<arcgis-compass slot="top-left"></arcgis-compass>
|
|
200
|
+
<arcgis-home slot="top-left"></arcgis-home>
|
|
201
|
+
<arcgis-locate slot="top-left"></arcgis-locate>
|
|
202
|
+
</arcgis-map>
|
|
203
|
+
|
|
204
|
+
<script type="module">
|
|
205
|
+
const mapElement = document.querySelector("arcgis-map");
|
|
206
|
+
await mapElement.viewOnReady(); // Wait for view to be ready
|
|
207
|
+
const view = mapElement.view; // Access the MapView
|
|
208
|
+
const map = mapElement.map; // Access the Map
|
|
209
|
+
</script>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Core API
|
|
213
|
+
```javascript
|
|
214
|
+
import Map from "@arcgis/core/Map.js";
|
|
215
|
+
import MapView from "@arcgis/core/views/MapView.js";
|
|
216
|
+
|
|
217
|
+
const map = new Map({ basemap: "streets-vector" });
|
|
218
|
+
|
|
219
|
+
const view = new MapView({
|
|
220
|
+
container: "viewDiv",
|
|
221
|
+
map: map,
|
|
222
|
+
center: [-118.24, 34.05],
|
|
223
|
+
zoom: 12,
|
|
224
|
+
// Optional constraints
|
|
225
|
+
constraints: {
|
|
226
|
+
minZoom: 5,
|
|
227
|
+
maxZoom: 18,
|
|
228
|
+
rotationEnabled: false
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 3D Scenes
|
|
234
|
+
|
|
235
|
+
### Map Components
|
|
236
|
+
```html
|
|
237
|
+
<arcgis-scene basemap="topo-3d" ground="world-elevation">
|
|
238
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
239
|
+
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
|
|
240
|
+
</arcgis-scene>
|
|
241
|
+
|
|
242
|
+
<script type="module">
|
|
243
|
+
const sceneElement = document.querySelector("arcgis-scene");
|
|
244
|
+
await sceneElement.viewOnReady();
|
|
245
|
+
const view = sceneElement.view; // SceneView
|
|
246
|
+
</script>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Core API
|
|
250
|
+
```javascript
|
|
251
|
+
import Map from "@arcgis/core/Map.js";
|
|
252
|
+
import SceneView from "@arcgis/core/views/SceneView.js";
|
|
253
|
+
|
|
254
|
+
const map = new Map({
|
|
255
|
+
basemap: "topo-3d",
|
|
256
|
+
ground: "world-elevation"
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const view = new SceneView({
|
|
260
|
+
container: "viewDiv",
|
|
261
|
+
map: map,
|
|
262
|
+
camera: {
|
|
263
|
+
position: {
|
|
264
|
+
longitude: -118.24,
|
|
265
|
+
latitude: 34.05,
|
|
266
|
+
z: 25000 // altitude in meters
|
|
267
|
+
},
|
|
268
|
+
heading: 0, // compass direction
|
|
269
|
+
tilt: 45 // 0 = straight down, 90 = horizon
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Loading WebMaps and WebScenes
|
|
275
|
+
|
|
276
|
+
### WebMap (2D)
|
|
277
|
+
```html
|
|
278
|
+
<!-- Map Components -->
|
|
279
|
+
<arcgis-map item-id="f2e9b762544945f390ca4ac3671cfa72">
|
|
280
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
281
|
+
</arcgis-map>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// Core API
|
|
286
|
+
import MapView from "@arcgis/core/views/MapView.js";
|
|
287
|
+
import WebMap from "@arcgis/core/WebMap.js";
|
|
288
|
+
|
|
289
|
+
const webmap = new WebMap({
|
|
290
|
+
portalItem: { id: "f2e9b762544945f390ca4ac3671cfa72" }
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const view = new MapView({
|
|
294
|
+
map: webmap,
|
|
295
|
+
container: "viewDiv"
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### WebScene (3D)
|
|
300
|
+
```html
|
|
301
|
+
<!-- Map Components -->
|
|
302
|
+
<arcgis-scene item-id="YOUR_WEBSCENE_ID">
|
|
303
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
304
|
+
</arcgis-scene>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
// Core API
|
|
309
|
+
import SceneView from "@arcgis/core/views/SceneView.js";
|
|
310
|
+
import WebScene from "@arcgis/core/WebScene.js";
|
|
311
|
+
|
|
312
|
+
const webscene = new WebScene({
|
|
313
|
+
portalItem: { id: "YOUR_WEBSCENE_ID" }
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const view = new SceneView({
|
|
317
|
+
map: webscene,
|
|
318
|
+
container: "viewDiv"
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Navigation Components
|
|
323
|
+
|
|
324
|
+
| Component | Purpose |
|
|
325
|
+
|-----------|---------|
|
|
326
|
+
| `arcgis-zoom` | Zoom in/out buttons |
|
|
327
|
+
| `arcgis-compass` | Orientation indicator, click to reset north |
|
|
328
|
+
| `arcgis-home` | Return to initial extent |
|
|
329
|
+
| `arcgis-locate` | Find user's location |
|
|
330
|
+
| `arcgis-navigation-toggle` | Switch between pan/rotate modes (3D) |
|
|
331
|
+
| `arcgis-fullscreen` | Toggle fullscreen mode |
|
|
332
|
+
| `arcgis-scale-bar` | Display map scale |
|
|
333
|
+
|
|
334
|
+
### Slot Positions
|
|
335
|
+
```html
|
|
336
|
+
<arcgis-map basemap="streets-vector">
|
|
337
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
338
|
+
<arcgis-home slot="top-left"></arcgis-home>
|
|
339
|
+
<arcgis-search slot="top-right"></arcgis-search>
|
|
340
|
+
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
341
|
+
<arcgis-scale-bar slot="bottom-right"></arcgis-scale-bar>
|
|
342
|
+
</arcgis-map>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Available slots: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `manual`
|
|
346
|
+
|
|
347
|
+
## View Configuration
|
|
348
|
+
|
|
349
|
+
### Setting Initial Extent
|
|
350
|
+
```javascript
|
|
351
|
+
// By center and zoom
|
|
352
|
+
const view = new MapView({
|
|
353
|
+
container: "viewDiv",
|
|
354
|
+
map: map,
|
|
355
|
+
center: [-118.24, 34.05],
|
|
356
|
+
zoom: 12
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// By scale
|
|
360
|
+
const view = new MapView({
|
|
361
|
+
container: "viewDiv",
|
|
362
|
+
map: map,
|
|
363
|
+
center: [-118.24, 34.05],
|
|
364
|
+
scale: 50000 // 1:50,000
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// By extent
|
|
368
|
+
const view = new MapView({
|
|
369
|
+
container: "viewDiv",
|
|
370
|
+
map: map,
|
|
371
|
+
extent: {
|
|
372
|
+
xmin: -118.5,
|
|
373
|
+
ymin: 33.8,
|
|
374
|
+
xmax: -117.9,
|
|
375
|
+
ymax: 34.3,
|
|
376
|
+
spatialReference: { wkid: 4326 }
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Programmatic Navigation
|
|
382
|
+
```javascript
|
|
383
|
+
// Go to location
|
|
384
|
+
await view.goTo({
|
|
385
|
+
center: [-118.24, 34.05],
|
|
386
|
+
zoom: 15
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// Animated navigation
|
|
390
|
+
await view.goTo(
|
|
391
|
+
{ center: [-118.24, 34.05], zoom: 15 },
|
|
392
|
+
{ duration: 2000, easing: "ease-in-out" }
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
// Go to extent
|
|
396
|
+
await view.goTo(layer.fullExtent);
|
|
397
|
+
|
|
398
|
+
// Go to features
|
|
399
|
+
await view.goTo(featureSet.features);
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### View Constraints
|
|
403
|
+
```javascript
|
|
404
|
+
// Constrain zoom levels
|
|
405
|
+
view.constraints = {
|
|
406
|
+
minZoom: 5,
|
|
407
|
+
maxZoom: 18
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
// Constrain to area
|
|
411
|
+
view.constraints = {
|
|
412
|
+
geometry: layer.fullExtent,
|
|
413
|
+
minScale: 500000
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// Disable rotation
|
|
417
|
+
view.constraints = {
|
|
418
|
+
rotationEnabled: false
|
|
419
|
+
};
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Event Handling
|
|
423
|
+
|
|
424
|
+
```javascript
|
|
425
|
+
// View ready
|
|
426
|
+
view.when(() => {
|
|
427
|
+
console.log("View is ready");
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// Click event
|
|
431
|
+
view.on("click", (event) => {
|
|
432
|
+
console.log("Clicked at:", event.mapPoint);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// Pointer move
|
|
436
|
+
view.on("pointer-move", (event) => {
|
|
437
|
+
const point = view.toMap(event);
|
|
438
|
+
console.log("Mouse at:", point.longitude, point.latitude);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// Extent change
|
|
442
|
+
view.watch("extent", (extent) => {
|
|
443
|
+
console.log("Extent changed:", extent);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Stationary (after pan/zoom completes)
|
|
447
|
+
view.watch("stationary", (isStationary) => {
|
|
448
|
+
if (isStationary) {
|
|
449
|
+
console.log("Navigation complete");
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Module Imports
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
// Single import
|
|
458
|
+
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
459
|
+
|
|
460
|
+
// Multiple imports
|
|
461
|
+
import Map from "@arcgis/core/Map.js";
|
|
462
|
+
import MapView from "@arcgis/core/views/MapView.js";
|
|
463
|
+
import Graphic from "@arcgis/core/Graphic.js";
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Common Basemaps
|
|
467
|
+
|
|
468
|
+
| Basemap ID | Description |
|
|
469
|
+
|------------|-------------|
|
|
470
|
+
| `streets-vector` | Street map |
|
|
471
|
+
| `topo-vector` | Topographic |
|
|
472
|
+
| `satellite` | Satellite imagery |
|
|
473
|
+
| `hybrid` | Satellite with labels |
|
|
474
|
+
| `dark-gray-vector` | Dark gray canvas |
|
|
475
|
+
| `gray-vector` | Light gray canvas |
|
|
476
|
+
| `osm` | OpenStreetMap |
|
|
477
|
+
| `topo-3d` | 3D topographic (SceneView) |
|
|
478
|
+
|
|
479
|
+
## esriRequest (HTTP Requests)
|
|
480
|
+
|
|
481
|
+
### Basic Request
|
|
482
|
+
```javascript
|
|
483
|
+
import esriRequest from "@arcgis/core/request.js";
|
|
484
|
+
|
|
485
|
+
// GET request with JSON response
|
|
486
|
+
const response = await esriRequest(url, {
|
|
487
|
+
query: { f: "json" },
|
|
488
|
+
responseType: "json"
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
console.log("Status:", response.httpStatus);
|
|
492
|
+
console.log("Data:", response.data);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Request with Options
|
|
496
|
+
```javascript
|
|
497
|
+
const response = await esriRequest(url, {
|
|
498
|
+
query: {
|
|
499
|
+
f: "json",
|
|
500
|
+
param1: "value1"
|
|
501
|
+
},
|
|
502
|
+
responseType: "json", // "json", "text", "array-buffer", "blob", "image"
|
|
503
|
+
method: "post", // "auto", "get", "post"
|
|
504
|
+
body: formData, // For POST requests
|
|
505
|
+
timeout: 30000, // Timeout in ms
|
|
506
|
+
headers: {
|
|
507
|
+
"X-Custom-Header": "value"
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Download Binary Data
|
|
513
|
+
```javascript
|
|
514
|
+
// Image response
|
|
515
|
+
const imageResponse = await esriRequest(imageUrl, {
|
|
516
|
+
responseType: "image"
|
|
517
|
+
});
|
|
518
|
+
const imageElement = imageResponse.data;
|
|
519
|
+
|
|
520
|
+
// Binary data
|
|
521
|
+
const binaryResponse = await esriRequest(fileUrl, {
|
|
522
|
+
responseType: "array-buffer"
|
|
523
|
+
});
|
|
524
|
+
const arrayBuffer = binaryResponse.data;
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Planetary Visualization (Mars)
|
|
528
|
+
|
|
529
|
+
### Mars Scene
|
|
530
|
+
```html
|
|
531
|
+
<arcgis-scene>
|
|
532
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
533
|
+
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
|
|
534
|
+
</arcgis-scene>
|
|
535
|
+
|
|
536
|
+
<script type="module">
|
|
537
|
+
import ElevationLayer from "@arcgis/core/layers/ElevationLayer.js";
|
|
538
|
+
import TileLayer from "@arcgis/core/layers/TileLayer.js";
|
|
539
|
+
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
|
|
540
|
+
|
|
541
|
+
const viewElement = document.querySelector("arcgis-scene");
|
|
542
|
+
|
|
543
|
+
// Set Mars spatial reference
|
|
544
|
+
viewElement.spatialReference = { wkid: 104971 }; // Mars 2000
|
|
545
|
+
|
|
546
|
+
// Configure camera for Mars
|
|
547
|
+
viewElement.camera = {
|
|
548
|
+
position: {
|
|
549
|
+
x: 27.63423,
|
|
550
|
+
y: -6.34466,
|
|
551
|
+
z: 1281525,
|
|
552
|
+
spatialReference: { wkid: 104971 }
|
|
553
|
+
},
|
|
554
|
+
heading: 332,
|
|
555
|
+
tilt: 37
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
await viewElement.viewOnReady();
|
|
559
|
+
|
|
560
|
+
// Mars elevation
|
|
561
|
+
const marsElevation = new ElevationLayer({
|
|
562
|
+
url: "https://astro.arcgis.com/arcgis/rest/services/OnMars/MDEM200M/ImageServer"
|
|
563
|
+
});
|
|
564
|
+
viewElement.ground = { layers: [marsElevation] };
|
|
565
|
+
|
|
566
|
+
// Mars imagery
|
|
567
|
+
const marsImagery = new TileLayer({
|
|
568
|
+
url: "https://astro.arcgis.com/arcgis/rest/services/OnMars/MDIM/MapServer",
|
|
569
|
+
title: "Mars Imagery"
|
|
570
|
+
});
|
|
571
|
+
viewElement.map.add(marsImagery);
|
|
572
|
+
</script>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
## Overview Map (Synchronized Views)
|
|
576
|
+
|
|
577
|
+
### Overview Map with Scene
|
|
578
|
+
```html
|
|
579
|
+
<arcgis-scene basemap="hybrid" ground="world-elevation">
|
|
580
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
581
|
+
<!-- Embed overview map inside scene -->
|
|
582
|
+
<arcgis-map basemap="topo-vector" id="overviewDiv" slot="top-right"></arcgis-map>
|
|
583
|
+
</arcgis-scene>
|
|
584
|
+
|
|
585
|
+
<style>
|
|
586
|
+
#overviewDiv { width: 300px; height: 200px; border: 1px solid black; }
|
|
587
|
+
</style>
|
|
588
|
+
|
|
589
|
+
<script type="module">
|
|
590
|
+
import Graphic from "@arcgis/core/Graphic.js";
|
|
591
|
+
import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
|
|
592
|
+
|
|
593
|
+
const sceneElement = document.querySelector("arcgis-scene");
|
|
594
|
+
const overviewElement = document.querySelector("arcgis-map");
|
|
595
|
+
|
|
596
|
+
await sceneElement.viewOnReady();
|
|
597
|
+
await overviewElement.viewOnReady();
|
|
598
|
+
|
|
599
|
+
// Disable rotation on overview
|
|
600
|
+
overviewElement.constraints.rotationEnabled = false;
|
|
601
|
+
overviewElement.view.ui.components = [];
|
|
602
|
+
|
|
603
|
+
// Add visible area graphic
|
|
604
|
+
const visibleAreaGraphic = new Graphic({
|
|
605
|
+
symbol: {
|
|
606
|
+
type: "simple-fill",
|
|
607
|
+
color: [0, 0, 0, 0.5],
|
|
608
|
+
outline: null
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
overviewElement.graphics.add(visibleAreaGraphic);
|
|
612
|
+
|
|
613
|
+
// Sync overview with main scene
|
|
614
|
+
reactiveUtils.watch(
|
|
615
|
+
() => sceneElement.visibleArea,
|
|
616
|
+
async (visibleArea) => {
|
|
617
|
+
visibleAreaGraphic.geometry = visibleArea;
|
|
618
|
+
await overviewElement.goTo(visibleArea);
|
|
619
|
+
},
|
|
620
|
+
{ initial: true }
|
|
621
|
+
);
|
|
622
|
+
</script>
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
## promiseUtils (Async Utilities)
|
|
626
|
+
|
|
627
|
+
### Debounce
|
|
628
|
+
```javascript
|
|
629
|
+
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
630
|
+
|
|
631
|
+
// Create debounced function
|
|
632
|
+
const debouncedUpdate = promiseUtils.debounce(async () => {
|
|
633
|
+
// This only runs after 300ms of no calls
|
|
634
|
+
await updateFeatures();
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
view.on("pointer-move", () => {
|
|
638
|
+
debouncedUpdate();
|
|
639
|
+
});
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Abort Error Handling
|
|
643
|
+
```javascript
|
|
644
|
+
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
645
|
+
|
|
646
|
+
const abortController = new AbortController();
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
await someAsyncOperation({ signal: abortController.signal });
|
|
650
|
+
} catch (error) {
|
|
651
|
+
if (promiseUtils.isAbortError(error)) {
|
|
652
|
+
// Operation was intentionally cancelled
|
|
653
|
+
console.log("Operation cancelled");
|
|
654
|
+
} else {
|
|
655
|
+
// Real error
|
|
656
|
+
throw error;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Cancel the operation
|
|
661
|
+
abortController.abort();
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### Create Resolver
|
|
665
|
+
```javascript
|
|
666
|
+
import promiseUtils from "@arcgis/core/core/promiseUtils.js";
|
|
667
|
+
|
|
668
|
+
// Create a promise that can be resolved/rejected externally
|
|
669
|
+
const { promise, resolve, reject } = promiseUtils.createResolver();
|
|
670
|
+
|
|
671
|
+
// Later, resolve or reject
|
|
672
|
+
resolve(result);
|
|
673
|
+
// or
|
|
674
|
+
reject(error);
|
|
675
|
+
|
|
676
|
+
// Use the promise
|
|
677
|
+
const result = await promise;
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
## reactiveUtils (Property Watching)
|
|
681
|
+
|
|
682
|
+
### Watch Properties
|
|
683
|
+
```javascript
|
|
684
|
+
import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
|
|
685
|
+
|
|
686
|
+
// Watch single property
|
|
687
|
+
reactiveUtils.watch(
|
|
688
|
+
() => view.scale,
|
|
689
|
+
(scale) => console.log("Scale:", scale)
|
|
690
|
+
);
|
|
691
|
+
|
|
692
|
+
// Watch with initial value
|
|
693
|
+
reactiveUtils.watch(
|
|
694
|
+
() => view.extent,
|
|
695
|
+
(extent) => console.log("Extent:", extent),
|
|
696
|
+
{ initial: true }
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
// Watch once
|
|
700
|
+
reactiveUtils.once(
|
|
701
|
+
() => view.stationary === true
|
|
702
|
+
).then(() => {
|
|
703
|
+
console.log("View became stationary");
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// When condition becomes true
|
|
707
|
+
reactiveUtils.when(
|
|
708
|
+
() => layer.loaded,
|
|
709
|
+
() => console.log("Layer loaded")
|
|
710
|
+
);
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
## Common Pitfalls
|
|
714
|
+
|
|
715
|
+
1. **Missing CSS for Core API**: The Core API requires `main.css`:
|
|
716
|
+
```html
|
|
717
|
+
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
2. **Not awaiting viewOnReady()**: Always wait for the view before accessing properties:
|
|
721
|
+
```javascript
|
|
722
|
+
await mapElement.viewOnReady();
|
|
723
|
+
const view = mapElement.view; // Safe to access now
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
3. **Coordinate order**: ArcGIS uses `[longitude, latitude]`, not `[latitude, longitude]`
|
|
727
|
+
|
|
728
|
+
4. **Missing viewDiv height**: Ensure the container has height:
|
|
729
|
+
```css
|
|
730
|
+
html, body, #viewDiv { height: 100%; margin: 0; }
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
5. **Script type**: Use `type="module"` for async/await support:
|
|
734
|
+
```html
|
|
735
|
+
<script type="module">
|
|
736
|
+
// async/await works here
|
|
737
|
+
</script>
|
|
738
|
+
```
|
|
739
|
+
|