Adding Image with Labels to BasemapGallery

4692
12
Jump to solution
01-06-2012 05:48 AM
MarkHoover
Occasional Contributor II
The constant shuffling of order and maps present in the Basemap Gallery is quite annoying.  I wish a basic Basemap Gallery was set, and then if we users decide we want to include new Basemaps like the National Geographic one, we could do so with the corresponding code:

            //create Terrain Basemap for Gallery             var terrainLayer = new esri.dijit.BasemapLayer({                 url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer"             });             var terrainBasemap = new esri.dijit.Basemap({                 layers: [terrainLayer],                 title: 'Terrain',                 thumbnailUrl: 'http://www.arcgis.com/sharing/content/items/11742666e55b45b8a508751532d0c1ea/info/thumbnail/Terrain_ne_usa.png'             });             basemapGallery.add(terrainBasemap);


Anyway, that's not my issue right now.  Because of the reordering and such, I am in the process of rearranging everything into the order that we had previously, with the Bing maps in the first row, Esri Imagery and Road in the next row and so on.  My process for doing so is removing all the layers that are out of order, and then adding them back to the Gallery in the order I'd like.

My question is, how do I add the Imagery with Labels Basemap back into the Gallery.  This Basemap relies on two services, the URLs of which are:

http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer
http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServe...

The url parameter for creating a new Basemap as shown above only accepts one URL, however.

Can I accomplish what I'm intending here?
0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor
Mark

Perhaps I don't quite understand what you are trying to do but it sounds like you want to have an item in the basemap gallery that when selected will draw one of the arcgis.com basemaps along with the labels.

If so you can modify your code below to define two basemap layers one for the World Terrain basemap and one for the labels. Then you'll create the Basemap and provide both new basemap layers as an array to the layers option:

             //create Terrain Basemap for Gallery             var terrainLayer = new esri.dijit.BasemapLayer({                 url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer"             });             var labelsLayer = new esri.dijit.BasemapLayer({                url: 'url to labels service',                isReference:true             });             var terrainBasemap = new esri.dijit.Basemap({                 layers: [terrainLayer,labelsLayer],                 title: 'Terrain with Labels',                 thumbnailUrl: 'http://www.arcgis.com/sharing/content/items/11742666e55b45b8a508751532d0c1ea/info/thumbnail/Terrain_ne_usa.png'             });             basemapGallery.add(terrainBasemap);

View solution in original post

12 Replies
MarkHoover
Occasional Contributor II
For those interested, here is my workaround:

Listen for the BasemapGalleryChange event and use the following function:

handleBasemapChange: function () {
        var basemap = Ext.getCmp('CTSApp').basemapGallery.getSelected();
        if (basemap.title == 'Light Gray with Labels') {
            var referenceLayer = new esri.layers.ArcGISTiledMapServiceLayer('http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer');
            map.referenceLayer = referenceLayer;
            map.addLayer(referenceLayer, 1);
        }
        else if (basemap.title == 'Imagery with Labels') {
            var referenceLayer = new esri.layers.ArcGISTiledMapServiceLayer('http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer');
            map.referenceLayer = referenceLayer;
            map.addLayer(referenceLayer, 1);
        }
        else {
            if (map.referenceLayer) {
                map.removeLayer(map.referenceLayer);
            }
        }
    }
0 Kudos
KellyHutchins
Esri Frequent Contributor
Mark,

Another option might be to create a group in ArcGIS.com that contains the basemaps you want to display in the gallery. You can then specify a basemap group (added at 2.6) when creating the basemap gallery.


 var basemapGallery = new esri.dijit.BasemapGallery({
   showArcGISBasemaps: false,
   basemapsGroup:{owner:"esri",title:"Community Basemaps"},
   map: map
 }, dojo.create('div'));
