How do I select which basemap is selected in the gallery AT STARTUP?

6615
12
07-24-2015 10:19 AM
ericliprandi
New Contributor III

Here is our situation:

  • users can have a custom list of basemaps
  • we use the BasemapGallery to allow them to select their basemap
  • we persist the basemap id in a cookie to load that same basemap the next time they visit their app

At this point what is the official way to load the Basemap gallery against a map with a specific basemap selected?

The only 2 lines of code involved in setting up the gallery with the map are:

var gallery = new BasemapGallery( options );
gallery.startup();

As far as we can tell, there is nothing in the options that allows this. We don't see a selected property on the Basemap.

So far, our only option is to let it load the gallery, using the first basemap, then, as soon as it's loaded, call select(id) on the gallery. But as you can guess, the experience is horrible at best. The map loads first with a basemap and within a second or two switches to the one the user really wanted.

Tags (1)
0 Kudos
12 Replies
JeffJacobson
Occasional Contributor III

Here is a JSFiddle sample that demonstrates how to do this. I'll paste the same code below in case something happens to the JSFiddle.

<div id="map"></div>
<div class="layer-list">
    <ul>
        <li>
            <input id="countyBoundariesCheckbox" type="checkbox" data-layer-id="County Boundaries" />
            <label for="countyBoundariesCheckbox">County Boundaries</label>
        </li>
    </ul>
</div>
<div id="basemapGalleryContainer">
    <div id="basemapGallery"></div>
</div>

html, body {
    height: 100%;
    overflow-y: hidden;
}
html, body, #map, .map.container {
    padding:0;
    margin:0;
}
#map, .map.container {
    height: calc(100% - 10em);
}
#basemapGalleryContainer {
    height: 10em;
    overflow-y: scroll;
}
.layer-list {
    position: absolute;
    right: 0;
    top: 0;
    z-index: 1;
    padding: 0.5em;
    background-color: RGBA(255, 255, 255, 0.75)
}

require([
    "esri/config",
    "esri/map", 
    "esri/geometry/Extent", 
    "esri/dijit/BasemapGallery",
    "esri/layers/ArcGISTiledMapServiceLayer"
], function (esriConfig, Map, Extent, BasemapGallery, ArcGISTiledMapServiceLayer) {
    "use strict";
    var map, basemapGallery, scalebar, wsdotBasemap, wsdotBasemapLayer;
    esriConfig.defaults.io.corsEnabledServers.push("www.wsdot.wa.gov");


    // Create the map, explicitly setting the LOD values.
    map = new Map("map", {
        extent: new Extent({
            "xmin": -14058520.2360666,
            "ymin": 5539437.0343901999,
            "ymax": 6499798.1008670302,
            "xmax": -12822768.6769759,
            "spatialReference": {
                "wkid": 3857
            }
        }),
        lods: [
            {"level": 0,"resolution": 56543.033928,"scale": 591657527.591555}, 
            {"level": 1,"resolution": 78271.5169639999,"scale": 295828763.795777},
            {"level": 2,"resolution": 39135.7584820001,"scale": 147914381.897889},
            {"level": 3,"resolution": 19567.8792409999,"scale": 73957190.948944},
            {"level": 4,"resolution": 9783.93962049996,"scale": 36978595.474472},
            {"level": 5,"resolution": 4891.96981024998,"scale": 18489297.737236},
            {"level": 6,"resolution": 2445.98490512499,"scale": 9244648.868618},
            {"level": 7,"resolution": 1222.99245256249,"scale": 4622324.434309},
            {"level": 8,"resolution": 611.49622628138,"scale": 2311162.217155},
            {"level": 9,"resolution": 305.748113140558,"scale": 1155581.108577},
            {"level": 10,"resolution": 152.874056570411, "scale": 577790.554289}, 
            {"level": 11,"resolution": 76.4370282850732,"scale": 288895.0},
            {"level": 12,"resolution": 38.2185141425366,"scale": 144447.638572},
            {"level": 13,"resolution": 19.1092570712683,"scale": 72223.819286},
            {"level": 14,"resolution": 9.55462853563415,"scale": 36111.909643},
            {"level": 15,"resolution": 4.77731426794937,"scale": 18055.954822},
            {"level": 16,"resolution": 2.38865713397468,"scale": 9027.977411},
            {"level": 17,"resolution": 1.19432856685505,"scale": 4513.988705},
            {"level": 18,"resolution": 0.597164283559817,"scale": 2256.994353},
            {"level": 19,"resolution": 0.298582141647617,"scale": 1128.497176}
        ],
        minZoom: 7,
        maxZoom: 19
    });


    // Create the basemap gallery using basemaps defined in a WSDOT group.
    basemapGallery = new BasemapGallery({
        map: map,
        basemapsGroup: {
            id: "085a9cb0bb664d29bf62b731ccc4aa64"
        },
        basemapIds: map.layerIds
    }, "basemapGallery");
    basemapGallery.startup();
    
    // When the basemap gallery loads, select the first basemap with 
    // the title "Imagery Hybrid". (There should be only one, but that's what
    // the code is doing.)
    basemapGallery.on("load", function() {
        var basemap, basemaps = basemapGallery.basemaps.filter(function(basemap){
            return basemap.title === "Imagery Hybrid";
        });
        if (basemaps && basemaps.length > 0) {
            basemap = basemaps[0];
            basemapGallery.select(basemap.id);
        }
    });
    
    map.on("load", function(){
        var toggleLayer = function() {
            var layer = map.getLayer(this.dataset.layerId);
            if (this.checked) {
                layer.show();
            } else {
                layer.hide();
            }
        };
        var checkbox = document.getElementById("countyBoundariesCheckbox");
        map.addLayer(new ArcGISTiledMapServiceLayer("http://www.wsdot.wa.gov/geosvcs/ArcGIS/rest/services/Shared/CountyBoundaries/MapServer", {
            id: "County Boundaries",
            visible: checkbox.checked
        }));    
        

        checkbox.onclick = toggleLayer;
    });    
});
RobertScheitlin__GISP
MVP Emeritus

Jeff,

   Your way is a lot easier.

0 Kudos
ericliprandi
New Contributor III

Jeff,

Thanks a lot for the long example. I hope you had that code already on hand... This is much appreciated. I definitely like the idea of the basemaps group defined in AGOL or Portal. And if we were to build custom apps, that would definitely be the way I would go. Unfortunately, we are an ISV and based on the number of combinations possible to build a basemap gallery, we had to settle on a compromise.

Just like we did 3 years ago when we built v1 of this app, we built our own gallery. It was not complicated and in the end gave us all the functionality we wanted. When the use of Portal and AGOL becomes more widely spread with our customers, we will likely go down the basemaps group path. Just too much legacy customers at this point.

Regards,

Eric.

0 Kudos