Using US Census data with Bing Maps

While creating the code samples for the Bing Maps V8 web control, we wanted to make the samples more realistic and use real data. As such, many of the Bing Maps V8 interactive code samples use data from a number of sources such as earthquake data from the USGS, satellite imagery of hurricanes from NASA, weather radar data from Iowa State University, and 2010 US Census data from the US Census Bureau.

To make the census data easy to integrate with Bing Maps applications, a subset of the data was uploaded into the Bing Spatial Data Services. This data has been exposed through 4 different data sources, each containing a census data based on a different type of geographical region; states, counties, ZCTA5 (Zip code tabulation area), and the 111th Congressional districts. The Bing Maps team has now made these data sources publicly available in the Bing Spatial Data Services so that you can easily use them in your application. Documentation on these data sources can be found here.

Creating a Census Choropleth map in Bing Maps V8

The following code sample shows how to create a Choropleth map (color coded boundary map) based on the population by state. This code sample uses the Bing Spatial Data Services module that is built into Bing Maps V8 to query the state level 2010 US Census data. This code sample also creates a legend with a gradient scalebar, which is used to color code the boundary data based on its relative population.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script type='text/javascript'
            src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
            async defer></script>
    <script type='text/javascript'>
    var sdsDataSourceUrl = 'https://spatial.virtualearth.net/REST/v1/data/755aa60032b24cb1bfb54e8a6d59c229/USCensus2010_States/States';

    var map,
        maxPopulation = 10000000,
        heatGradientData;

    function GetMap() {
        map = new Microsoft.Maps.Map('#myMap', {
            credentials: 'Your Bing Maps Key',
            center: new Microsoft.Maps.Location(53.32, -110.29),
            zoom: 3
        });

        //Create a legend.
        createLegend(maxPopulation);

        //Load the Bing Spatial Data Services module.
        Microsoft.Maps.loadModule('Microsoft.Maps.SpatialDataService', function () {

            var worldBounds = Microsoft.Maps.LocationRect.fromEdges(90, -180, -90, 180);

            //Get all states by doing an intersection test against a bounding box of the world and have up to 52 results returned.
            var queryOptions = {
                queryUrl: sdsDataSourceUrl,
                spatialFilter: {
                    spatialFilterType: 'intersects',
                    intersects: worldBounds
                },
                top: 52
            };

            Microsoft.Maps.SpatialDataService.QueryAPIManager.search(queryOptions, map, function (data) {
                //Loop through results and set the fill color of the polygons based on the population property.
                for (var i = 0; i < data.length; i++) {
                    data[i].setOptions({
                        fillColor: getLegendColor(data[i].metadata.Population, maxPopulation)
                    });

                    //Add a click event to each polygon and display metadata.
                    Microsoft.Maps.Events.addHandler(data[i], 'click', function (e) {
                        alert(e.target.metadata.Name + '\r\nPopulation: ' + e.target.metadata.Population);
                    });
                }

                //Add results to the map.
                map.entities.push(data);
            });
        });
    }

    function createLegend(maxValue) {
        var canvas = document.getElementById('legendCanvas');
        var ctx = canvas.getContext('2d');

        //Create a linear gradient for the legend.
        var colorGradient = {
            "0.00": 'rgba(0,255,0,255)',    // Green
            "0.50": 'rgba(255,255,0,255)',  // Yellow
            "1.00": 'rgba(255,0,0,255)'     // Red
        };

        var grd = ctx.createLinearGradient(0, 0, 256, 0);
        for (var c in colorGradient) {
            grd.addColorStop(c, colorGradient[c]);
        }
        ctx.fillStyle = grd;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        //Store the pixel information from the legend.
        heatGradientData = ctx.getImageData(0, 0, canvas.width, 1);
    }

    function getLegendColor(value, maxValue) {
        value = (value > maxValue) ? maxValue : value;

        //Calculate the pixel data index from the ratio of value/maxValue.
        var idx = Math.round((value / maxValue) * 256) * 4 - 4;

        if (idx < 0) {
            idx = 0;
        }

        //Create an RGBA color from the pixel data at the calculated index.
        return 'rgba('+ heatGradientData.data[idx]+ ',' +
            heatGradientData.data[idx + 1] + ',' +
            heatGradientData.data[idx + 2] + ',' + '0.5)';
    }
    </script>
    <style>
        .mapContainer {
            position: relative;
            width: 800px;
            height: 600px;
        }

        #map {
            position: relative;
            width: 800px;
            height: 600px;
        }

        .legend {
            position: absolute;
            top: 5px;
            left: 5px;
            width: 256px;
            height: 35px;
            font-family: Arial;
            font-size: 12px;
            background-color: rgba(255, 255, 255, 0.8);
            border-radius: 5px;
            padding: 5px;
        }

        #legendCanvas {
            width: 256px;
            height: 15px;
        }

        .legend-max {
            float: right;
        }
    </style>
