Mapping county, city and venue data using ArcGIS + ESRI

This single-page web app shows you how to publish a map using ArcGIS for mapping, ESRI for publishable data, and a JSON file for custom data. I took it one step further and even drew out vector graphics using the DOJO graphics engine.

Example


The hardest part of this demo was using the Dojo framework. Yes, it's still Javascript, but it's radically different from jQuery. If it weren't for ArcGIS, I might not have gone through the effort.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
        <title></title>
        <link rel="stylesheet" href="http://js.arcgis.com/3.6/js/dojo/dijit/themes/tundra/tundra.css">
        <link rel="stylesheet" href="http://js.arcgis.com/3.6/js/esri/css/esri.css">
        <style>
            html, body, #mapDiv {
                height: 100%;
                width: 100%;
                margin: 0;
                padding: 0;
            }
        </style>
        <!-- Javascript -->
        <script src="http://js.arcgis.com/3.6/">
        </script>
        <script type="text/javascript" charset="utf-8">
            //https://developers.arcgis.com/en/javascript/jsapi/graphic-amd.html
            var map;
            var Data = {
                ESRI: {
                    CENSUS: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3",
                    STATES_CITIES_RIVERS: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0/"
                }
            }
            var params = {
                coords: {
                    lng: -118.049,
                    lat: 34
                },
                zoom: 6,
                markerURL: "https://s3.amazonaws.com/com.cartodb.users-assets.production/production/jonmrich/assets/20150203194453red_pin.png",
                state: "California"
            };
            
            var libs = ["dojo/parser", "dojo/on", "dojo/aspect", "dojo/dom", "dojo/io/script", "dojo/_base/array", "dojo/json", "esri/map", "esri/geometry/Point", "esri/symbols/PictureMarkerSymbol", "esri/graphic", "esri/layers/GraphicsLayer", "dojo/domReady!"];
            
            require(libs, function(parser, on, aspect, dom, script, arrayUtil, JSON, Map, Point, PictureMarkerSymbol, Graphic, GraphicsLayer, domConstruct){
            
                map = new Map("mapDiv", {
                    center: [params.coords.lng, params.coords.lat],
                    zoom: params.zoom,
                    //"satellite", "hybrid", "topo", "gray", "ocean", "osm", "national_geographic"
                    basemap: "topo"
                });
                
                
                //On Layers Add Event Handler
                map.on("layers-add-result", onLayerAddResult);
                function onLayerAddResult(res){
                    console.log("onLayerAddResult", res);
                }
                
                //Plot multiple layers on a map
                //https://developers.arcgis.com/en/javascript/jssamples/graphics_multiple_layers.html
                aspect.after(map, "onLoad", queryCounties);
                aspect.after(map, "onLoad", queryCities);
                
                on(map, "load", queryVenues);
                on(map, "load", plotItem);
                
                function plotItem(){
                    //A. CREATE GEO POINT
                    var point = new esri.geometry.Point(params.coords.lng, params.coords.lat);
                    point = esri.geometry.geographicToWebMercator(point);
                    //B. CREATE SYMBOL
                    var symbol = new esri.symbol.PictureMarkerSymbol(params.markerURL, 32, 32);
                    //C. CREATE GRAPHIC, INSERT THE SYMBOL AND POINT
                    var graphic = new esri.Graphic(point, symbol);
                    //D. CREATE LAYER
                    var layer = new esri.layers.GraphicsLayer();
                    //E. ADD GRAPHIC TO LAYER
                    layer.add(graphic);
                    //F. CREATE AN EVENT LISTENER + HANDLER
                    aspect.after(layer, "onclick", onPictureMarkerClick);
                    function onPictureMarkerClick(){
                        console.log("onPictureMarkerClick:");
                    }
                    //G. ADD LAYER TO MAP
                    map.addLayer(layer);
                }
                
                
                /**************************************
                 * Venue Data
                 */
                function queryVenues(){
                    script.get({
                        // The URL to get JSON from Twitter
                        url: "http://main-worldvenues.rhcloud.com/feed",
                        callbackParamName: "callback",
                        handleAs: "json",
                        content: {},
                        load: function(data){
                            var items = JSON.parse(data, true);
                            
                            var symbol = new esri.symbol.SimpleMarkerSymbol();
                            symbol.setColor(new dojo.Color([0, 0, 255, 0.8]));
                            
                            var graphicsLayer = new esri.layers.GraphicsLayer();
                            //Re-order the layers
                            //map.reorderLayer(graphicsLayer, 1);
                            
                            //Add each item to the Graphics Layer
                            dojo.forEach(items.rows, function(item){
                                //console.log( item.value );
                                var item = item.value;
                                var lat = item.latitude;
                                var lng = item.longitude;
                                var point = new esri.geometry.Point(lng, lat);
                                var attr = item;
                                //https://developers.arcgis.com/en/javascript/jsapi/infotemplate.html
                                var infoTemplate = new esri.InfoTemplate("Venue", "${*}");
                                var g = new esri.Graphic(point, symbol, attr, infoTemplate);
                                
                                graphicsLayer.add(g);
                            });
                            //Add Graphics Layer to Map
                            map.addLayer(graphicsLayer);
                        },
                        error: function(err){
                            console.log("Error!", err);
                        }
                    });
                }
                
                /*****************************************
                 * Single Data Point
                 */
                function plotProject(lat, lng){
                    var point = new esri.geometry.Point(lng, lat);
                    
                    var symbol = new esri.symbol.SimpleMarkerSymbol();
                    symbol.setColor(new dojo.Color([0, 0, 255]));
                    
                    var attr = {};
                    var infoTemplate = new esri.InfoTemplate("Special Marker", "${*}");
                    var graphic = new esri.Graphic(point, symbol, attr, infoTemplate);
                    
                    var graphicsLayer = new esri.layers.GraphicsLayer();
                    graphicsLayer.add(graphic);
                    
                    //Add Graphics Layer to Map
                    map.addLayer(graphicsLayer);
                    //map.reorderLayer(graphicsLayer, 2);
                
                    //We're using graphicLayer instead of raw Symbol on a map
                    //map.graphics.add(graphic);
                }
                
                /**************************************
                 * County Data
                 */
                function queryCounties(){
                    var param = params.state;
                    var countyQueryTask = new esri.tasks.QueryTask(Data.ESRI.CENSUS);
                    
                    var countyQuery = new esri.tasks.Query();
                    countyQuery.outFields = ["*"];
                    countyQuery.returnGeometry = true;
                    countyQuery.outSpatialReference = map.spatialReference;
                    countyQuery.where = "STATE_NAME = '" + param + "'";
                    countyQueryTask.execute(countyQuery, addCountyFeatureSetToMap);
                }
                
                function addCountyFeatureSetToMap(featureSet){
                    var symbol = new esri.symbol.SimpleFillSymbol();
                    symbol.setColor(new dojo.Color([100, 100, 100, 0.1]));
                    
                    //Create graphics layer for counties
                    var graphicsLayer = new esri.layers.GraphicsLayer();
                    graphicsLayer.setInfoTemplate(new esri.InfoTemplate("${NAME}", "${*}"));
                    
                    map.addLayer(graphicsLayer);
                    //map.reorderLayer(graphicsLayer, 2);
                    
                    //Add counties to the graphics layer
                    dojo.forEach(featureSet.features, function(feature){
                        graphicsLayer.add(feature.setSymbol(symbol));
                    });
                }
                
                /*****************************************
                 * City Data
                 */
                function queryCities(){
                    var param = params.state;
                    //Query all cities in...
                    var cityQueryTask = new esri.tasks.QueryTask(Data.ESRI.STATES_CITIES_RIVERS);
                    var cityQuery = new esri.tasks.Query();
                    cityQuery.outFields = ["*"];
                    cityQuery.returnGeometry = true;
                    cityQuery.outSpatialReference = map.spatialReference;
                    cityQuery.where = "STATE_NAME = '" + param + "'";
                    cityQueryTask.execute(cityQuery, addCityFeatureSetToMap);
                }
                
                function addCityFeatureSetToMap(featureSet){
                    var symbol = new esri.symbol.SimpleMarkerSymbol();
                    symbol.setColor(new dojo.Color([250, 250, 210, 0.3]));
                    
                    //Create graphics layer for cities
                    var graphicsLayer = new esri.layers.GraphicsLayer();
                    graphicsLayer.setInfoTemplate(new esri.InfoTemplate("${CITY_NAME}", "${*}"));
                    
                    map.addLayer(graphicsLayer);
                    map.reorderLayer(graphicsLayer, 1);
                    
                    //Add cities to the graphics layer
                    dojo.forEach(featureSet.features, function(feature){
                        graphicsLayer.add(feature.setSymbol(symbol));
                    });
                }
                
            });
        </script>
    </head>
    <body class="tundra">
    <div id="mapDiv">
    </div>
    </div>
</body>
</html>

Final Thoughts

If you're trying to work with dynamic data and mapping, I highly suggest you look at Google Maps API with jQuery. Here's an example I made which also displays data from Flickr.