Select to view content in your preferred language

Swipe Multiple Web Maps (using map components)

370
3
Jump to solution
04-15-2025 02:40 PM
JaredPilbeam2
MVP Alum

This question is a continuation of my last post. I'm attempting to combine Swipe and Map.

In my sample, my goal is to initialize on the 1862 webmap with the basemap and vector tile layer as the leading swipe layer. The webmaps should be the trailing swipe layers. Then, I want the ability to click back and forth between the other webmap(s) while also being able to swipe. Right now, the swipe doesn't mesh with the webmaps. When I click one of the buttons I get:

Uncaught (in promise) "No layerview has been found for the layer"

What's confusing me is that components do not use views as far as I understand. Here's how I did it with the current JS SDK:

<script>
require(["esri/Map",
            "esri/views/MapView",
            "esri/layers/ImageryLayer",
            "esri/widgets/Swipe",
            "esri/WebMap",
        ], (Map, MapView, ImageryLayer, Swipe, WebMap) => {
            //webmap IDs
            /************************************************************
          * Create multiple WebMap instances
          ************************************************************/
            const webmapids = [
                "e67a8eb6768641c19d4a7c5df394dbf4", //DTM
                "bfc5b0242adb42bfb0fc41e54497dfc8", //DSM
                "6ed3d2e495db4e859a73d2a32ce3d576", //HEDEM
                "d653b18bc941458491e06e657e10f393", //Intensity
                "a9ab25b1c7204764b2fabad6fc7a4635", //IR
                "e6bab92ebc524072a3305ec8f128e8f8", //Soil
                "2f9acebfb8db4e10bb6dddab8d3239c7", //ClosedDepressions
            ];

            const webmaps = webmapids.map((webmapid) => {
                return new WebMap({
                    portalItem: {
                        // autocasts as new PortalItem()
                        id: webmapid,
                    }
                });
            });

            // add image services used in the swipe map
            const imagery2024 = new ImageryLayer({
                url: "https://gis.willcountyillinois.com/portal/sharing/servers/871887c09c234de98109ed4033f842ad/rest/services/Orthoimagery/Orthos_2024_3IN/ImageServer",

            });
            webmaps[0].add(imagery2024);

            /************************************************************
             * Initialize the View with the first WebMap
             ************************************************************/
            const view = new MapView({
                map: webmaps[0],
                container: "viewDiv",
                constraints: {
                    maxScale: 500,
                    minScale: 300000,
                }
            });
            console.log('construct the view')
            //use promise function.when to add the imagery layer after the webmap group layer, hence, rendering it over the group layers
            view.when(function () {
                console.log('show the view')
                webmaps[0].add(imagery2024);
            });

            // create a new Swipe widget
            let swipe = new Swipe({

                leadingLayers: [imagery2024],
                // trailingLayers: [imagery2024],
                position: 45, // set position of widget to 35%
                dragLabel: "drag left or right",
                view: view,
            });
            // add the widget to the view
            view.ui.add(swipe);


            /************************************************************
            * On a button click, change the map of the View
            ************************************************************/
            document.querySelector(".btns").addEventListener("click", (event) => {
                const id = event.target.getAttribute("data-id");
                if (id) {
                    const webmap = webmaps[id];
                    view.map = webmap;
                    webmap.add(imagery2024);
                    // promise
                    webmap.when(function () {
                        webmap.add(imagery2024);
                        console.log("View loaded");
                    }, function (error) {
                    });

                    const nodes = document.querySelectorAll(".btn-switch");
                    for (let idx = 0; idx < nodes.length; idx++) {
                        const node = nodes[idx];
                        const mapIndex = node.getAttribute("data-id");
                        if (mapIndex === id) {
                            node.classList.add("active-map");
                        } else {
                            node.classList.remove("active-map");
                        }
                    }
                }
            });
});
</script>
0 Kudos
1 Solution

Accepted Solutions
Edvinas_S
Esri Contributor

Add the basemap as a new layer and do the same things to it as labelsTileLayer. In my sample I used a TileLayer with a link to esris default satellite basemap. You will probably use ImageryLayer.

I updated the same codepen: https://codepen.io/edvinasHB/pen/VYYYVrV

View solution in original post

0 Kudos
3 Replies
Edvinas_S
Esri Contributor

2 problems. After you change map itemId, your label layer is removed and you don't add it back. Your old code used to add that layer again.

When you fix that, second problem comes up. Changing map itemId messes up the label layer for some reason. To fix that, remove label layer from the map before changing the itemId.

Here is a working demo: https://codepen.io/edvinasHB/pen/VYYYVrV See numbered comments (1, 2, 3) to see what was changed

JaredPilbeam2
MVP Alum

Thanks @Edvinas_S for the help! 

That got me real close. When I click a button I expect to see the webmap on the trailing side of the swipe only. The leading side of the swipe should include the street labels and the satellite basemap on start-up, only and always. In your Codepen the webmap is on both sides after clicking a button. 

I believe using a promise function .when to add the satellite basemap after the webmapids, hence, rendering it over them will work if I can figure out how/where to implement it. My old code did this with an imagery layer.

0 Kudos
Edvinas_S
Esri Contributor

Add the basemap as a new layer and do the same things to it as labelsTileLayer. In my sample I used a TileLayer with a link to esris default satellite basemap. You will probably use ImageryLayer.

I updated the same codepen: https://codepen.io/edvinasHB/pen/VYYYVrV

0 Kudos