</head>
<body>
    <div class="mapContainer">
        <div id="myMap"></div>

        <div class="legend">
            <canvas id="legendCanvas"></canvas>
            <span class="legend-min">0</span>
            <span class="legend-max">10,000,000</span>
        </div>
    </div>
</body>
</html>

Running this code will display a map of the USA with color coded US states based on population. A legend for the colors is overlaid on top the map as well. If you click on any of the states, a notification will appear which specifies which state was clicked and its population.

SDS Choropleth Map Example

Try it now

Access additional US Census Data

The 2010 US Census data sources that are made available in the Bing Spatial Data Sources contain a subset of the data collected by the US Census, primarily population data. The US Census Bureau captures a lot of additional data which has not been included in the newly released data sources in the Bing Spatial Data Services. If you would like to access this data, there are a few options. One option is to download some of the existing geographic data sets from the US Census and upload them into the Bing Spatial Data Service. You can easily upload ESRI Shapefiles and KML files into the Bing Spatial Data Services to create a data source. Alternatively, you can upload this data into a spatial database such as SQL Azure and then expose the data through a custom web service.

Partner Solutions

Don’t want to develop a custom application yourself, take a look at one of these solutions.

Microsoft Power BI

Power BI along with the mapping functionality available in Excel make it easy to visualize data on Bing Maps. Here are a few useful blog posts on how to do this:

CensusViewer by MoonShadow Mobile

CensusViewer is an online application built by Moonshadow Mobile. This application gives you access to the 2010 and 2000 Census "Summary File 1" data from the U.S. Census Bureau as well as the selected American Community Survey (ACS) data and extensive data including registered voters and frequently updated commercial data sources. It is an excellent online tool for demographic analysis of the U.S. population. With CensusViewer you can navigate the census data from within the familiar Bing Maps interface coupled with Moonshadow’s cutting-edge database technology, to provide an intuitive platform for accessing and analyzing the data. Now, there are a couple different versions which give you access to different levels of data. If you want to try it out yourself, you’re in luck because there’s a free version. Here is a heat map created using this tool of the US population that is at or below the poverty level.

Moon Shadow Mobile Census App

EasyTerritory.com

EasyTerritory is a leading map-based solution for territory management and geospatial business intelligence for Microsoft Dynamics CRM or SQL Server. Powered by Bing Maps for Enterprise, EasyTerritory allows users to geographically build and manage territories and get business-intel for leads, opportunities, contacts, accounts or any custom Dynamics CRM entity. EasyTerritory can optionally be deployed without Dynamics CRM using only SQL Server 2008, 2012, 2014, or SQL Azure. Features of EasyTerritory include, territory management, geospatial BI, US Census data sets, route planning and full legacy GIS integration. Out-of-the-box, this solution includes worldwide political boundary data as well as demographic for the US, Canada and parts of Europe. The EasyTerritory solution is available as an online service or can be deployed on-premises.

Bing Maps Easy Territory