geodev-hackerlabs

Smart Mapping

In this lab you will use Smart Mapping components to style neighborhoods by population and see how Smart Mapping can intelligently pick appropriate styles for you.

You will add a basemap picker and legend, and configure the Neighborhood layer popup.

A continuous color ramp renderer will be used, and the color ramp will be automatically selected by Smart Mapping to best suit the underlying basemap.

  1. Click create_starter_map/index.html and copy the contents to a new jsbin.com.

  2. In JSBin > HTML, add the basemap picker and legend div elements:

     <body>
       <div id="mapDiv"></div>
    
       <!-- ADD new div for the basemap picker and legend -->
       <div id="basemapPickerDiv" class="esriBasemapGallery"></div>
       <div id="legendContainer">
         <div id="legendDiv"></div>
       </div>
     </body>
    
  3. At the top of the page, add CSS to the main style tag to configure the basemap picker and legend display:

     <style>
       html,body,#mapDiv {
           padding:0;
           margin:0;
           height:100%;
       }
    
       /* ADD UI styling */
       .esriBasemapGallery {
         background: #fafafa;
         position: absolute;
         top: 10px;
         right: 10px;
         height: 100px;
         overflow-x: auto;
         overflow-y: hidden;
       }
    
       #legendContainer {
         background-color: #fafafa;
         position: absolute;
         right: 10px;
         top: 140px;
         padding: 8px;
       }
    
       .esriBasemapGalleryLabelContainer, #legendContainer {
         font-family: sans-serif;
         font-size: 0.75em;
       }
     </style>
    
  4. Update the require statement and function definition:

     require(["esri/map",
              // ADD modules
              "esri/layers/FeatureLayer",
              "esri/renderers/smartMapping",
              "esri/basemaps",
              "esri/dijit/Basemap",
              "esri/dijit/BasemapGallery",
              "esri/dijit/Legend",
              "esri/InfoTemplate",
             "dojo/domReady!"],
       // ADD aliases
       function(Map,FeatureLayer,smartMapping,
         esriBasemaps,Basemap,BasemapGallery,
         Legend,InfoTemplate) {
         ... 
    
  5. Add a list of basemaps to choose from. Update the map creation to make use of this. We’ll also change the default zoom of the map to 12:

     function(Map,FeatureLayer,smartMapping,esriBasemaps,Basemap,BasemapGallery,Legend,InfoTemplate) {
    
       // ADD a list of basemaps, and track the current one
       var basemapList = ["topo","streets","osm","gray","dark-gray"],
           currentBasemap = basemapList[0];
        
       map = new Map("mapDiv", {
         center: [-122.68, 45.52],
         // UPDATE the zoom level and starting basemap
         zoom: 12,
         basemap: currentBasemap
       });
    
  6. Add a FeatureLayer pointing to the Neighborhoods layer. We’ll also configure the InfoTemplate which defines how the popup will look when you click on the layer in the map. You can see that we’re explicitly asking the feature layer for NAME and TOTPOP_CY attributes for use in the popup:

       // ADD a neighborhoods layer
       var neighborhoodsLayer = new FeatureLayer("http://services.arcgis.com/uCXeTVveQzP4IIcx/arcgis/rest/services/PDX_Neighborhoods_Styled/FeatureServer/0", {outFields: ["NAME","TOTPOP_CY"]});
    
       map.addLayer(neighborhoodsLayer);
    
       neighborhoodsLayer.setInfoTemplate(new InfoTemplate("${NAME}","Population: ${TOTPOP_CY}"));
    
  7. Create a Legend item:

     // ADD a legend widget to the UI
     var legend = new Legend({
       map: map,
       layerInfos: [
         {
           layer: neighborhoodsLayer,
           title: "Population"
         }
       ]
     }, "legendDiv");
    
     legend.startup();
    
  8. Create a basemap gallery:

     // ADD a basemap gallery of just our list of basemaps
     var basemapGallery = new BasemapGallery({
       showArcGISBasemaps: false,
       map: map
     }, "basemapPickerDiv");
    
     for (var i = 0; i < basemapList.length ; i++) {
       var esriBasemap = esriBasemaps[basemapList[i]];
       basemapGallery.add(new Basemap({
         id: basemapList[i],
         layers: esriBasemap.baseMapLayers,
         thumbnailUrl: esriBasemap.thumbnailUrl,
         title: esriBasemap.title
       }));
     }
    
     basemapGallery.startup();
    
  9. Add code to update the SmartMapping renderer and the legend when the map loads and whenever the basemap changes:

     // ADD a function to update the renderer colors and legend
     function SetRenderer() {
       smartMapping.createColorRenderer({
         layer: neighborhoodsLayer,
         field: "TOTPOP_CY",
         basemap: currentBasemap,
         theme: "high-to-low",
         showOthers: false
       }).then(function (colorRenderer) {
         neighborhoodsLayer.setRenderer(colorRenderer.renderer);
         neighborhoodsLayer.redraw();
         legend.refresh();
       });
     };
    
     // ADD code to configure the renderer when the layer first loads
     neighborhoodsLayer.on("load", function() {
       SetRenderer();
     });
    
     // ADD code to configure the renderer when a basemap is selected
     basemapGallery.on("selection-change", function (event){
       currentBasemap = event.target.getSelected().id;
       if (neighborhoodsLayer.loaded) {
         SetRenderer();
       }
     });
    
  10. In JSBin, run the app > Select a basemap in the gallery to see how Smart Mapping changes the styling of the neighborhood layer appropriately for each basemap.

Your app should look something like this:

Bonus