arcgis-map-tools

Use this skill for swipe comparison, measurement tools, identify operations, and routing services.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "arcgis-map-tools" with this command: npx skills add saschabrunnerch/arcgis-maps-sdk-js-ai-context/saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-map-tools

ArcGIS Map Tools

Use this skill for swipe comparison, measurement tools, identify operations, and routing services.

Swipe Widget

Swipe Component

<arcgis-map zoom="15" center="-154.88, 19.46"> <arcgis-zoom slot="top-left"></arcgis-zoom> <arcgis-swipe swipe-position="32"></arcgis-swipe> </arcgis-map>

<script type="module"> import Map from "@arcgis/core/Map.js"; import TileLayer from "@arcgis/core/layers/TileLayer.js";

const viewElement = document.querySelector("arcgis-map"); const arcgisSwipe = document.querySelector("arcgis-swipe");

const layer1 = new TileLayer({ url: "..." }); const layer2 = new TileLayer({ url: "..." });

viewElement.map = new Map({ basemap: "satellite", layers: [layer1, layer2] });

// Configure swipe when ready arcgisSwipe.addEventListener("arcgisPropertyChange", (e) => { if (e.detail.name === "state" && arcgisSwipe.state === "ready") { arcgisSwipe.leadingLayers.add(layer1); arcgisSwipe.trailingLayers.add(layer2); } }); </script>

Swipe Widget (Core API) - Deprecated

DEPRECATED since 4.32: Use the arcgis-swipe component shown above instead. For information on widget deprecation, see Esri's move to web components.

// DEPRECATED - Use arcgis-swipe component instead import Swipe from "@arcgis/core/widgets/Swipe.js";

const swipe = new Swipe({ view: view, leadingLayers: [layer1], trailingLayers: [layer2], position: 50, // Percentage from left direction: "horizontal" // or "vertical" });

view.ui.add(swipe);

Measurement

Measurement Components

<!-- 2D Measurement --> <arcgis-map> <arcgis-distance-measurement-2d slot="top-right"></arcgis-distance-measurement-2d> <arcgis-area-measurement-2d slot="top-right"></arcgis-area-measurement-2d> </arcgis-map>

<!-- 3D Measurement --> <arcgis-scene> <arcgis-direct-line-measurement-3d slot="top-right"></arcgis-direct-line-measurement-3d> <arcgis-area-measurement-3d slot="top-right"></arcgis-area-measurement-3d> </arcgis-scene>

Measurement Widget (Core API)

import Measurement from "@arcgis/core/widgets/Measurement.js";

const measurement = new Measurement({ view: view });

view.ui.add(measurement, "bottom-right");

// Activate distance measurement // For 2D: "distance", For 3D: "direct-line" measurement.activeTool = view.type === "2d" ? "distance" : "direct-line";

// Activate area measurement measurement.activeTool = "area";

// Clear measurements measurement.clear();

2D Measurement Widgets (Core API)

import DistanceMeasurement2D from "@arcgis/core/widgets/DistanceMeasurement2D.js"; import AreaMeasurement2D from "@arcgis/core/widgets/AreaMeasurement2D.js";

// Distance measurement const distanceWidget = new DistanceMeasurement2D({ view: view, unit: "kilometers" }); view.ui.add(distanceWidget, "top-right");

// Area measurement const areaWidget = new AreaMeasurement2D({ view: view, unit: "square-kilometers" }); view.ui.add(areaWidget, "top-right");

3D Measurement Widgets (Core API)

import DirectLineMeasurement3D from "@arcgis/core/widgets/DirectLineMeasurement3D.js"; import AreaMeasurement3D from "@arcgis/core/widgets/AreaMeasurement3D.js";

// Direct line measurement (3D) const lineWidget = new DirectLineMeasurement3D({ view: sceneView, unit: "meters" });

// Area measurement (3D) const areaWidget = new AreaMeasurement3D({ view: sceneView, unit: "square-meters" });

Identify

Identify on MapImageLayer

import * as identify from "@arcgis/core/rest/identify.js"; import IdentifyParameters from "@arcgis/core/rest/support/IdentifyParameters.js";

const identifyURL = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/MtBaldy_BaseMap/MapServer";

// Set up parameters const params = new IdentifyParameters({ tolerance: 3, layerIds: [0, 1, 2, 3, 4], layerOption: "top", // "top", "visible", "all" width: view.width, height: view.height });

// Execute on click view.on("click", async (event) => { params.geometry = event.mapPoint; params.mapExtent = view.extent;

const response = await identify.identify(identifyURL, params);

const features = response.results.map(result => { const feature = result.feature; feature.attributes.layerName = result.layerName;

// Set popup template based on layer
if (result.layerName === "Roads") {
  feature.popupTemplate = {
    title: "Road",
    content: "&#x3C;b>Length:&#x3C;/b> {Shape_Length}"
  };
}
return feature;

});

if (features.length > 0) { view.openPopup({ features: features, location: event.mapPoint }); } });

