Setting up to lasercut Bravo airspace

Another Ponoko project, making a 3d model of San Francisco’s Bravo airspace. It’s a bunch of roughly circular slices, should be great cutting a disc every 500′ or 1000′ to the outlines of the bravo. Some first steps to getting there, from raw data to basic (not finished) SVG files.

1. Download the FADDS database to get the FAA’s shapefiles of airspace. It contains some shapefiles for airspace.

2. Identify the coordinate reference system because shp2pgsql isn’t smart enough to guess. Class_b.prj says:

GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]

A quick lookup lets me know this is NAD83, EPSG:4269. That’s what I would have guessed, it’s quite close to WGS84, the GPS reference everyone sane uses. US government prefers NAD83 for some complex historical reason.

3. Load a database.

createdb faa -T template_postgis2
shp2pgsql -s 4269 class_b.shp | psql faa

4. Try loading the data into QGIS and see if it looks right. This is where projections start to matter. The Project Properties dialog lets you reproject the data on rendering; you have to check “Enable on the fly CRS transformation”. The SF bravo looks wrong when projected to WGS 84 (EPSG: 4326), too squashed. They should look like circles, using some projection local to San Francisco. There’s a few NAD 83 / California Albers projections that do pretty well, like EPSG: 3310.

Even better is grab Aeronav’s GeoTIFF for San Francisco and see what they use; pilots expect the airspace to look like it does on the chart. Here’s what gdalinfo and QGIS identify it as:

+proj=lcc +lat_1=45 +lat_2=33 +lat_0=37.6 +lon_0=-122.25 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs

PROJCS["San Francisco TAC",
    GEOGCS["NAD83",
        DATUM["North_American_Datum_1983",
            SPHEROID["GRS 1980",6378137,298.2572221010002,
                AUTHORITY["EPSG","7019"]],
            AUTHORITY["EPSG","6269"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4269"]],
    PROJECTION["Lambert_Conformal_Conic_2SP"],
    PARAMETER["standard_parallel_1",45],
    PARAMETER["standard_parallel_2",33],
    PARAMETER["latitude_of_origin",37.6],
    PARAMETER["central_meridian",-122.25],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]
Origin = (-144533.795827518420992,71334.980332990919123)
Pixel Size = (31.819676000000001,-31.819676000000001)

Here’s a gallery of what the airspace shape looks like in WGS 84 (the squished one), that California Albers, and the “correct” Lambert projection the FAA uses (with the raster backdrop). The latter two are pretty close, but I could make things hard for myself and use the custom Lambert projection. Instead I’m going to use EPSG:26942, a Lambert that’s centered more or less on San Francisco. Visually the result looks very similar to the FAA’s projection, with the advantage I don’t have to figure out how to add a custom CRS to PostGIS.

5. Create an SVG file with some code. Naively this is as simple as ST_AsSVG(geom) and pasting the path into a skeleton SVG document. This actually works, but is a bit awkward since without reprojection the coordinates are all lat/lon values and stuff’s in a box from 37, -115 to 40, -118 or so. Quick workaround for that in Inkscape: select all (Ctrl-A) then zoom to selection (3). Also need to set the stroke width to something sensible for the coordinates.

 

Having to stop work on this here; I’m now generating reasonable SVG files, one per chunk of Bravo. Two main things left to do. First, use SVG transforms to scale the shapes from the default extent numbers like x=2,000,000 y=464,000 to something like 7cm square Ponoko uses. And second, do some topology calculations with ST_Union or the like so I render each slice of the airspace cake for every elevation.