Omitting Greenland Won’t
Fix Your Mercator Map

Yesterday I read an interesting article in the “AI Journal“, which is the german news journal of amnesty international. It was about how many people in the world having internet access and how some governments and companies are censoring internet content. Thereby I saw this map:

Visualization of world-wide internet access taken from the current german "AI Journal"

Visualization of world-wide internet access taken from the current german "AI Journal"

Thanks to the Mercator projection, the European countries are about twice as large as there are in reality, Iceland appears as big as Spain and Alaska as big as Australia. As it’s impossible to map the surface of a sphere to a plane without distortions, every map projection has to deal with some kind of errors. But there is at least one mistake that cannot be tolerated. Can anybody see where Greenland has gone? I mean, it’s quite a large country so it’s not easy to forget. I think they simply left it out. Who cares about the 57,000 people living there? Who cares about all the people seeing this map in the journal? Who cares about visualization integrity? At least not the editorial staff from the German AI Journal.

So, I want to apologize to all people living in Greenland by completing this post with a map of Greenland in it’s real size and proportion. I know you are there!

The geographic position and size of Greenland

The geographic position and size of Greenland

Capturing Video from Flash Movies with ActionScript

I recently had the problem to store a flash animation into a video file. I first tried some tools I found in the net, but they all run into problems because my flash movie doesn’t integrate the MovieClip timeline. Tools like swf2avi are stopping the conversion after the first frame, because they’re thinking it’s the only frame. One way round is make let your movie extend the MovieClip class instead of the Sprite and to integrate the timeline in your animation. But this starts to get very difficult if you’re making heavy use of the timers and tweening engines.

The first thing you need to do, is to add a new event listener to the stage’s ENTER_FRAME event.

stage.addEventListener(Event.ENTER_FRAME, captureFrame);

Inside this event listener you have to check if the current frame is one of those you want to capture. It makes a lot of sense to limit the number of frames regarding to your requirements as all images will be stored uncompressed to your RAM, which might lead to problems if you capture too many frames at once. To capture a single frame you simply create a new BitmapData instance and draw the stage onto it. Since you don’t need transparent images for most video purposes, you set the third constructor parameter to false and define a background color as you like. Finally you store the frame in an array.

private const _fromFrame:uint = 0;
private const _toFrame:uint = 400;
private var _frame:uint = 0;
private var _bitmaps:Array = [];
 
private function captureFrame(e:Event):void 
{
	if (_frame >= _fromFrame && _frame < = _toFrame) {
		var bmp:BitmapData = new BitmapData(
			stage.stageWidth, stage.stageHeight, 
			false, 0x000000);
		bmp.draw(stage);
		_bitmaps.push(bmp);
	}
	_frame++;
}

Now that we stored all frames we wait till the movie finishes. The next thing to do is to compress the images. You can use the PNGEncoder class of the as3corelib. There is no way to save images directly to your harddrive via flash, so we need to go a way round using an http connection and a little php script on our local web server.

private function exportBitmaps():void
{
	var j:uint = _bitmaps.length;
	for (var i:uint = 0; i < j; i++) {
		// encoding the image as png
		var pngStream:ByteArray = PNGEncoder.encode(_bitmaps[i] as BitmapData);
 
		// setup a simple http connection to the php script
		var header:URLRequestHeader = new URLRequestHeader(
			"Content-type", "application/octet-stream");
		var urlReq:URLRequest = new URLRequest(
			"http://localhost/saveImage.php?name=frame_"+i+".png");
		urlReq.requestHeaders.push(header);
		urlReq.method = URLRequestMethod.POST;
		urlReq.data = pngStream;
 
		// send out the data
		new URLLoader(urlReq);
	}	
}

The php script is very simple, as it just puts the http post data into a new file on your harddisc.

if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
	file_put_contents("folder/".$_GET["name"], $GLOBALS["HTTP_RAW_POST_DATA"];);
}

Now you got a nice set of images and you’re ready to convert them into a video file in your favorite format. You can do this with a lot of free tools, I chose VirtualDub, for instance. That’s all..

frames

Polygon Operations in ActionScript

Polygons play a major role in a lot of visualization applications. Beside of the possibility of drawing polygons, there is neither an explicit presentation of polygon data nor are common polygon operations supported in ActionScript. As far as I know there is no simple solution available that solves the following geometrical problems for simple 2D polygons, so I wrote one. Continue reading

Simple Map Visualization In Flash – German Population Density

Today I’m going to demonstrate a simple geospation visualization in flash. Therefore I used a scalable vector graphic of germany which contains individual shapes for every district. and labeled them to the specific district id used by lots of datasets. The common source for data about germany is the german department for statistics. This time, I just used the population density which is the number of people living in a district divided to the districts area [km²].

The svg and the dataset are embedded into the flash movie for a better compression (800 -> 270kb)  and to enable the offline usage of the visualization. The svg is processed using a simple string based svg parser which just extracts the shape coordinates (either svg-polygons or svg-paths) and labels. I used the formerly introduced class PerceptualColor to map the data to hsl color values.

Update: added some interactivity and display for selected details.