Routing

Basic Route

import * as route from "@arcgis/core/rest/route.js"; import RouteParameters from "@arcgis/core/rest/support/RouteParameters.js"; import FeatureSet from "@arcgis/core/rest/support/FeatureSet.js"; import Graphic from "@arcgis/core/Graphic.js"; import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";

const routeUrl = "https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";

const routeLayer = new GraphicsLayer(); map.add(routeLayer);

const routeParams = new RouteParameters({ apiKey: "YOUR_API_KEY", stops: new FeatureSet(), outSpatialReference: { wkid: 3857 } });

// Add stop on click view.on("click", async (event) => { const stop = new Graphic({ geometry: event.mapPoint, symbol: { type: "simple-marker", style: "cross", size: 15 } }); routeLayer.add(stop); routeParams.stops.features.push(stop);

// Solve route when 2+ stops if (routeParams.stops.features.length >= 2) { const result = await route.solve(routeUrl, routeParams); const routeResult = result.routeResults[0].route; routeResult.symbol = { type: "simple-line", color: [0, 0, 255, 0.5], width: 5 }; routeLayer.add(routeResult); } });

Route with Options

const routeParams = new RouteParameters({ apiKey: "YOUR_API_KEY", stops: new FeatureSet({ features: stopGraphics }), returnDirections: true, directionsLanguage: "en", returnRoutes: true, returnStops: true, impedanceAttribute: "TravelTime", // or "Miles", "Kilometers" restrictionAttributes: ["Avoid Toll Roads"], outSpatialReference: { wkid: 4326 } });

const result = await route.solve(routeUrl, routeParams);

// Get directions const directions = result.routeResults[0].directions; directions.features.forEach(feature => { console.log(feature.attributes.text); });

Directions Widget

Directions Component

<arcgis-map> <arcgis-directions slot="top-right"></arcgis-directions> </arcgis-map>

Directions Widget (Core API)

import Directions from "@arcgis/core/widgets/Directions.js";

const directions = new Directions({ view: view, apiKey: "YOUR_API_KEY" });

view.ui.add(directions, "top-right");

Print

Print Component

<arcgis-map item-id="YOUR_WEBMAP_ID"> <arcgis-expand slot="top-right" expand-tooltip="Print"> <arcgis-print></arcgis-print> </arcgis-expand> </arcgis-map>

Print Service

import * as print from "@arcgis/core/rest/print.js"; import PrintTemplate from "@arcgis/core/rest/support/PrintTemplate.js"; import PrintParameters from "@arcgis/core/rest/support/PrintParameters.js";

const printUrl = "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";

const template = new PrintTemplate({ format: "pdf", layout: "a4-landscape", layoutOptions: { titleText: "My Map", authorText: "Author Name" } });

const params = new PrintParameters({ view: view, template: template });

const result = await print.execute(printUrl, params); console.log("PDF URL:", result.url);

PrintTemplate Configuration

import PrintTemplate from "@arcgis/core/rest/support/PrintTemplate.js";

const template = new PrintTemplate({ // Output format format: "pdf", // pdf, png32, png8, jpg, gif, eps, svg, svgz

// Layout template name (from print service) layout: "a4-landscape", // Or custom layout name

// Export options for map-only output exportOptions: { width: 800, height: 600, dpi: 300 },

// Layout customization layoutOptions: { titleText: "Map Title", authorText: "Created by", copyrightText: "Copyright 2024", scalebarUnit: "Kilometers", // Kilometers, Miles legendLayers: [], // Layers to include in legend customTextElements: [ { customText: "Custom field value" } ] },

// Preserve scale or extent outScale: 50000, // Fixed scale scalePreserved: true, // Maintain current scale

// Include attribution attributionVisible: true });

Print Formats

Format Description

pdf

Adobe PDF

png32

PNG with transparency (32-bit)

png8

PNG 8-bit

jpg

JPEG

gif

GIF

eps

Encapsulated PostScript

svg

Scalable Vector Graphics

svgz

Compressed SVG

Map-Only Export (No Layout)

const template = new PrintTemplate({ format: "png32", layout: "map-only", // No layout template exportOptions: { width: 1920, height: 1080, dpi: 96 } });

High-Resolution Export

const template = new PrintTemplate({ format: "pdf", layout: "a3-landscape", exportOptions: { dpi: 300 // High DPI for print quality }, layoutOptions: { titleText: "High Resolution Map", scalebarUnit: "Miles" }, scalePreserved: true });

Print with Custom Extent

const template = new PrintTemplate({ format: "pdf", layout: "letter-ansi-a-landscape", outScale: 24000 // 1:24000 scale });

const params = new PrintParameters({ view: view, template: template, extraParameters: { // Custom extent (optional) extent: { xmin: -117.2, ymin: 34.0, xmax: -117.1, ymax: 34.1, spatialReference: { wkid: 4326 } } } });

Print Widget (Core API)

import Print from "@arcgis/core/widgets/Print.js";

const print = new Print({ view: view, printServiceUrl: "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task" });

view.ui.add(print, "top-right");

Print Widget Configuration (Core API)

import Print from "@arcgis/core/widgets/Print.js";

const print = new Print({ view: view, printServiceUrl: printUrl,

// Allowed formats allowedFormats: ["pdf", "png32", "jpg"],

// Allowed layouts allowedLayouts: ["a4-landscape", "a4-portrait", "letter-ansi-a-landscape"],

// Default template settings templateOptions: { title: "Default Map Title", author: "Default Author", copyright: "Copyright 2024", scaleEnabled: true, attributionEnabled: true },

// Include legend includeDefaultTemplates: true });

Print Widget State

// Track print widget state import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";

reactiveUtils.watch( () => printWidget.viewModel.state, (state) => { console.log("Print state:", state); // ready, printing, complete, error } );

Custom Print Workflow

async function printMap(view, options = {}) { const { title = "Map Export", format = "pdf", layout = "a4-landscape", dpi = 150 } = options;

const template = new PrintTemplate({ format, layout, exportOptions: { dpi }, layoutOptions: { titleText: title, authorText: "Generated by Web App", copyrightText: Exported: ${new Date().toLocaleDateString()} } });

const params = new PrintParameters({ view, template });

try { const result = await print.execute(printUrl, params); return result.url; } catch (error) { console.error("Print failed:", error); throw error; } }

// Usage const pdfUrl = await printMap(view, { title: "Project Area Map", format: "pdf", dpi: 300 }); window.open(pdfUrl, "_blank");

Print with Legend Customization

const template = new PrintTemplate({ format: "pdf", layout: "a4-landscape", layoutOptions: { titleText: "Map with Custom Legend", // Specify which layers to include in legend legendLayers: [ { layerId: featureLayer.id }, { layerId: anotherLayer.id, sublayerIds: [0, 2] } // Specific sublayers ] } });

Screenshot as Alternative

For quick exports without a print service:

// Take screenshot of current view const screenshot = await view.takeScreenshot({ format: "png", width: 1920, height: 1080, quality: 90 });

// Use the data URL const img = document.createElement("img"); img.src = screenshot.dataUrl; document.body.appendChild(img);

// Or download const link = document.createElement("a"); link.download = "map-screenshot.png"; link.href = screenshot.dataUrl; link.click();

Find

Find Service

import * as find from "@arcgis/core/rest/find.js"; import FindParameters from "@arcgis/core/rest/support/FindParameters.js";

const findUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer";

const params = new FindParameters({ searchText: "California", layerIds: [0, 1, 2], searchFields: ["STATE_NAME", "NAME"], returnGeometry: true });

const result = await find.find(findUrl, params);

result.results.forEach(r => { console.log(r.feature.attributes); });

Complete Example

<!DOCTYPE html> <html> <head> <script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js">&#x3C;/script> <script src="https://js.arcgis.com/4.34/">&#x3C;/script> <script type="module" src="https://js.arcgis.com/4.34/map-components/">&#x3C;/script> <style> html, body { height: 100%; margin: 0; } #toolbar { position: absolute; top: 10px; right: 10px; } </style> </head> <body> <arcgis-map basemap="streets-navigation-vector" center="-117.195, 34.057" zoom="13"> <arcgis-zoom slot="top-left"></arcgis-zoom> </arcgis-map> <div id="toolbar"> <calcite-button id="measureBtn">Measure</calcite-button> <calcite-button id="clearBtn">Clear</calcite-button> </div>

<script type="module"> import Measurement from "@arcgis/core/widgets/Measurement.js";

const viewElement = document.querySelector("arcgis-map");
await viewElement.viewOnReady();

const measurement = new Measurement({ view: viewElement.view });
viewElement.ui.add(measurement, "bottom-right");

document.getElementById("measureBtn").onclick = () => {
  measurement.activeTool = "distance";
};

document.getElementById("clearBtn").onclick = () => {
  measurement.clear();
};

</script> </body> </html>

Reference Samples

  • widgets-measurement

  • Distance and area measurement tools

  • widgets-print

  • Print widget for map export

  • widgets-directions

  • Directions widget for routing

  • swipe

  • Swipe widget for comparing layers

  • identify

  • Identify features on the map

Common Pitfalls

API Key for routing: Route service requires valid API key or authenticated user

Identify tolerance: Set appropriate tolerance based on zoom level

Swipe layer order: Leading/trailing layers must be in the map's layers collection

Measurement units: Set appropriate units for the measurement context

3D vs 2D measurement: Use different widgets/tools for 2D and 3D views

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

arcgis-widgets-ui

No summary provided by upstream source.

Repository SourceNeeds Review
General

arcgis-popup-templates

No summary provided by upstream source.

Repository SourceNeeds Review
General

arcgis-geometry-operations

No summary provided by upstream source.

Repository SourceNeeds Review