0 Kudos
NianweiLiu
Occasional Contributor II
If you want your own order, it's better to just use manual mode with fixed order. To deal with reference layers, use multiple URL and set the reference=true flag. Using your workaround is kind of risky. Since Esri may change the default gallery, you may end up different type of reference layer, or your hard-coded basemap just completely gone.
Use a user group as Kelly suggested may help in some extent, but unlikely for Esri's basemaps. The gallery order is decided by a attributed called "name" (as of v2.6), which is not available for user editing. The value is null for non-Esri basemaps, which translated to "undeterministic". Esri's basemap have pre-set "names" via other methods (likely via non-public API). If you see the default gallery order changed, chances are those "name" attributes were changed in the map item, then the order will change in your user group as well.
0 Kudos
MarkHoover
Occasional Contributor II
If you want your own order, it's better to just use manual mode with fixed order. To deal with reference layers, use multiple URL and set the reference=true flag. Using your workaround is kind of risky. Since Esri may change the default gallery, you may end up different type of reference layer, or your hard-coded basemap just completely gone.
Use a user group as Kelly suggested may help in some extent, but unlikely for Esri's basemaps. The gallery order is decided by a attributed called "name" (as of v2.6), which is not available for user editing. The value is null for non-Esri basemaps, which translated to "undeterministic". Esri's basemap have pre-set "names" via other methods (likely via non-public API). If you see the default gallery order changed, chances are those "name" attributes were changed in the map item, then the order will change in your user group as well.


Some thoughts:

Where is this Manual Mode property you're referring to?  I don't see it on the Basemap, BasemapLayer, or BasemapGallery classes.

How (and where) do you use multiple URLs?  The BasemapLayer's url parameter is expecting a string, not an array or something.

I actually don't need the "reference layer" behavior of drawing on top of all of my layers.  I simply need the labels (which come from a different Map Service for Imagery with Labels, Terrain with Labels, and Light Gray with labels, for example) to also turn on when a user selects one of those Basemaps from my Gallery.  Because they are two separate services and must both be added to the map, that workaround is the best solution I currently have.

Are you referring to hard-coding the Basemap URLs?  That's not a big concern for us, we're assuming the Esri basemap resources to be pretty reliable.  Should they ever change, it would be easy to make the swap.

Also, I'd rather handle the maintenance of this list within the code, rather than go out to Arcgis.com and create a group, should I ever need to change it.  Don't really want to rely on another resource for something I can accomplish in code.
0 Kudos
KellyHutchins
Esri Frequent Contributor
Mark

Perhaps I don't quite understand what you are trying to do but it sounds like you want to have an item in the basemap gallery that when selected will draw one of the arcgis.com basemaps along with the labels.

If so you can modify your code below to define two basemap layers one for the World Terrain basemap and one for the labels. Then you'll create the Basemap and provide both new basemap layers as an array to the layers option:

             //create Terrain Basemap for Gallery             var terrainLayer = new esri.dijit.BasemapLayer({                 url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer"             });             var labelsLayer = new esri.dijit.BasemapLayer({                url: 'url to labels service',                isReference:true             });             var terrainBasemap = new esri.dijit.Basemap({                 layers: [terrainLayer,labelsLayer],                 title: 'Terrain with Labels',                 thumbnailUrl: 'http://www.arcgis.com/sharing/content/items/11742666e55b45b8a508751532d0c1ea/info/thumbnail/Terrain_ne_usa.png'             });             basemapGallery.add(terrainBasemap);
NianweiLiu
Occasional Contributor II

Where is this Manual Mode property you're referring to?  I don't see it on the Basemap, BasemapLayer, or BasemapGallery classes.

There is no "manual mode" per se, I was referring to the manual sample for the API, in which you create an array and add basemaps to it in code.

How (and where) do you use multiple URLs?  The BasemapLayer's url parameter is expecting a string, not an array or something.

Basemap accepts multiple BasemapLayers.

Because they are two separate services and must both be added to the map, that workaround is the best solution I currently have.

