Cesium to Visualise NYC Carbon Footprint


Cesiumjs is a wonderfully simple and extensible library to work with. It is, in simplest terms, a 3D globe with imagery providers which can be used for nearly anything under the sun. I recently discovered that NYC publishes a lot of its data online, and I was dying to play around with that data to see what I could gather from the city data. I also had Cesium on hand, and open city data coupled with a versatile visualisation tool is a killer combination so I gave myself a few hours last Saturday afternoon to see what I could do.

I started with the carbon emissions data from NYC. Since the NYC data api provided me with building names instead of location coordinates, I had to do a reverse lookup with google to fetch the WGS84 lat,lng coordinates for each datapoint.

After downloading the data and doing the reverse geolocation lookup, I decided to strip it of all information except what was needed. I often do this since it removes redundant information and allows me to focus and debug code without distractions. My data after processing looked like this:

{  
  "loc":{  
    "lat":40.697487,
    "lng":-73.91223699999999
  },
  "co2":"11.90"
},
{  
  "loc":{  
     "lat":40.713645,
     "lng":-73.947993
  },
  "co2":"15.10"
},

This was fairly clean and usable. I then quickly looked through the Cesium documentation for something which would be suitable to show as the equivalent of an emissions footprint. I decided to use polylines with a larger width, whose lengths would correspond with the co2 value for each building. I expected to see a nice set of lines clustered around Manhattan where the tall buildings were.

First setting up Cesium:

var canvas3d = document.getElementById('map');
// only showing the very basic globe; refer to docs for details
viewer = new Cesium.Viewer(canvas3d, {
  animation: false,
  baseLayerPicker: false,
  fullscreenButton: false,
  geocoder: false,
  homeButton: false,
  infoBox: false,
  sceneModePicker: false,
  selectionIndicator: false,
  timeline: false,
  navigationHelpButton: false,
});
scene = viewer.scene;
canvas = viewer.canvas;
camera = viewer.camera;

var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : '//assets.agi.com/stk-terrain/world'
});
viewer.terrainProvider = terrainProvider;

Next I added those lines on the globe on top of NYC:

//locations is the set of data as shown above
function addLines() {
	for (var i=1;i<locations.length;i++) {
	    var surfacepos = new Cesium.Cartesian3.fromDegrees(locations[i].loc.lng, locations[i].loc.lat, 0);
	    var aerialpos = new Cesium.Cartesian3.fromDegrees(locations[i].loc.lng, locations[i].loc.lat, locations[i].co2*10);
	    var greenBox = viewer.entities.add({
	        polyline : {
	            show: true,
	            positions : [surfacepos, aerialpos],
	            shape :[new Cesium.Cartesian2(-20, -20),
	                    new Cesium.Cartesian2(20, -20),
	                    new Cesium.Cartesian2(20, 20),
	                    new Cesium.Cartesian2(-20, 20)],
	            cornerType : Cesium.CornerType.BEVELED,
	            material : Cesium.Color.ORANGE.withAlpha(0.6),
	            outline : true,
	            outlineColor : Cesium.Color.BLACK,
	            width: 10
	        }
	    });
	}
}

The code goes through the locations dataset, and for each point, it draws a polyline with length co2*10 to make it more visible at the respective coordinate point.

This made for some already seriously pro-looking visuals. However, as one last feature, I added:

camera.flyTo({
	//nyc coordinates
    destination : Cesium.Cartesian3.fromDegrees(-73.959082,40.915096, 2000),
    orientation : {
        heading : Cesium.Math.toRadians(150),
        pitch : Cesium.Math.toRadians(-10.0),
        roll : 0.0
    }
});

rotate();

function rotate() {
    camera.rotate(Cesium.Cartesian3.fromDegrees(-73.951529,40.790447), 0.001);
    window.requestAnimationFrame(rotate);
}

This created a cinematic feel as the camera flew around the carbon emissions data.

NYC Carbon Footprint

Carbon Emissions Visualised!

Looks pretty cool! Check out the live demo here.

More Reading
comments powered by Disqus