RogerBW's Blog

Plotting onto Tactical Pilotage Charts 10 June 2014

Sometimes my interests intersect. I've been working on a way to plot markers and objects onto real-world charts.

The charts in question are the Tactical Pilotage Charts (1:500,000) and Operational Navigation Charts (1:1,000,000); these are used for civilian and some military air navigation, and so focus on terrain altitudes and features recognisable from the air. Current charts are vastly expensive, but a fairly complete set from the late 1980s and early 1990s is available from the Map Collection of the Perry-Castañeda Library at the University of Texas: here are the TPCs, and here are the ONCs.

I'm going to go into a fair bit of technical detail, but first: why am I doing this? (Beyond the obvious: for playing Harpoon or other games, e.g. by email, with limited information available to the players.) Two reasons. One is to use real world locations with some degree of accuracy; while many published scenarios for Harpoon are set in generic open sea, quite a few are not. A scenario map, such as the ones found in this PDF, tends to be a pretty rough affair, and is hard to translate into something directly gameable, whereas with the charts one can get a much greater degree of detail. The other reason is visual appeal, and this is why I'm using these particular charts rather than tiles from OpenStreetMap (which would be much simpler as there's continuous world-wide coverage, so I wouldn't need to think about individual map sheets): the aviation charts "feel" more relevant to the situation than a general-purpose map. (Maritime charts would be even better, of course, but there's no free source for those that I'm aware of, and many areas aren't covered at all.)

The scans aren't perfect; there are places where what should be straight lines suddenly jump sideways an arcminute or two, presumably because of a crease or tear in the original. But they're decently high resolution, to the point where a single map sheet can be around sixteen megabytes in size and 9000×6000 pixels. (Fortunately for a modern computer it's generally not a problem to view an image this large in a web browser, either zoomed out to get a general impression or zoomed in to view detail.) The full TPC set is around ten gibibytes, while the ONC set is about 3.4. Another downside is that there are no charts of areas that contain no land.

Also, these don't use a simple projection. They work on the Lambert conformal conic projection, and coping with that is what the meat of this post is about. I wrote my code in Perl, but I'll avoid specificities of programming language here.

This projection shows parallels of latitude as curved lines, and parallels of longitude as straight lines. I therefore made a simplifying abstraction: I treat the LCC as a form of polar coordinates, where latitude is the distance r from the north pole and longitude is the angle θ from some arbitrary meridian. There's some error in the longitude conversion by using this method, but it's less than the errors already in the scan.

This then is the basis for the conversion. I measure four points on the map, three along a parallel of latitude (conventionally the edge nearest the pole) and one along a (conventionally leftmost) parallel of longitude, and store both their latitude and longitude (read from the map) and their pixel x and y coordinates.

From the points at the same latitude, I generate the pixel coordinates xc and yc of the centre of the latitude circle (where the pole would be, if one were foolish enough to extend this map that far); this is of course a long way off the actual map. There are multiple methods for doing this, and your language's geometry library may already have one; failing that, either take the perpendicular bisectors of the lines between two of the pairs of points and find their intersection, or generate three simultaneous equations of the form (xn-xc)²+(yn-yc)²=R², where (xn,yn) are individual points on the circumference, and solve for R, xc and yc.

Then it's just a matter of generating linear conversions (of the form y=a+bx): one converts latitude in degrees to the r distance in pixels from the virtual pole (based on first and fourth points), while the other converts longitude in degrees to a useful θ, based on first and third points. At this point plotting a latitude/longitude location becomes a simple matter of converting polar to Cartesian coordinates (and of course the process is reversible).

I've played a fair bit of computer Harpoon, so I plot with the NTDS symbology, more or less as seen here, though I don't use the "carrier" symbol. It's fairly easy to pick up, and at least mildly authentic.

So here is HMS Coventry in San Carlos Water, coming under attack by a pair of Skyhawks. The heavy circles on land are small airfields.

simple example

Everything that gets plotted on the map is defined in terms of latitude and longitude coordinates rather than X and Y. This makes calculations of ranges and bearings somewhat more involved, but for Perl at least there's the excellent Geo::Ellipsoid module that does all the heavy lifting.

Since Harpoon gaming often involves submarines, I was very happy to find the ETOPO1 dataset from the NOAA. This is a free, arcminute-resolution, data set of global elevations, including sea depths. It's not perfect, but it's a usable abstraction that's easy to add to a map plot (here I'm converting depth to Harpoon's bands, off the southern coast of Norway in the midst of the Skagerrak).

example with depth bands

It's also possible to plot circles, boxes, and arbitrary paths (which can include arc segments as well as straight lines). Here's a setup map for the Battles of the Third World War scenario The Russians Are Coming, where the Russian start zone in the Barents Sea is described as "from 30 to 80 nautical miles from [the Norwegian ship Nordkapp], between bearings 080 and 100". (The black box surrounds all units that a player knows about, his own and any detected enemies, and is used as an aid for getting one's bearings on the full map.) Click image for full-size view.

example with setup zone

Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.

Tags 1920s 1930s 1940s 1950s 1960s 1970s 1980s 1990s 2000s 2010s 3d printing action aeronautics aikakirja anecdote animation anime army astronomy audio tech base commerce battletech beer boardgaming bookmonth chain of command children chronicle church of no redeeming virtues cold war comedy computing contemporary cornish smuggler cosmic encounter coup cycling dead of winter doctor who documentary drama driving drone ecchi espionage essen 2015 essen 2016 essen 2017 existential risk falklands war fandom fantasy film firefly first world war flash point food garmin drive gazebo geodata gurps gurps 101 harpoon historical history horror hugo 2014 hugo 2015 hugo 2016 hugo 2017 hugo-nebula reread in brief avoid instrumented life kickstarter learn to play leaving earth linux mecha museum mystery naval non-fiction one for the brow opera perl photography podcast politics powers prediction privacy project woolsack pyracantha quantum rail ranting raspberry pi reading reading boardgames social real life restaurant reviews romance rpg a day rpgs science fiction scythe second world war security shipwreck simutrans south atlantic war squaddies stationery steampunk stuarts suburbia superheroes suspense television the resistance thirsty meeples thriller tin soldier torg toys trailers travel vietnam war war wargaming weather wives and sweethearts writing about writing x-wing young adult
Special All book reviews, All film reviews
Produced by aikakirja v0.1