@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,607 +1,607 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arcgis-analysis-services
|
|
3
|
-
description: Perform spatial analysis, geometry operations, and use ArcGIS REST services. Use for routing, geocoding, geoprocessing, elevation analysis, viewshed, and feature queries with statistics.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# ArcGIS Analysis & Services
|
|
7
|
-
|
|
8
|
-
Use this skill for spatial analysis, geometry operations, REST services, and feature reduction (clustering/binning).
|
|
9
|
-
|
|
10
|
-
## Geometry Operators
|
|
11
|
-
|
|
12
|
-
ArcGIS Maps SDK provides geometry operators for client-side spatial operations.
|
|
13
|
-
|
|
14
|
-
### Loading Operators
|
|
15
|
-
|
|
16
|
-
```javascript
|
|
17
|
-
import bufferOperator from "@arcgis/core/geometry/operators/bufferOperator.js";
|
|
18
|
-
import intersectOperator from "@arcgis/core/geometry/operators/intersectOperator.js";
|
|
19
|
-
import centroidOperator from "@arcgis/core/geometry/operators/centroidOperator.js";
|
|
20
|
-
|
|
21
|
-
// Load before use (most operators require this)
|
|
22
|
-
await bufferOperator.load();
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Buffer
|
|
26
|
-
```javascript
|
|
27
|
-
import bufferOperator from "@arcgis/core/geometry/operators/bufferOperator.js";
|
|
28
|
-
await bufferOperator.load();
|
|
29
|
-
|
|
30
|
-
const buffered = bufferOperator.execute(point, 1000); // 1000 meters
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Geodesic Buffer (accurate over large distances)
|
|
34
|
-
```javascript
|
|
35
|
-
import geodesicBufferOperator from "@arcgis/core/geometry/operators/geodesicBufferOperator.js";
|
|
36
|
-
await geodesicBufferOperator.load();
|
|
37
|
-
|
|
38
|
-
const buffered = geodesicBufferOperator.execute(point, {
|
|
39
|
-
distances: [100],
|
|
40
|
-
unit: "kilometers"
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Intersect
|
|
45
|
-
```javascript
|
|
46
|
-
import intersectOperator from "@arcgis/core/geometry/operators/intersectOperator.js";
|
|
47
|
-
await intersectOperator.load();
|
|
48
|
-
|
|
49
|
-
const intersection = intersectOperator.execute(geometry1, geometry2);
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Union
|
|
53
|
-
```javascript
|
|
54
|
-
import unionOperator from "@arcgis/core/geometry/operators/unionOperator.js";
|
|
55
|
-
await unionOperator.load();
|
|
56
|
-
|
|
57
|
-
const unioned = unionOperator.execute([polygon1, polygon2, polygon3]);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Centroid
|
|
61
|
-
```javascript
|
|
62
|
-
import centroidOperator from "@arcgis/core/geometry/operators/centroidOperator.js";
|
|
63
|
-
await centroidOperator.load();
|
|
64
|
-
|
|
65
|
-
const centroid = centroidOperator.execute(polygon);
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Contains / Within
|
|
69
|
-
```javascript
|
|
70
|
-
import containsOperator from "@arcgis/core/geometry/operators/containsOperator.js";
|
|
71
|
-
await containsOperator.load();
|
|
72
|
-
|
|
73
|
-
const isContained = containsOperator.execute(polygon, point); // true/false
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Distance
|
|
77
|
-
```javascript
|
|
78
|
-
import geodeticLengthOperator from "@arcgis/core/geometry/operators/geodeticLengthOperator.js";
|
|
79
|
-
await geodeticLengthOperator.load();
|
|
80
|
-
|
|
81
|
-
const length = geodeticLengthOperator.execute(polyline, { unit: "miles" });
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Area
|
|
85
|
-
```javascript
|
|
86
|
-
import geodeticAreaOperator from "@arcgis/core/geometry/operators/geodeticAreaOperator.js";
|
|
87
|
-
await geodeticAreaOperator.load();
|
|
88
|
-
|
|
89
|
-
const area = geodeticAreaOperator.execute(polygon, { unit: "square-kilometers" });
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Available Operators
|
|
93
|
-
|
|
94
|
-
| Operator | Purpose |
|
|
95
|
-
|----------|---------|
|
|
96
|
-
| `bufferOperator` | Create buffer around geometry |
|
|
97
|
-
| `geodesicBufferOperator` | Geodetic buffer (accurate) |
|
|
98
|
-
| `intersectOperator` | Find intersection |
|
|
99
|
-
| `unionOperator` | Combine geometries |
|
|
100
|
-
| `differenceOperator` | Subtract geometries |
|
|
101
|
-
| `clipOperator` | Clip geometry by envelope |
|
|
102
|
-
| `convexHullOperator` | Create convex hull |
|
|
103
|
-
| `centroidOperator` | Get centroid point |
|
|
104
|
-
| `containsOperator` | Test if contains |
|
|
105
|
-
| `withinOperator` | Test if within |
|
|
106
|
-
| `intersectsOperator` | Test if intersects |
|
|
107
|
-
| `distanceOperator` | Calculate planar distance |
|
|
108
|
-
| `geodeticLengthOperator` | Calculate geodetic length |
|
|
109
|
-
| `geodeticAreaOperator` | Calculate geodetic area |
|
|
110
|
-
| `simplifyOperator` | Simplify geometry |
|
|
111
|
-
| `densifyOperator` | Add vertices to geometry |
|
|
112
|
-
| `projectOperator` | Project to spatial reference |
|
|
113
|
-
|
|
114
|
-
## Analysis Objects
|
|
115
|
-
|
|
116
|
-
### ElevationProfileAnalysis
|
|
117
|
-
```javascript
|
|
118
|
-
import ElevationProfileAnalysis from "@arcgis/core/analysis/ElevationProfileAnalysis.js";
|
|
119
|
-
|
|
120
|
-
const analysis = new ElevationProfileAnalysis({
|
|
121
|
-
profiles: [
|
|
122
|
-
{ type: "ground", color: "brown" },
|
|
123
|
-
{ type: "input", color: "blue" }
|
|
124
|
-
],
|
|
125
|
-
displayUnits: {
|
|
126
|
-
distance: "meters",
|
|
127
|
-
elevation: "meters"
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
// Add to SceneView
|
|
132
|
-
view.analyses.add(analysis);
|
|
133
|
-
|
|
134
|
-
// Set line geometry
|
|
135
|
-
analysis.geometry = polyline;
|
|
136
|
-
|
|
137
|
-
// Get analysis view for results
|
|
138
|
-
const analysisView = await view.whenAnalysisView(analysis);
|
|
139
|
-
|
|
140
|
-
// Watch progress and results
|
|
141
|
-
reactiveUtils.watch(
|
|
142
|
-
() => analysisView.progress,
|
|
143
|
-
(progress) => {
|
|
144
|
-
if (progress === 1) {
|
|
145
|
-
console.log("Results:", analysisView.results);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### LineOfSightAnalysis
|
|
152
|
-
```javascript
|
|
153
|
-
import LineOfSightAnalysis from "@arcgis/core/analysis/LineOfSightAnalysis.js";
|
|
154
|
-
|
|
155
|
-
const analysis = new LineOfSightAnalysis({
|
|
156
|
-
observer: {
|
|
157
|
-
type: "point",
|
|
158
|
-
x: -122.4,
|
|
159
|
-
y: 37.8,
|
|
160
|
-
z: 100,
|
|
161
|
-
spatialReference: { wkid: 4326 }
|
|
162
|
-
},
|
|
163
|
-
targets: [
|
|
164
|
-
{ type: "point", x: -122.41, y: 37.81, z: 50 },
|
|
165
|
-
{ type: "point", x: -122.42, y: 37.79, z: 75 }
|
|
166
|
-
]
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
view.analyses.add(analysis);
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### ViewshedAnalysis
|
|
173
|
-
```javascript
|
|
174
|
-
import ViewshedAnalysis from "@arcgis/core/analysis/ViewshedAnalysis.js";
|
|
175
|
-
|
|
176
|
-
const analysis = new ViewshedAnalysis({
|
|
177
|
-
observer: {
|
|
178
|
-
type: "point",
|
|
179
|
-
x: -122.4,
|
|
180
|
-
y: 37.8,
|
|
181
|
-
z: 100,
|
|
182
|
-
spatialReference: { wkid: 4326 }
|
|
183
|
-
},
|
|
184
|
-
farDistance: 1000,
|
|
185
|
-
heading: 45,
|
|
186
|
-
tilt: 90,
|
|
187
|
-
horizontalFieldOfView: 120,
|
|
188
|
-
verticalFieldOfView: 90
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
view.analyses.add(analysis);
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### ShadowCastAnalysis
|
|
195
|
-
```javascript
|
|
196
|
-
import ShadowCastAnalysis from "@arcgis/core/analysis/ShadowCastAnalysis.js";
|
|
197
|
-
|
|
198
|
-
const analysis = new ShadowCastAnalysis();
|
|
199
|
-
view.analyses.add(analysis);
|
|
200
|
-
|
|
201
|
-
// Configure date/time for shadow calculation
|
|
202
|
-
view.environment.lighting.date = new Date("2024-06-21T12:00:00");
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### SliceAnalysis
|
|
206
|
-
```javascript
|
|
207
|
-
import SliceAnalysis from "@arcgis/core/analysis/SliceAnalysis.js";
|
|
208
|
-
|
|
209
|
-
const analysis = new SliceAnalysis({
|
|
210
|
-
plane: {
|
|
211
|
-
position: { type: "point", x: -122.4, y: 37.8, z: 50 },
|
|
212
|
-
heading: 0,
|
|
213
|
-
tilt: 0
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
view.analyses.add(analysis);
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## REST Services
|
|
221
|
-
|
|
222
|
-
### Routing
|
|
223
|
-
|
|
224
|
-
```javascript
|
|
225
|
-
import route from "@arcgis/core/rest/route.js";
|
|
226
|
-
|
|
227
|
-
const routeParams = {
|
|
228
|
-
stops: [
|
|
229
|
-
{ geometry: { x: -122.4, y: 37.8 } },
|
|
230
|
-
{ geometry: { x: -122.5, y: 37.7 } }
|
|
231
|
-
],
|
|
232
|
-
outSpatialReference: { wkid: 4326 },
|
|
233
|
-
returnDirections: true,
|
|
234
|
-
returnRoutes: true
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
const result = await route.solve(
|
|
238
|
-
"https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World",
|
|
239
|
-
routeParams
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const routeGeometry = result.routeResults[0].route.geometry;
|
|
243
|
-
const directions = result.routeResults[0].directions;
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Geocoding (Address to Location)
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
import locator from "@arcgis/core/rest/locator.js";
|
|
250
|
-
|
|
251
|
-
const results = await locator.addressToLocations(
|
|
252
|
-
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
|
|
253
|
-
{
|
|
254
|
-
address: { SingleLine: "380 New York St, Redlands, CA" },
|
|
255
|
-
outFields: ["*"],
|
|
256
|
-
maxLocations: 5
|
|
257
|
-
}
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
results.forEach(result => {
|
|
261
|
-
console.log(result.address, result.location);
|
|
262
|
-
});
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Reverse Geocoding (Location to Address)
|
|
266
|
-
|
|
267
|
-
```javascript
|
|
268
|
-
import locator from "@arcgis/core/rest/locator.js";
|
|
269
|
-
|
|
270
|
-
const result = await locator.locationToAddress(
|
|
271
|
-
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
|
|
272
|
-
{
|
|
273
|
-
location: { x: -117.195, y: 34.057 }
|
|
274
|
-
}
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
console.log(result.address);
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Geoprocessing
|
|
281
|
-
|
|
282
|
-
```javascript
|
|
283
|
-
import geoprocessor from "@arcgis/core/rest/geoprocessor.js";
|
|
284
|
-
|
|
285
|
-
const params = {
|
|
286
|
-
inputLayer: featureSet,
|
|
287
|
-
distance: 1000,
|
|
288
|
-
distanceUnits: "Meters"
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
const result = await geoprocessor.execute(
|
|
292
|
-
"https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Buffer/GPServer/Buffer",
|
|
293
|
-
params
|
|
294
|
-
);
|
|
295
|
-
|
|
296
|
-
const outputFeatures = result.results[0].value;
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### Print
|
|
300
|
-
|
|
301
|
-
```javascript
|
|
302
|
-
import print from "@arcgis/core/rest/print.js";
|
|
303
|
-
|
|
304
|
-
const params = {
|
|
305
|
-
view: view,
|
|
306
|
-
template: {
|
|
307
|
-
format: "pdf",
|
|
308
|
-
layout: "letter-ansi-a-landscape",
|
|
309
|
-
layoutOptions: {
|
|
310
|
-
titleText: "My Map"
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
const result = await print.execute(
|
|
316
|
-
"https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task",
|
|
317
|
-
params
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
// Download the PDF
|
|
321
|
-
window.open(result.url);
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Places Service
|
|
325
|
-
|
|
326
|
-
```javascript
|
|
327
|
-
import places from "@arcgis/core/rest/places.js";
|
|
328
|
-
import PlacesQueryParameters from "@arcgis/core/rest/support/PlacesQueryParameters.js";
|
|
329
|
-
import FetchPlaceParameters from "@arcgis/core/rest/support/FetchPlaceParameters.js";
|
|
330
|
-
|
|
331
|
-
// Query places near a point
|
|
332
|
-
const queryParams = new PlacesQueryParameters({
|
|
333
|
-
categoryIds: ["4d4b7104d754a06370d81259"], // Arts and Entertainment
|
|
334
|
-
radius: 500, // meters
|
|
335
|
-
point: { type: "point", longitude: -87.626, latitude: 41.882 },
|
|
336
|
-
icon: "png"
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
const results = await places.queryPlacesNearPoint(queryParams);
|
|
340
|
-
|
|
341
|
-
// Process results
|
|
342
|
-
results.results.forEach(place => {
|
|
343
|
-
console.log(place.name, place.location, place.categories[0].label);
|
|
344
|
-
console.log("Distance:", place.distance / 1000, "km");
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// Fetch detailed information about a place
|
|
348
|
-
const fetchParams = new FetchPlaceParameters({
|
|
349
|
-
placeId: results.results[0].placeId,
|
|
350
|
-
requestedFields: ["all"]
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
const details = await places.fetchPlace(fetchParams);
|
|
354
|
-
const placeDetails = details.placeDetails;
|
|
355
|
-
|
|
356
|
-
console.log("Address:", placeDetails.address.streetAddress);
|
|
357
|
-
console.log("Phone:", placeDetails.contactInfo.telephone);
|
|
358
|
-
console.log("Website:", placeDetails.contactInfo.website);
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Places Category IDs
|
|
362
|
-
|
|
363
|
-
| Category | ID |
|
|
364
|
-
|----------|-----|
|
|
365
|
-
| Arts and Entertainment | `4d4b7104d754a06370d81259` |
|
|
366
|
-
| Business Services | `4d4b7105d754a06375d81259` |
|
|
367
|
-
| Community and Government | `63be6904847c3692a84b9b9a` |
|
|
368
|
-
| Dining and Drinking | `63be6904847c3692a84b9bb5` |
|
|
369
|
-
| Health and Medicine | `63be6904847c3692a84b9bb9` |
|
|
370
|
-
| Landmarks and Outdoors | `4d4b7105d754a06377d81259` |
|
|
371
|
-
| Retail | `4d4b7105d754a06378d81259` |
|
|
372
|
-
| Sports and Recreation | `4f4528bc4b90abdf24c9de85` |
|
|
373
|
-
| Travel and Transportation | `4d4b7105d754a06379d81259` |
|
|
374
|
-
|
|
375
|
-
## Feature Queries with Statistics
|
|
376
|
-
|
|
377
|
-
### Basic Statistics
|
|
378
|
-
```javascript
|
|
379
|
-
const query = featureLayer.createQuery();
|
|
380
|
-
query.outStatistics = [
|
|
381
|
-
{
|
|
382
|
-
statisticType: "sum",
|
|
383
|
-
onStatisticField: "population",
|
|
384
|
-
outStatisticFieldName: "totalPop"
|
|
385
|
-
},
|
|
386
|
-
{
|
|
387
|
-
statisticType: "avg",
|
|
388
|
-
onStatisticField: "population",
|
|
389
|
-
outStatisticFieldName: "avgPop"
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
statisticType: "max",
|
|
393
|
-
onStatisticField: "population",
|
|
394
|
-
outStatisticFieldName: "maxPop"
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
statisticType: "min",
|
|
398
|
-
onStatisticField: "population",
|
|
399
|
-
outStatisticFieldName: "minPop"
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
statisticType: "count",
|
|
403
|
-
onStatisticField: "population",
|
|
404
|
-
outStatisticFieldName: "count"
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
statisticType: "stddev",
|
|
408
|
-
onStatisticField: "population",
|
|
409
|
-
outStatisticFieldName: "stdDev"
|
|
410
|
-
}
|
|
411
|
-
];
|
|
412
|
-
|
|
413
|
-
const result = await featureLayer.queryFeatures(query);
|
|
414
|
-
console.log(result.features[0].attributes);
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
### Group By Statistics
|
|
418
|
-
```javascript
|
|
419
|
-
const query = featureLayer.createQuery();
|
|
420
|
-
query.groupByFieldsForStatistics = ["state"];
|
|
421
|
-
query.outStatistics = [{
|
|
422
|
-
statisticType: "sum",
|
|
423
|
-
onStatisticField: "population",
|
|
424
|
-
outStatisticFieldName: "totalPop"
|
|
425
|
-
}];
|
|
426
|
-
query.orderByFields = ["totalPop DESC"];
|
|
427
|
-
|
|
428
|
-
const result = await featureLayer.queryFeatures(query);
|
|
429
|
-
// Returns one feature per state with total population
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
### Spatial Statistics Query
|
|
433
|
-
```javascript
|
|
434
|
-
const query = featureLayer.createQuery();
|
|
435
|
-
query.geometry = view.extent;
|
|
436
|
-
query.spatialRelationship = "intersects";
|
|
437
|
-
query.outStatistics = [{
|
|
438
|
-
statisticType: "count",
|
|
439
|
-
onStatisticField: "ObjectID",
|
|
440
|
-
outStatisticFieldName: "featureCount"
|
|
441
|
-
}];
|
|
442
|
-
|
|
443
|
-
const result = await featureLayer.queryFeatures(query);
|
|
444
|
-
console.log("Features in view:", result.features[0].attributes.featureCount);
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
## Feature Reduction
|
|
448
|
-
|
|
449
|
-
### Clustering
|
|
450
|
-
|
|
451
|
-
```javascript
|
|
452
|
-
const clusterConfig = {
|
|
453
|
-
type: "cluster",
|
|
454
|
-
clusterRadius: "100px",
|
|
455
|
-
clusterMinSize: "24px",
|
|
456
|
-
clusterMaxSize: "60px",
|
|
457
|
-
popupTemplate: {
|
|
458
|
-
title: "Cluster summary",
|
|
459
|
-
content: "This cluster represents {cluster_count} features.",
|
|
460
|
-
fieldInfos: [{
|
|
461
|
-
fieldName: "cluster_count",
|
|
462
|
-
format: { digitSeparator: true, places: 0 }
|
|
463
|
-
}]
|
|
464
|
-
},
|
|
465
|
-
labelingInfo: [{
|
|
466
|
-
deconflictionStrategy: "none",
|
|
467
|
-
labelExpressionInfo: {
|
|
468
|
-
expression: "Text($feature.cluster_count, '#,###')"
|
|
469
|
-
},
|
|
470
|
-
symbol: {
|
|
471
|
-
type: "text",
|
|
472
|
-
color: "white",
|
|
473
|
-
font: { size: "12px", weight: "bold" }
|
|
474
|
-
},
|
|
475
|
-
labelPlacement: "center-center"
|
|
476
|
-
}]
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
featureLayer.featureReduction = clusterConfig;
|
|
480
|
-
|
|
481
|
-
// Toggle clustering
|
|
482
|
-
featureLayer.featureReduction = null; // Disable
|
|
483
|
-
featureLayer.featureReduction = clusterConfig; // Enable
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
### Cluster with Aggregated Fields
|
|
487
|
-
```javascript
|
|
488
|
-
const clusterConfig = {
|
|
489
|
-
type: "cluster",
|
|
490
|
-
clusterRadius: "100px",
|
|
491
|
-
fields: [{
|
|
492
|
-
name: "avg_magnitude",
|
|
493
|
-
statisticType: "avg",
|
|
494
|
-
onStatisticField: "magnitude"
|
|
495
|
-
}, {
|
|
496
|
-
name: "total_count",
|
|
497
|
-
statisticType: "count",
|
|
498
|
-
onStatisticField: "ObjectID"
|
|
499
|
-
}],
|
|
500
|
-
renderer: {
|
|
501
|
-
type: "simple",
|
|
502
|
-
symbol: {
|
|
503
|
-
type: "simple-marker",
|
|
504
|
-
style: "circle",
|
|
505
|
-
color: "#69dcff"
|
|
506
|
-
},
|
|
507
|
-
visualVariables: [{
|
|
508
|
-
type: "size",
|
|
509
|
-
field: "total_count",
|
|
510
|
-
stops: [
|
|
511
|
-
{ value: 1, size: 8 },
|
|
512
|
-
{ value: 100, size: 40 }
|
|
513
|
-
]
|
|
514
|
-
}]
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### Binning
|
|
520
|
-
```javascript
|
|
521
|
-
const binConfig = {
|
|
522
|
-
type: "binning",
|
|
523
|
-
fixedBinLevel: 4, // Level of detail
|
|
524
|
-
renderer: {
|
|
525
|
-
type: "simple",
|
|
526
|
-
symbol: {
|
|
527
|
-
type: "simple-fill",
|
|
528
|
-
outline: { color: "white", width: 0.5 }
|
|
529
|
-
},
|
|
530
|
-
visualVariables: [{
|
|
531
|
-
type: "color",
|
|
532
|
-
field: "aggregateCount",
|
|
533
|
-
stops: [
|
|
534
|
-
{ value: 1, color: "#feebe2" },
|
|
535
|
-
{ value: 50, color: "#fbb4b9" },
|
|
536
|
-
{ value: 100, color: "#f768a1" },
|
|
537
|
-
{ value: 500, color: "#c51b8a" },
|
|
538
|
-
{ value: 1000, color: "#7a0177" }
|
|
539
|
-
]
|
|
540
|
-
}]
|
|
541
|
-
},
|
|
542
|
-
popupTemplate: {
|
|
543
|
-
title: "Bin",
|
|
544
|
-
content: "{aggregateCount} features in this bin"
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
featureLayer.featureReduction = binConfig;
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
## Projection
|
|
552
|
-
|
|
553
|
-
```javascript
|
|
554
|
-
import projectOperator from "@arcgis/core/geometry/operators/projectOperator.js";
|
|
555
|
-
await projectOperator.load();
|
|
556
|
-
|
|
557
|
-
// Project to Web Mercator
|
|
558
|
-
const projected = projectOperator.execute(geometry, { wkid: 3857 });
|
|
559
|
-
|
|
560
|
-
// Project to WGS 84
|
|
561
|
-
const wgs84 = projectOperator.execute(geometry, { wkid: 4326 });
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
## TypeScript Usage
|
|
565
|
-
|
|
566
|
-
Feature reduction configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
|
|
567
|
-
|
|
568
|
-
```typescript
|
|
569
|
-
// Use 'as const' for type safety
|
|
570
|
-
const clusterConfig = {
|
|
571
|
-
type: "cluster",
|
|
572
|
-
clusterRadius: "100px",
|
|
573
|
-
renderer: {
|
|
574
|
-
type: "simple",
|
|
575
|
-
symbol: {
|
|
576
|
-
type: "simple-marker",
|
|
577
|
-
color: "#69dcff"
|
|
578
|
-
}
|
|
579
|
-
} as const,
|
|
580
|
-
labelingInfo: [{
|
|
581
|
-
labelExpressionInfo: {
|
|
582
|
-
expression: "Text($feature.cluster_count, '#,###')"
|
|
583
|
-
},
|
|
584
|
-
symbol: {
|
|
585
|
-
type: "text",
|
|
586
|
-
color: "white"
|
|
587
|
-
} as const
|
|
588
|
-
}]
|
|
589
|
-
} as const;
|
|
590
|
-
|
|
591
|
-
featureLayer.featureReduction = clusterConfig;
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
> **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
|
|
595
|
-
|
|
596
|
-
## Common Pitfalls
|
|
597
|
-
|
|
598
|
-
1. **Operator not loaded**: Most operators require `await operator.load()` before use
|
|
599
|
-
|
|
600
|
-
2. **API key required**: Some REST services (routing, geocoding) require an API key
|
|
601
|
-
|
|
602
|
-
3. **Analysis only in SceneView**: Some analyses (viewshed, line of sight) only work in 3D
|
|
603
|
-
|
|
604
|
-
4. **Cluster fields**: Use `cluster_count` to access feature count in clusters
|
|
605
|
-
|
|
606
|
-
5. **Statistics query returns features**: Statistics queries return features with calculated attributes, not raw numbers
|
|
607
|
-
|
|
1
|
+
---
|
|
2
|
+
name: arcgis-analysis-services
|
|
3
|
+
description: Perform spatial analysis, geometry operations, and use ArcGIS REST services. Use for routing, geocoding, geoprocessing, elevation analysis, viewshed, and feature queries with statistics.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ArcGIS Analysis & Services
|
|
7
|
+
|
|
8
|
+
Use this skill for spatial analysis, geometry operations, REST services, and feature reduction (clustering/binning).
|
|
9
|
+
|
|
10
|
+
## Geometry Operators
|
|
11
|
+
|
|
12
|
+
ArcGIS Maps SDK provides geometry operators for client-side spatial operations.
|
|
13
|
+
|
|
14
|
+
### Loading Operators
|
|
15
|
+
|
|
16
|
+
```javascript
|
|
17
|
+
import bufferOperator from "@arcgis/core/geometry/operators/bufferOperator.js";
|
|
18
|
+
import intersectOperator from "@arcgis/core/geometry/operators/intersectOperator.js";
|
|
19
|
+
import centroidOperator from "@arcgis/core/geometry/operators/centroidOperator.js";
|
|
20
|
+
|
|
21
|
+
// Load before use (most operators require this)
|
|
22
|
+
await bufferOperator.load();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Buffer
|
|
26
|
+
```javascript
|
|
27
|
+
import bufferOperator from "@arcgis/core/geometry/operators/bufferOperator.js";
|
|
28
|
+
await bufferOperator.load();
|
|
29
|
+
|
|
30
|
+
const buffered = bufferOperator.execute(point, 1000); // 1000 meters
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Geodesic Buffer (accurate over large distances)
|
|
34
|
+
```javascript
|
|
35
|
+
import geodesicBufferOperator from "@arcgis/core/geometry/operators/geodesicBufferOperator.js";
|
|
36
|
+
await geodesicBufferOperator.load();
|
|
37
|
+
|
|
38
|
+
const buffered = geodesicBufferOperator.execute(point, {
|
|
39
|
+
distances: [100],
|
|
40
|
+
unit: "kilometers"
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Intersect
|
|
45
|
+
```javascript
|
|
46
|
+
import intersectOperator from "@arcgis/core/geometry/operators/intersectOperator.js";
|
|
47
|
+
await intersectOperator.load();
|
|
48
|
+
|
|
49
|
+
const intersection = intersectOperator.execute(geometry1, geometry2);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Union
|
|
53
|
+
```javascript
|
|
54
|
+
import unionOperator from "@arcgis/core/geometry/operators/unionOperator.js";
|
|
55
|
+
await unionOperator.load();
|
|
56
|
+
|
|
57
|
+
const unioned = unionOperator.execute([polygon1, polygon2, polygon3]);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Centroid
|
|
61
|
+
```javascript
|
|
62
|
+
import centroidOperator from "@arcgis/core/geometry/operators/centroidOperator.js";
|
|
63
|
+
await centroidOperator.load();
|
|
64
|
+
|
|
65
|
+
const centroid = centroidOperator.execute(polygon);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Contains / Within
|
|
69
|
+
```javascript
|
|
70
|
+
import containsOperator from "@arcgis/core/geometry/operators/containsOperator.js";
|
|
71
|
+
await containsOperator.load();
|
|
72
|
+
|
|
73
|
+
const isContained = containsOperator.execute(polygon, point); // true/false
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Distance
|
|
77
|
+
```javascript
|
|
78
|
+
import geodeticLengthOperator from "@arcgis/core/geometry/operators/geodeticLengthOperator.js";
|
|
79
|
+
await geodeticLengthOperator.load();
|
|
80
|
+
|
|
81
|
+
const length = geodeticLengthOperator.execute(polyline, { unit: "miles" });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Area
|
|
85
|
+
```javascript
|
|
86
|
+
import geodeticAreaOperator from "@arcgis/core/geometry/operators/geodeticAreaOperator.js";
|
|
87
|
+
await geodeticAreaOperator.load();
|
|
88
|
+
|
|
89
|
+
const area = geodeticAreaOperator.execute(polygon, { unit: "square-kilometers" });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Available Operators
|
|
93
|
+
|
|
94
|
+
| Operator | Purpose |
|
|
95
|
+
|----------|---------|
|
|
96
|
+
| `bufferOperator` | Create buffer around geometry |
|
|
97
|
+
| `geodesicBufferOperator` | Geodetic buffer (accurate) |
|
|
98
|
+
| `intersectOperator` | Find intersection |
|
|
99
|
+
| `unionOperator` | Combine geometries |
|
|
100
|
+
| `differenceOperator` | Subtract geometries |
|
|
101
|
+
| `clipOperator` | Clip geometry by envelope |
|
|
102
|
+
| `convexHullOperator` | Create convex hull |
|
|
103
|
+
| `centroidOperator` | Get centroid point |
|
|
104
|
+
| `containsOperator` | Test if contains |
|
|
105
|
+
| `withinOperator` | Test if within |
|
|
106
|
+
| `intersectsOperator` | Test if intersects |
|
|
107
|
+
| `distanceOperator` | Calculate planar distance |
|
|
108
|
+
| `geodeticLengthOperator` | Calculate geodetic length |
|
|
109
|
+
| `geodeticAreaOperator` | Calculate geodetic area |
|
|
110
|
+
| `simplifyOperator` | Simplify geometry |
|
|
111
|
+
| `densifyOperator` | Add vertices to geometry |
|
|
112
|
+
| `projectOperator` | Project to spatial reference |
|
|
113
|
+
|
|
114
|
+
## Analysis Objects
|
|
115
|
+
|
|
116
|
+
### ElevationProfileAnalysis
|
|
117
|
+
```javascript
|
|
118
|
+
import ElevationProfileAnalysis from "@arcgis/core/analysis/ElevationProfileAnalysis.js";
|
|
119
|
+
|
|
120
|
+
const analysis = new ElevationProfileAnalysis({
|
|
121
|
+
profiles: [
|
|
122
|
+
{ type: "ground", color: "brown" },
|
|
123
|
+
{ type: "input", color: "blue" }
|
|
124
|
+
],
|
|
125
|
+
displayUnits: {
|
|
126
|
+
distance: "meters",
|
|
127
|
+
elevation: "meters"
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Add to SceneView
|
|
132
|
+
view.analyses.add(analysis);
|
|
133
|
+
|
|
134
|
+
// Set line geometry
|
|
135
|
+
analysis.geometry = polyline;
|
|
136
|
+
|
|
137
|
+
// Get analysis view for results
|
|
138
|
+
const analysisView = await view.whenAnalysisView(analysis);
|
|
139
|
+
|
|
140
|
+
// Watch progress and results
|
|
141
|
+
reactiveUtils.watch(
|
|
142
|
+
() => analysisView.progress,
|
|
143
|
+
(progress) => {
|
|
144
|
+
if (progress === 1) {
|
|
145
|
+
console.log("Results:", analysisView.results);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### LineOfSightAnalysis
|
|
152
|
+
```javascript
|
|
153
|
+
import LineOfSightAnalysis from "@arcgis/core/analysis/LineOfSightAnalysis.js";
|
|
154
|
+
|
|
155
|
+
const analysis = new LineOfSightAnalysis({
|
|
156
|
+
observer: {
|
|
157
|
+
type: "point",
|
|
158
|
+
x: -122.4,
|
|
159
|
+
y: 37.8,
|
|
160
|
+
z: 100,
|
|
161
|
+
spatialReference: { wkid: 4326 }
|
|
162
|
+
},
|
|
163
|
+
targets: [
|
|
164
|
+
{ type: "point", x: -122.41, y: 37.81, z: 50 },
|
|
165
|
+
{ type: "point", x: -122.42, y: 37.79, z: 75 }
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
view.analyses.add(analysis);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### ViewshedAnalysis
|
|
173
|
+
```javascript
|
|
174
|
+
import ViewshedAnalysis from "@arcgis/core/analysis/ViewshedAnalysis.js";
|
|
175
|
+
|
|
176
|
+
const analysis = new ViewshedAnalysis({
|
|
177
|
+
observer: {
|
|
178
|
+
type: "point",
|
|
179
|
+
x: -122.4,
|
|
180
|
+
y: 37.8,
|
|
181
|
+
z: 100,
|
|
182
|
+
spatialReference: { wkid: 4326 }
|
|
183
|
+
},
|
|
184
|
+
farDistance: 1000,
|
|
185
|
+
heading: 45,
|
|
186
|
+
tilt: 90,
|
|
187
|
+
horizontalFieldOfView: 120,
|
|
188
|
+
verticalFieldOfView: 90
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
view.analyses.add(analysis);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### ShadowCastAnalysis
|
|
195
|
+
```javascript
|
|
196
|
+
import ShadowCastAnalysis from "@arcgis/core/analysis/ShadowCastAnalysis.js";
|
|
197
|
+
|
|
198
|
+
const analysis = new ShadowCastAnalysis();
|
|
199
|
+
view.analyses.add(analysis);
|
|
200
|
+
|
|
201
|
+
// Configure date/time for shadow calculation
|
|
202
|
+
view.environment.lighting.date = new Date("2024-06-21T12:00:00");
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### SliceAnalysis
|
|
206
|
+
```javascript
|
|
207
|
+
import SliceAnalysis from "@arcgis/core/analysis/SliceAnalysis.js";
|
|
208
|
+
|
|
209
|
+
const analysis = new SliceAnalysis({
|
|
210
|
+
plane: {
|
|
211
|
+
position: { type: "point", x: -122.4, y: 37.8, z: 50 },
|
|
212
|
+
heading: 0,
|
|
213
|
+
tilt: 0
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
view.analyses.add(analysis);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## REST Services
|
|
221
|
+
|
|
222
|
+
### Routing
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
import route from "@arcgis/core/rest/route.js";
|
|
226
|
+
|
|
227
|
+
const routeParams = {
|
|
228
|
+
stops: [
|
|
229
|
+
{ geometry: { x: -122.4, y: 37.8 } },
|
|
230
|
+
{ geometry: { x: -122.5, y: 37.7 } }
|
|
231
|
+
],
|
|
232
|
+
outSpatialReference: { wkid: 4326 },
|
|
233
|
+
returnDirections: true,
|
|
234
|
+
returnRoutes: true
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const result = await route.solve(
|
|
238
|
+
"https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World",
|
|
239
|
+
routeParams
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const routeGeometry = result.routeResults[0].route.geometry;
|
|
243
|
+
const directions = result.routeResults[0].directions;
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Geocoding (Address to Location)
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import locator from "@arcgis/core/rest/locator.js";
|
|
250
|
+
|
|
251
|
+
const results = await locator.addressToLocations(
|
|
252
|
+
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
|
|
253
|
+
{
|
|
254
|
+
address: { SingleLine: "380 New York St, Redlands, CA" },
|
|
255
|
+
outFields: ["*"],
|
|
256
|
+
maxLocations: 5
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
results.forEach(result => {
|
|
261
|
+
console.log(result.address, result.location);
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Reverse Geocoding (Location to Address)
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
import locator from "@arcgis/core/rest/locator.js";
|
|
269
|
+
|
|
270
|
+
const result = await locator.locationToAddress(
|
|
271
|
+
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
|
|
272
|
+
{
|
|
273
|
+
location: { x: -117.195, y: 34.057 }
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
console.log(result.address);
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Geoprocessing
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
import geoprocessor from "@arcgis/core/rest/geoprocessor.js";
|
|
284
|
+
|
|
285
|
+
const params = {
|
|
286
|
+
inputLayer: featureSet,
|
|
287
|
+
distance: 1000,
|
|
288
|
+
distanceUnits: "Meters"
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const result = await geoprocessor.execute(
|
|
292
|
+
"https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Buffer/GPServer/Buffer",
|
|
293
|
+
params
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
const outputFeatures = result.results[0].value;
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Print
|
|
300
|
+
|
|
301
|
+
```javascript
|
|
302
|
+
import print from "@arcgis/core/rest/print.js";
|
|
303
|
+
|
|
304
|
+
const params = {
|
|
305
|
+
view: view,
|
|
306
|
+
template: {
|
|
307
|
+
format: "pdf",
|
|
308
|
+
layout: "letter-ansi-a-landscape",
|
|
309
|
+
layoutOptions: {
|
|
310
|
+
titleText: "My Map"
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const result = await print.execute(
|
|
316
|
+
"https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task",
|
|
317
|
+
params
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
// Download the PDF
|
|
321
|
+
window.open(result.url);
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Places Service
|
|
325
|
+
|
|
326
|
+
```javascript
|
|
327
|
+
import places from "@arcgis/core/rest/places.js";
|
|
328
|
+
import PlacesQueryParameters from "@arcgis/core/rest/support/PlacesQueryParameters.js";
|
|
329
|
+
import FetchPlaceParameters from "@arcgis/core/rest/support/FetchPlaceParameters.js";
|
|
330
|
+
|
|
331
|
+
// Query places near a point
|
|
332
|
+
const queryParams = new PlacesQueryParameters({
|
|
333
|
+
categoryIds: ["4d4b7104d754a06370d81259"], // Arts and Entertainment
|
|
334
|
+
radius: 500, // meters
|
|
335
|
+
point: { type: "point", longitude: -87.626, latitude: 41.882 },
|
|
336
|
+
icon: "png"
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const results = await places.queryPlacesNearPoint(queryParams);
|
|
340
|
+
|
|
341
|
+
// Process results
|
|
342
|
+
results.results.forEach(place => {
|
|
343
|
+
console.log(place.name, place.location, place.categories[0].label);
|
|
344
|
+
console.log("Distance:", place.distance / 1000, "km");
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// Fetch detailed information about a place
|
|
348
|
+
const fetchParams = new FetchPlaceParameters({
|
|
349
|
+
placeId: results.results[0].placeId,
|
|
350
|
+
requestedFields: ["all"]
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const details = await places.fetchPlace(fetchParams);
|
|
354
|
+
const placeDetails = details.placeDetails;
|
|
355
|
+
|
|
356
|
+
console.log("Address:", placeDetails.address.streetAddress);
|
|
357
|
+
console.log("Phone:", placeDetails.contactInfo.telephone);
|
|
358
|
+
console.log("Website:", placeDetails.contactInfo.website);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Places Category IDs
|
|
362
|
+
|
|
363
|
+
| Category | ID |
|
|
364
|
+
|----------|-----|
|
|
365
|
+
| Arts and Entertainment | `4d4b7104d754a06370d81259` |
|
|
366
|
+
| Business Services | `4d4b7105d754a06375d81259` |
|
|
367
|
+
| Community and Government | `63be6904847c3692a84b9b9a` |
|
|
368
|
+
| Dining and Drinking | `63be6904847c3692a84b9bb5` |
|
|
369
|
+
| Health and Medicine | `63be6904847c3692a84b9bb9` |
|
|
370
|
+
| Landmarks and Outdoors | `4d4b7105d754a06377d81259` |
|
|
371
|
+
| Retail | `4d4b7105d754a06378d81259` |
|
|
372
|
+
| Sports and Recreation | `4f4528bc4b90abdf24c9de85` |
|
|
373
|
+
| Travel and Transportation | `4d4b7105d754a06379d81259` |
|
|
374
|
+
|
|
375
|
+
## Feature Queries with Statistics
|
|
376
|
+
|
|
377
|
+
### Basic Statistics
|
|
378
|
+
```javascript
|
|
379
|
+
const query = featureLayer.createQuery();
|
|
380
|
+
query.outStatistics = [
|
|
381
|
+
{
|
|
382
|
+
statisticType: "sum",
|
|
383
|
+
onStatisticField: "population",
|
|
384
|
+
outStatisticFieldName: "totalPop"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
statisticType: "avg",
|
|
388
|
+
onStatisticField: "population",
|
|
389
|
+
outStatisticFieldName: "avgPop"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
statisticType: "max",
|
|
393
|
+
onStatisticField: "population",
|
|
394
|
+
outStatisticFieldName: "maxPop"
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
statisticType: "min",
|
|
398
|
+
onStatisticField: "population",
|
|
399
|
+
outStatisticFieldName: "minPop"
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
statisticType: "count",
|
|
403
|
+
onStatisticField: "population",
|
|
404
|
+
outStatisticFieldName: "count"
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
statisticType: "stddev",
|
|
408
|
+
onStatisticField: "population",
|
|
409
|
+
outStatisticFieldName: "stdDev"
|
|
410
|
+
}
|
|
411
|
+
];
|
|
412
|
+
|
|
413
|
+
const result = await featureLayer.queryFeatures(query);
|
|
414
|
+
console.log(result.features[0].attributes);
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Group By Statistics
|
|
418
|
+
```javascript
|
|
419
|
+
const query = featureLayer.createQuery();
|
|
420
|
+
query.groupByFieldsForStatistics = ["state"];
|
|
421
|
+
query.outStatistics = [{
|
|
422
|
+
statisticType: "sum",
|
|
423
|
+
onStatisticField: "population",
|
|
424
|
+
outStatisticFieldName: "totalPop"
|
|
425
|
+
}];
|
|
426
|
+
query.orderByFields = ["totalPop DESC"];
|
|
427
|
+
|
|
428
|
+
const result = await featureLayer.queryFeatures(query);
|
|
429
|
+
// Returns one feature per state with total population
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Spatial Statistics Query
|
|
433
|
+
```javascript
|
|
434
|
+
const query = featureLayer.createQuery();
|
|
435
|
+
query.geometry = view.extent;
|
|
436
|
+
query.spatialRelationship = "intersects";
|
|
437
|
+
query.outStatistics = [{
|
|
438
|
+
statisticType: "count",
|
|
439
|
+
onStatisticField: "ObjectID",
|
|
440
|
+
outStatisticFieldName: "featureCount"
|
|
441
|
+
}];
|
|
442
|
+
|
|
443
|
+
const result = await featureLayer.queryFeatures(query);
|
|
444
|
+
console.log("Features in view:", result.features[0].attributes.featureCount);
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Feature Reduction
|
|
448
|
+
|
|
449
|
+
### Clustering
|
|
450
|
+
|
|
451
|
+
```javascript
|
|
452
|
+
const clusterConfig = {
|
|
453
|
+
type: "cluster",
|
|
454
|
+
clusterRadius: "100px",
|
|
455
|
+
clusterMinSize: "24px",
|
|
456
|
+
clusterMaxSize: "60px",
|
|
457
|
+
popupTemplate: {
|
|
458
|
+
title: "Cluster summary",
|
|
459
|
+
content: "This cluster represents {cluster_count} features.",
|
|
460
|
+
fieldInfos: [{
|
|
461
|
+
fieldName: "cluster_count",
|
|
462
|
+
format: { digitSeparator: true, places: 0 }
|
|
463
|
+
}]
|
|
464
|
+
},
|
|
465
|
+
labelingInfo: [{
|
|
466
|
+
deconflictionStrategy: "none",
|
|
467
|
+
labelExpressionInfo: {
|
|
468
|
+
expression: "Text($feature.cluster_count, '#,###')"
|
|
469
|
+
},
|
|
470
|
+
symbol: {
|
|
471
|
+
type: "text",
|
|
472
|
+
color: "white",
|
|
473
|
+
font: { size: "12px", weight: "bold" }
|
|
474
|
+
},
|
|
475
|
+
labelPlacement: "center-center"
|
|
476
|
+
}]
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
featureLayer.featureReduction = clusterConfig;
|
|
480
|
+
|
|
481
|
+
// Toggle clustering
|
|
482
|
+
featureLayer.featureReduction = null; // Disable
|
|
483
|
+
featureLayer.featureReduction = clusterConfig; // Enable
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Cluster with Aggregated Fields
|
|
487
|
+
```javascript
|
|
488
|
+
const clusterConfig = {
|
|
489
|
+
type: "cluster",
|
|
490
|
+
clusterRadius: "100px",
|
|
491
|
+
fields: [{
|
|
492
|
+
name: "avg_magnitude",
|
|
493
|
+
statisticType: "avg",
|
|
494
|
+
onStatisticField: "magnitude"
|
|
495
|
+
}, {
|
|
496
|
+
name: "total_count",
|
|
497
|
+
statisticType: "count",
|
|
498
|
+
onStatisticField: "ObjectID"
|
|
499
|
+
}],
|
|
500
|
+
renderer: {
|
|
501
|
+
type: "simple",
|
|
502
|
+
symbol: {
|
|
503
|
+
type: "simple-marker",
|
|
504
|
+
style: "circle",
|
|
505
|
+
color: "#69dcff"
|
|
506
|
+
},
|
|
507
|
+
visualVariables: [{
|
|
508
|
+
type: "size",
|
|
509
|
+
field: "total_count",
|
|
510
|
+
stops: [
|
|
511
|
+
{ value: 1, size: 8 },
|
|
512
|
+
{ value: 100, size: 40 }
|
|
513
|
+
]
|
|
514
|
+
}]
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Binning
|
|
520
|
+
```javascript
|
|
521
|
+
const binConfig = {
|
|
522
|
+
type: "binning",
|
|
523
|
+
fixedBinLevel: 4, // Level of detail
|
|
524
|
+
renderer: {
|
|
525
|
+
type: "simple",
|
|
526
|
+
symbol: {
|
|
527
|
+
type: "simple-fill",
|
|
528
|
+
outline: { color: "white", width: 0.5 }
|
|
529
|
+
},
|
|
530
|
+
visualVariables: [{
|
|
531
|
+
type: "color",
|
|
532
|
+
field: "aggregateCount",
|
|
533
|
+
stops: [
|
|
534
|
+
{ value: 1, color: "#feebe2" },
|
|
535
|
+
{ value: 50, color: "#fbb4b9" },
|
|
536
|
+
{ value: 100, color: "#f768a1" },
|
|
537
|
+
{ value: 500, color: "#c51b8a" },
|
|
538
|
+
{ value: 1000, color: "#7a0177" }
|
|
539
|
+
]
|
|
540
|
+
}]
|
|
541
|
+
},
|
|
542
|
+
popupTemplate: {
|
|
543
|
+
title: "Bin",
|
|
544
|
+
content: "{aggregateCount} features in this bin"
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
featureLayer.featureReduction = binConfig;
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Projection
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
import projectOperator from "@arcgis/core/geometry/operators/projectOperator.js";
|
|
555
|
+
await projectOperator.load();
|
|
556
|
+
|
|
557
|
+
// Project to Web Mercator
|
|
558
|
+
const projected = projectOperator.execute(geometry, { wkid: 3857 });
|
|
559
|
+
|
|
560
|
+
// Project to WGS 84
|
|
561
|
+
const wgs84 = projectOperator.execute(geometry, { wkid: 4326 });
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
## TypeScript Usage
|
|
565
|
+
|
|
566
|
+
Feature reduction configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
// Use 'as const' for type safety
|
|
570
|
+
const clusterConfig = {
|
|
571
|
+
type: "cluster",
|
|
572
|
+
clusterRadius: "100px",
|
|
573
|
+
renderer: {
|
|
574
|
+
type: "simple",
|
|
575
|
+
symbol: {
|
|
576
|
+
type: "simple-marker",
|
|
577
|
+
color: "#69dcff"
|
|
578
|
+
}
|
|
579
|
+
} as const,
|
|
580
|
+
labelingInfo: [{
|
|
581
|
+
labelExpressionInfo: {
|
|
582
|
+
expression: "Text($feature.cluster_count, '#,###')"
|
|
583
|
+
},
|
|
584
|
+
symbol: {
|
|
585
|
+
type: "text",
|
|
586
|
+
color: "white"
|
|
587
|
+
} as const
|
|
588
|
+
}]
|
|
589
|
+
} as const;
|
|
590
|
+
|
|
591
|
+
featureLayer.featureReduction = clusterConfig;
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
> **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
|
|
595
|
+
|
|
596
|
+
## Common Pitfalls
|
|
597
|
+
|
|
598
|
+
1. **Operator not loaded**: Most operators require `await operator.load()` before use
|
|
599
|
+
|
|
600
|
+
2. **API key required**: Some REST services (routing, geocoding) require an API key
|
|
601
|
+
|
|
602
|
+
3. **Analysis only in SceneView**: Some analyses (viewshed, line of sight) only work in 3D
|
|
603
|
+
|
|
604
|
+
4. **Cluster fields**: Use `cluster_count` to access feature count in clusters
|
|
605
|
+
|
|
606
|
+
5. **Statistics query returns features**: Statistics queries return features with calculated attributes, not raw numbers
|
|
607
|
+
|