How indieprojector shaped the world

Posted by Andy

Our recent release of indieprojector is a fitting first step toward indiemapper, as it was the experiments with web-based map projection that sparked the idea for indiemapper a year and a half ago. Control of map projections, we found, is sorely lacking in the explosively popular and powerful world of web cartography. So we began working in Flash on a tool that would read shapefiles and re-project them for display and eventual export, and at least that goal has now been realized with indieprojector. Here we thought we’d pass on some of what we’ve learned along the way about working with map projections in ActionScript 3.

Projecting geo-data: the basics

To simply draw geo-data to a certain map projection is a pretty easy process. The data are loaded from SHP or KML files and stored as a series of latitude/longitude coordinates. (KML parsing takes advantage of AS3’s native XML capabilities, and our SHP loading and parsing are based on Edwin van Rijkom’s libraries.) Then, re-projecting the data is just a matter of plugging the lat/long values (in radians) into a projection’s transformation equation, incorporating applicable centering coordinates and standard parallels. Generally the math is straightforward. Here are the equations for a Mercator projection, for example (from Wikipedia):

Mercator equations

We found lots of help in Wikipedia, Wolfram MathWorld, and the PROJ.4 library, or more specifically this Java spinoff, which is easy to translate to AS3.

A Challenge

Warning: read no further if you don’t want to be immersed in the filthy details of how indieprojector works. Otherwise, what follows may serve as a useful lesson; it certainly did for us.

The most notable challenge of implementing the map projections in indieprojector was correctly re-centering maps on longitudes other than the default 0 degrees. As you can see below in the images below, with North America, re-centering the map can split polygons (and lines) in two.

World map centered at 0 longitude

World map with split polygons

The data as imported and stored, of course, define single polygons as… well, single polygons (with a very few exceptions). If we were to simply project all the points in a polygon and try to draw the shape, where drawing should stop at one edge of the map and pick up again at the other, it would instead draw a segment clear across the map from one end to the other, like this:

Draw from one point to the next (ignoring lots of actual points on this polygon for demonstration purposes)…
Drawing between points on the same side

But the next point is on the other side of the map! It draws all the way over to that point, and then continues from there.
Drawing between points across the map

This means that every time the projection settings are altered, we need to split polygons and lines on the fly as needed. Polygon and line data are already stored as sets of rings, which are the individual pieces of a single feature. (Consider, for instance, the state of Hawaii as a polygon feature. It is just one “polygon” but each of its islands is a separate ring.) So, when needed, we further divide polygons into more rings. For anyone interested, here is a simplified version of the steps we’re taking:

Look at the longitudes of the first two points. The first (right) is farther east (i.e. higher longitude) than the second, and is also closer to the right edge of the map than the second. This indicates that the two points are not divided by the map edge, so they belong in the same ring.
Drawing between points on the same side

Now look at the next pair of points. The first point (second point above, left image below) has a higher longitude, but is farther from the right edge of the map than the second point (inner point on the right image). This indicates that the two points are divided by the map edge. So, interpolate a point in between them on the map edge, and then add it to the original ring as well as to a new ring that will contain points on the other side of the map. Finally, add that second point to the new ring.
Drawing points on different sides of the map

Look at the next pair of points. Again the first point has a higher longitude and is closer to the right edge of the map, so the points belong in the same ring.
Drawing points on one side of the map

Between map edge crossings on a ring, we add a series of additional points on the edge so that the ring can approximately follow the curved edge of some projections.
Extra edge points

Our algorithms will continue to evolve, eventually into proper clipping routines, but we think we’ve made a good start toward bringing projections into web-based mapping for the common cartographer. It’s a virtual globe and Mercator world out there, and those are fine for a lot of purposes, but our training and experience has taught us that a Greenland-on-steroids projection and an obscuring, variable-perspective 3D globe are probably not the best for thematic maps. Our math and drawing hurdles here don’t address the much larger challenges of bringing map projections fully into mainstream web cartography, but we hope that indiemapper (and indieprojector) will serve as a good introduction.

One Response to “How indieprojector shaped the world”

  1. [Indiemapper] How indieprojector shaped the world | Axis Maps Blog Says:

    [...] How indieprojector shaped the world (via indiemapper blog) « [Indiemapper] Announcing: [...]

Leave a Reply