you can mix-and-match different services(BasemapLayer) to create a "Basemap". If you want have label layer turned on/off inside the gallery, check out this sample: http://gmaps-utility-gis.googlecode.com/svn/tags/agsjs/1.07/examples/gmapsgallery.html

Also, I'd rather handle the maintenance of this list within the code, rather than go out to Arcgis.com and create a group, should I ever need to change it.  Don't really want to rely on another resource for something I can accomplish in code.

I am sure many people will disagree, but do what you feel most comfortable with.
0 Kudos
MarkHoover
Occasional Contributor II
Ah ha!  Kelly and Nianwei, you've both uncovered what it is I was after; I had missed the obvious fact that a "Basemap" can consist of multiple "BasemapLayers".  That will render my workaround obsolete, thank you both.

I believe I already am manually adding Basemaps to the Gallery, as you described.

Lastly, perhaps many people will disagree due to the ease of using arcgis.com vs. coding, but this only makes sense to us from a maintenance standpoint.  There's plenty of entry points for maintaining this application as is (the code itself, SQL Server, ArcMap to design/tweak the services, etc.) that adding another component, especially one that can be and maybe even "should" be handled in code, is adding another needless layer of maintenace.  If it works for others, wonderful.
0 Kudos
ChristopherPollard
Occasional Contributor
Nianwei....Thank you again for all great examples. I am using your gmaplayer example (1.4) with the buttons to switch basemaps. I have maunally changed the order and which basemap layers to show. I am having an issues getting the ESRI Grey Canvas and Canvas Reference to display at the same time.
I triied to include both map ids but it only shows the 1st one....

     <button dojoType="dijit.form.Button" onClick="changeMap([esriGreyRef, esriGrey]);"> ESRI Grey Map </button>

The new gmapsggalley (1.7)  example is great but how do I go about building a manual version of the gallery to only show the 3 Google Basemaps, ESRI Street,ESRI Topo and ESRI Grey with Reference ?

My BETA/working example with can be found here:
http://www.dvrpc.org/webmaps/CMP/index.html

I'm using your build 1.4 version...

Thanks,
Chris
0 Kudos
NianweiLiu
Occasional Contributor II
Chris,

The new gmapsggalley (1.7)  example is great but how do I go about building a manual version of the gallery to only show the 3 Google Basemaps, ESRI Street,ESRI Topo and ESRI Grey with Reference ?


Something like that:
              var basemaps = [];
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
                })],
                title: "Esri Street",
                thumbnailUrl: "http://www.arcgis.com/sharing/content/items/b165c3df453e4be6b5ac4fdb241effbe/info/thumbnail/delorme_base_map.jpg"
              }));
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"
                })],
                title: "Esri Topo"
              }));
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  url: "http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer"
                 }), new esri.dijit.BasemapLayer({
                  url: "http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer",
                 isReference:true
               })],
                title: "Esri Grey with Label"
              }));
              
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  type: 'GoogleMapsRoad'
                })],
                title: "Google Maps",
                thumbnailUrl: dojo.moduleUrl("agsjs.dijit", "images/googleroad.png")
              }));
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  type: 'GoogleMapsSatellite'
                })],
                title: "Google Satellite",
                thumbnailUrl: dojo.moduleUrl("agsjs.dijit", "images/googlesatellite.png")
              }));
              basemaps.push(new esri.dijit.Basemap({
                layers: [new esri.dijit.BasemapLayer({
                  type: 'GoogleMapsHybrid'
                })],
                title: "Google Hybrid",
                thumbnailUrl: dojo.moduleUrl("agsjs.dijit", "images/googlehybrid.png")
              }));
              
              var basemapGallery = new esri.dijit.BasemapGallery({
                showArcGISBasemaps: false,
                basemaps: basemaps,
                googleMapsApi: {
                  v: 3.6
                },
                map: map
              }, "basemapGallery");
              basemapGallery.startup();

0 Kudos