diff --git a/src/Airports/GenAirports/airport.cxx b/src/Airports/GenAirports/airport.cxx
index 8b28d998..b8d15763 100644
--- a/src/Airports/GenAirports/airport.cxx
+++ b/src/Airports/GenAirports/airport.cxx
@@ -1,1138 +1,1160 @@
-#include <ctime>
-#include <list>
-
-#include <stdio.h>
-
-#include <simgear/bucket/newbucket.hxx>
-#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/io/sg_binobj.hxx>
-#include <simgear/math/SGGeometry.hxx>
-#include <simgear/math/sg_geodesy.hxx>
-#include <simgear/misc/texcoord.hxx>
-#include <simgear/structure/exception.hxx>
-
-#include <terragear/tg_chopper.hxx>
-#include <terragear/tg_polygon.hxx>
-#include <terragear/tg_shapefile.hxx>
-#include <terragear/tg_unique_geod.hxx>
-#include <terragear/tg_unique_vec2f.hxx>
-#include <terragear/tg_unique_vec3f.hxx>
-
-#include "airport.hxx"
-#include "beznode.hxx"
-#include "debug.hxx"
-#include "elevations.hxx"
-#include "global.hxx"
-#include "helipad.hxx"
-#include "output.hxx"
-#include "runway.hxx"
-
-
-Airport::Airport(int c, char* def)
-{
-    int numParams;
-    char* tok;
-#if 0 // temporary until we can confirm that this isn't still being used.
-    int   ct = 0;
-#endif
-
-    code = c;
-
-    // we need to tokenize airports, since we can't scanf two strings next to each other...
-    numParams = 0;
-    bool done = false;
-
-    while (!done) {
-        // trim leading whitespace
-        while (isspace(*def)) def++;
-
-        tok = strtok(def, " \t\r\n");
-
-        if (tok) {
-            def += strlen(tok) + 1;
-
-            switch (numParams) {
-            case 0:
-                // airport elevation (feet MSL)
-                altitude = atoi(tok);
-                break;
-
-            case 1:
-                // Airport has a control tower (1=yes, 0=no)
-                // deprecated v10.00
-#if 0 // temporary until we can confirm that this isn't still being used.
-                    ct = atoi(tok);
-#endif
-                break;
-
-            case 2:
-                // default airport buildings (1=yes, 0=no)
-                // deprecated v8.50
-                break;
-
-            case 3:
-                // ICAO code (FAA code when ICAO doesn't exist)
-                icao = tok;
-                // tok-4 = airport name
-                description = def;
-                done = true;
-                break;
-            }
-        }
-        numParams++;
-    }
-
-    altitude *= SG_FEET_TO_METER;
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Read airport with icao " << icao << ", and description " << description);
-}
-
-Airport::~Airport()
-{
-    std::fill(features.begin(), features.end(), nullptr);
-    std::fill(helipads.begin(), helipads.end(), nullptr);
-    std::fill(runways.begin(), runways.end(), nullptr);
-    std::fill(waterrunways.begin(), waterrunways.end(), nullptr);
-    std::fill(pavements.begin(), pavements.end(), nullptr);
-    std::fill(taxiways.begin(), taxiways.end(), nullptr);
-    std::fill(lightobjects.begin(), lightobjects.end(), nullptr);
-    std::fill(windsocks.begin(), windsocks.end(), nullptr);
-    std::fill(beacons.begin(), beacons.end(), nullptr);
-    std::fill(signs.begin(), signs.end(), nullptr);
-    std::fill(boundary.begin(), boundary.end(), nullptr);
-}
-
-bool Airport::isDebugRunway(int rwy)
-{
-    bool dbg = false;
-
-    debug_map_const_iterator it = debug_runways.find(icao);
-    if (it != debug_runways.end()) {
-        for (unsigned int i = 0; i < it->second.size() && !dbg; i++) {
-            if (it->second[i] == std::numeric_limits<int>::max()) {
-                dbg = true;
-            } else if (it->second[i] == rwy + 1) {
-                dbg = true;
-            }
-        }
-    }
-
-    return dbg;
-}
-
-bool Airport::isDebugPavement(int pvmt)
-{
-    bool dbg = false;
-
-    debug_map_const_iterator it = debug_pavements.find(icao);
-    if (it != debug_pavements.end()) {
-        for (unsigned int i = 0; i < it->second.size() && !dbg; i++) {
-            if (it->second[i] == std::numeric_limits<int>::max()) {
-                dbg = true;
-            } else if (it->second[i] == pvmt + 1) {
-                dbg = true;
-            }
-        }
-    }
-
-    return dbg;
-}
-
-bool Airport::isDebugTaxiway(int taxi)
-{
-    bool dbg = false;
-
-    debug_map_const_iterator it = debug_taxiways.find(icao);
-    if (it != debug_taxiways.end()) {
-        for (unsigned int i = 0; i < it->second.size() && !dbg; i++) {
-            if (it->second[i] == std::numeric_limits<int>::max()) {
-                dbg = true;
-            } else if (it->second[i] == taxi + 1) {
-                dbg = true;
-            }
-        }
-    }
-
-    return dbg;
-}
-
-bool Airport::isDebugFeature(int feat)
-{
-    bool dbg = false;
-
-    debug_map_const_iterator it = debug_features.find(icao);
-    if (it != debug_features.end()) {
-        for (unsigned int i = 0; i < it->second.size() && !dbg; i++) {
-            if (it->second[i] == std::numeric_limits<int>::max()) {
-                dbg = true;
-            } else if (it->second[i] == feat + 1) {
-                dbg = true;
-            }
-        }
-    }
-
-    return dbg;
-}
-
-void Airport::BuildBtg(const std::string& root, const string_list& elev_src)
-{
-    tgcontour_list slivers;
-    tgcontour_list line_slivers;
-
-    tgpolygon_list apt_base_polys;
-    tgpolygon_list apt_clearing_polys;
-
-    // runways
-    tgpolygon_list rwy_polys;
-
-    // pavements
-    tgpolygon_list pvmt_polys;
-
-    // linear features
-    tgpolygon_list line_polys;
-
-    // runway lights
-    tglightcontour_list rwy_lights;
-
-    char debug_root[32];
-    snprintf(debug_root, 32, "./airport_dbg/%s/", icao.c_str());
-
-    // parse main airport information
-    double apt_lon = 0.0, apt_lat = 0.0;
-
-    SGTimeStamp build_start;
-    SGTimeStamp build_end;
-    SGTimeStamp cleanup_start;
-    SGTimeStamp cleanup_end;
-    SGTimeStamp triangulation_start;
-    SGTimeStamp triangulation_end;
-    time_t log_time;
-
-    char shapefile_name[64];
-    std::string shapefile;
-
-    // Find the average of all the runway and heliport long / lats
-    int num_samples = 0;
-    for (auto& runway : runways) {
-        apt_lon += runway->GetMidpoint().getLongitudeDeg();
-        apt_lat += runway->GetMidpoint().getLatitudeDeg();
-        num_samples++;
-    }
-
-    for (auto& helipad : helipads) {
-        apt_lon += helipad->GetLoc().getLongitudeDeg();
-        apt_lat += helipad->GetLoc().getLatitudeDeg();
-        num_samples++;
-    }
-
-    apt_lon = apt_lon / (double)num_samples;
-    apt_lat = apt_lat / (double)num_samples;
-
-    SGBucket b(SGGeod::fromDeg(apt_lon, apt_lat));
-    TG_LOG(SG_GENERAL, SG_DEBUG, b.gen_base_path() << "/" << b.gen_index_str());
-
-    // If we are cutting in the linear features, add them first
-    if (pavements.size()) {
-        for (auto& pavement : pavements) {
-            AddFeatures(pavement->GetFeatures());
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Parse Complete - Runways: " << runways.size() << " Pavements: " << pavements.size() << " Features: " << features.size() << " Taxiways: " << taxiways.size());
-
-    // Starting to clip the polys (for now - only UNIX builds)
-    build_start.stamp();
-
-    // Add the linear features
-    if (features.size()) {
-        tgAccumulator lf_accum(icao);
-
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << features.size() << " Linear Feature Polys");
-        unsigned i = 0;
-        for (auto& feature : features) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << ++i << " of " << features.size() << " : " << feature->GetDescription());
-
-            bool make_shapefiles = false;
-            feature->BuildBtg(line_polys, rwy_lights, lf_accum, make_shapefiles);
-        }
-
-        log_time = time(0);
-        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << DebugTimeToString(log_time));
-    }
-
-    /* Initialize a new accumulator for the other objects */
-    tgAccumulator pvmt_accum(icao);
-
-    // Build runways next
-    if (runways.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Polys");
-        unsigned i = 0;
-        for (auto& runway : runways) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i+1 << " of " << runways.size());
-
-            if (isDebugRunway(i))
-                sprintf(shapefile_name, "runway_%u", i);
-            else
-                strcpy(shapefile_name, "");
-            shapefile = shapefile_name;
-
-            if (boundary.size())
-                runway->BuildBtg(rwy_polys, rwy_lights, slivers, pvmt_accum, shapefile);
-            else
-                runway->BuildBtg(rwy_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
-            ++i;
-        }
-
-        log_time = time(0);
-        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << DebugTimeToString(log_time));
-    }
-
-    if (lightobjects.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << lightobjects.size() << " Light Objects ");
-        unsigned i = 0;
-        for (auto& light : lightobjects) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build runway light " << ++i << " of " << lightobjects.size());
-            light->BuildBtg(rwy_lights);
-        }
-    }
-
-    // Build helipads (use runway poly- and texture list for this)
-    if (helipads.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << helipads.size() << " Helipad Polys ");
-        unsigned i = 0;
-        for (auto& helipad : helipads) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << ++i << " of " << helipads.size());
-
-            if (boundary.size())
-                helipad->BuildBtg(rwy_polys, rwy_lights, slivers, pvmt_accum);
-            else
-                helipad->BuildBtg(rwy_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum);
-        }
-    }
-
-    // Build the pavements
-    if (pavements.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << pavements.size() << " Pavement Polys ");
-        unsigned i = 0;
-        for (auto& pavement : pavements) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i+1 << " of " << pavements.size() << " : " << pavement->GetDescription());
-
-            if (isDebugPavement(i))
-                sprintf(shapefile_name, "pvmnt_%u", i);
-            else
-                strcpy(shapefile_name, "");
-            shapefile = shapefile_name;
-
-            if (boundary.size())
-                pavement->BuildBtg(pvmt_polys, slivers, pvmt_accum, shapefile);
-            else
-                pavement->BuildBtg(pvmt_polys, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
-            ++i;
-        }
-
-        log_time = time(0);
-        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << DebugTimeToString(log_time));
-    }
-
-    // Build the legacy taxiways
-    if (taxiways.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << taxiways.size() << " Taxiway Polys ");
-
-        unsigned i = 0;
-        for (auto& taxiway : taxiways) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Taxiway " << i+1 << " of " << taxiways.size());
-
-            if (isDebugTaxiway(i))
-                sprintf(shapefile_name, "taxiway_%u", i);
-            else
-                strcpy(shapefile_name, "");
-            shapefile = shapefile_name;
-
-            if (boundary.size())
-                taxiway->BuildBtg(pvmt_polys, rwy_lights, slivers, pvmt_accum, shapefile);
-            else
-                taxiway->BuildBtg(pvmt_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
-            ++i;
-        }
-    }
-
-    // Build runway shoulders here
-    if (runways.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Shoulder Polys ");
-
-        unsigned i = 0;
-        for (auto& runway : runways) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << ++i << " of " << runways.size());
-
-            if (runway->GetsShoulder())
-                runway->BuildShoulder(rwy_polys, slivers, pvmt_accum);
-        }
-    }
-
-    // Build helipad shoulders here
-    if (helipads.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Helipad Shoulder Polys ");
-
-        unsigned i = 0;
-        for (auto& helipad : helipads) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Helipad shoulder " << ++i << " of " << helipads.size());
-
-            if (helipad->GetsShoulder())
-                helipad->BuildShoulder(rwy_polys, slivers, pvmt_accum);
-        }
-    }
-
-    // build the base and clearing if there's a boundary
-    tgPolygon apt_base, apt_clearing;
-    if (boundary.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Build " << boundary.size() << " Boundary Polys ");
-
-        shapefile = "";
-
-        unsigned i = 0;
-        for (auto& b : boundary) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Build user-defined boundary " << ++i << " of " << boundary.size());
-
-            b->BuildBtg(apt_base, apt_clearing, shapefile);
-        }
-    } else {
-        apt_base = tgPolygon::Union(apt_base_polys);
-        apt_clearing = tgPolygon::Union(apt_clearing_polys);
-    }
-
-    if (apt_base.TotalNodes() == 0) {
-        TG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
-        return;
-    }
-
-    tgPolygon filled_base = tgPolygon::StripHoles(apt_base);
-    tgPolygon divided_base = tgPolygon::SplitLongEdges(filled_base, 200.0);
-    tgPolygon base_poly = pvmt_accum.Diff(divided_base);
-
-    build_end.stamp();
-    build_time = build_end - build_start;
-
-    cleanup_start.stamp();
-
-    // add segments to polygons to remove any possible "T"
-    // intersections
-    UniqueSGGeodSet tmp_pvmt_nodes;
-    UniqueSGGeodSet tmp_feat_nodes;
-
-    // build temporary node list from runways...
-    TG_LOG(SG_GENERAL, SG_INFO, "Build Node List ");
-    for (unsigned int k = 0; k < rwy_polys.size(); ++k) {
-        tgPolygon poly = rwy_polys[k];
-        for (unsigned int i = 0; i < poly.Contours(); ++i) {
-            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
-                tmp_pvmt_nodes.add(poly.GetNode(i, j));
-            }
-        }
-    }
-
-    // and pavements
-    for (unsigned int k = 0; k < pvmt_polys.size(); ++k) {
-        tgPolygon poly = pvmt_polys[k];
-        for (unsigned int i = 0; i < poly.Contours(); ++i) {
-            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
-                tmp_pvmt_nodes.add(poly.GetNode(i, j));
-            }
-        }
-    }
-
-    // and linear features ( keep Linear feature nodes separate)
-    for (unsigned int k = 0; k < line_polys.size(); ++k) {
-        tgPolygon poly = line_polys[k];
-        for (unsigned int i = 0; i < poly.Contours(); ++i) {
-            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
-                tmp_feat_nodes.add(poly.GetNode(i, j));
-            }
-        }
-    }
-
-    // and the base
-    for (unsigned int i = 0; i < base_poly.Contours(); ++i) {
-        for (unsigned int j = 0; j < base_poly.ContourSize(i); ++j) {
-            tmp_pvmt_nodes.add(base_poly.GetNode(i, j));
-        }
-    }
-
-    // the divided base could contain points not found in base_poly,
-    // so we should add them because the skirt needs them.
-    for (unsigned int i = 0; i < divided_base.Contours(); ++i) {
-        for (unsigned int j = 0; j < divided_base.ContourSize(i); ++j) {
-            tmp_pvmt_nodes.add(divided_base.GetNode(i, j));
-        }
-    }
-
-    log_time = time(0);
-    TG_LOG(SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << DebugTimeToString(log_time));
-
-    // second pass : runways
-    for (unsigned int k = 0; k < rwy_polys.size(); ++k) {
-        tgPolygon poly = rwy_polys[k];
-        poly = tgPolygon::AddColinearNodes(poly, tmp_pvmt_nodes);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
-        rwy_polys[k] = poly;
-    }
-
-    // second pass : and pavements
-    for (unsigned int k = 0; k < pvmt_polys.size(); ++k) {
-        tgPolygon poly = pvmt_polys[k];
-        poly = tgPolygon::AddColinearNodes(poly, tmp_pvmt_nodes);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
-        pvmt_polys[k] = poly;
-    }
-
-    // second pass : and lines
-    for (unsigned int k = 0; k < line_polys.size(); ++k) {
-        tgPolygon poly = line_polys[k];
-        poly = tgPolygon::AddColinearNodes(poly, tmp_feat_nodes);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
-        line_polys[k] = poly;
-    }
-
-    log_time = time(0);
-    TG_LOG(SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << DebugTimeToString(log_time));
-
-    for (unsigned int k = 0; k < line_polys.size(); ++k) {
-        tgPolygon poly = line_polys[k];
-
-#if 1
-        poly = tgPolygon::RemoveCycles(poly);
-        poly = tgPolygon::RemoveDups(poly);
-        poly = tgPolygon::RemoveBadContours(poly);
-#endif
-
-        line_polys[k] = poly;
-    }
-
-    log_time = time(0);
-    TG_LOG(SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << DebugTimeToString(log_time));
-
-    base_poly = tgPolygon::AddColinearNodes(base_poly, tmp_pvmt_nodes);
-
-    cleanup_end.stamp();
-    cleanup_time = cleanup_end - cleanup_start;
-
-    /* before tessellating the base, make sure there are no
-       intersecting contours */
-    base_poly = tgPolygon::Simplify(base_poly);
-
-    triangulation_start.stamp();
-
-    // tesselate the polygons and prepare them for final output
-    if (rwy_polys.size()) {
-        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << rwy_polys.size() << " Runway Polys ");
-        for (unsigned int i = 0; i < rwy_polys.size(); ++i) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating runway poly = " << i + 1 << " of " << rwy_polys.size());
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes());
-            rwy_polys[i].Tesselate();
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
-            rwy_polys[i].Texture();
-        }
-    }
-
-    if (pvmt_polys.size()) {
-        // tesselate the polygons and prepare them for final output
-        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << pvmt_polys.size() << " Pavement Polys ");
-        for (unsigned int i = 0; i < pvmt_polys.size(); ++i) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating pavement poly = " << i + 1 << " of " << pvmt_polys.size());
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes());
-            pvmt_polys[i].Tesselate();
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles());
-            pvmt_polys[i].Texture();
-        }
-    }
-
-    if (line_polys.size()) {
-        // tesselate the polygons and prepare them for final output
-        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << line_polys.size() << " Linear Feature Polys ");
-        for (unsigned int i = 0; i < line_polys.size(); ++i) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating line poly = " << i + 1 << " of " << line_polys.size());
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes());
-            line_polys[i].Tesselate();
-
-            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles());
-            line_polys[i].Texture();
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly : " << base_poly.Contours() << " contours ");
-    base_poly.Tesselate();
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done : Triangles = " << base_poly.Triangles());
-    // should we texture base here?
-    base_poly.SetTexMethod(TG_TEX_BY_GEODE, b.get_center_lat());
-    base_poly.Texture();
-
-    triangulation_end.stamp();
-
-    // a few airports fail here
-    if (base_poly.Triangles() == 0) {
-        TG_LOG(SG_GENERAL, SG_ALERT, "no base poly triangles");
-        return;
-    }
-
-    triangulation_time = triangulation_end - triangulation_start;
-
-    //
-    // We should now have the runway polygons all generated with their
-    // corresponding triangles and texture coordinates, and the
-    // surrounding base area.
-    //
-    // Next we need to create the output lists ... vertices, normals,
-    // texture coordinates, and tri-strips
-    //
-
-    // traverse the tri list and create ordered node and texture
-    // coordinate lists
-    // start with just nodes
-    SGBinObject obj;
-    SGBinObjectTriangle sgboTri;
-    SGBinObjectPoint sgboPt;
-
-    UniqueSGGeodSet nodes;
-    UniqueSGVec3fSet normals;
-    UniqueSGVec2fSet texcoords;
-
-    group_list pts_v;
-    pts_v.clear();
-    group_list pts_n;
-    pts_n.clear();
-    string_list pt_materials;
-    pt_materials.clear();
-
-    group_list tris_v;
-    tris_v.clear();
-    group_list tris_n;
-    tris_n.clear();
-    group_list tris_tc;
-    tris_tc.clear();
-    string_list tri_materials;
-    tri_materials.clear();
-
-    group_list strips_v;
-    strips_v.clear();
-    group_list strips_n;
-    strips_n.clear();
-    group_list strips_tc;
-    strips_tc.clear();
-    string_list strip_materials;
-    strip_materials.clear();
-
-    int_list pt_v, tri_v, strip_v;
-    int_list pt_n, tri_n, strip_n;
-    int_list tri_tc, strip_tc;
-
-    // calculate "the" normal for this airport
-    SGVec3f vnt = SGVec3f::fromGeod(base_poly.GetNode(0, 0));
-    vnt = normalize(vnt);
-    TG_LOG(SG_GENERAL, SG_INFO, "Adding runway nodes and normals");
-
-    for (unsigned int k = 0; k < rwy_polys.size(); ++k) {
-        tgPolygon poly = rwy_polys[k];
-
-        TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
-        std::string material = rwy_polys[k].GetMaterial();
-        TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << rwy_polys[k].Triangles());
-        for (unsigned int i = 0; i < rwy_polys[k].Triangles(); ++i) {
-            sgboTri.clear();
-            sgboTri.material = material;
-
-            for (int l = 0; l < 3; ++l) {
-                int index = nodes.add(poly.GetTriNode(i, l));
-                sgboTri.v_list.push_back(index);
-
-                // use 'the' normal
-                index = normals.add(vnt);
-                sgboTri.n_list.push_back(index);
-
-                index = texcoords.add(poly.GetTriTexCoord(i, l));
-                sgboTri.tc_list[0].push_back(index);
-            }
-
-            obj.add_triangle(sgboTri);
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Adding pavement nodes and normals");
-    for (unsigned int k = 0; k < pvmt_polys.size(); ++k) {
-        TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
-        std::string material = pvmt_polys[k].GetMaterial();
-        TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << pvmt_polys[k].Triangles());
-        for (unsigned int i = 0; i < pvmt_polys[k].Triangles(); ++i) {
-            tgPolygon poly = pvmt_polys[k];
-            sgboTri.clear();
-            sgboTri.material = material;
-
-            for (int l = 0; l < 3; ++l) {
-                int index = nodes.add(poly.GetTriNode(i, l));
-                sgboTri.v_list.push_back(index);
-
-                // use 'the' normal
-                index = normals.add(vnt);
-                sgboTri.n_list.push_back(index);
-
-                index = texcoords.add(poly.GetTriTexCoord(i, l));
-                sgboTri.tc_list[0].push_back(index);
-            }
-
-            obj.add_triangle(sgboTri);
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Adding line nodes and normals");
-    for (unsigned int k = 0; k < line_polys.size(); ++k) {
-        TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
-        std::string material = line_polys[k].GetMaterial();
-        TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
-        TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << line_polys[k].Triangles());
-        for (unsigned int i = 0; i < line_polys[k].Triangles(); ++i) {
-            tgPolygon poly = line_polys[k];
-            sgboTri.clear();
-            sgboTri.material = material;
-
-            for (int l = 0; l < 3; ++l) {
-                int index = nodes.add(poly.GetTriNode(i, l));
-                sgboTri.v_list.push_back(index);
-
-                // use 'the' normal
-                index = normals.add(vnt);
-                sgboTri.n_list.push_back(index);
-
-                index = texcoords.add(poly.GetTriTexCoord(i, l));
-                sgboTri.tc_list[0].push_back(index);
-            }
-
-            obj.add_triangle(sgboTri);
-        }
-    }
-
-    // add base points
-    TG_LOG(SG_GENERAL, SG_INFO, "Adding base triangles");
-    std::string material = "Grass";
-    for (unsigned int k = 0; k < base_poly.Triangles(); ++k) {
-        sgboTri.clear();
-        sgboTri.material = material;
-
-        for (int l = 0; l < 3; ++l) {
-            int index = nodes.add(base_poly.GetTriNode(k, l));
-            sgboTri.v_list.push_back(index);
-
-            // use 'the' normal
-            index = normals.add(vnt);
-            sgboTri.n_list.push_back(index);
-
-            index = texcoords.add(base_poly.GetTriTexCoord(k, l));
-            sgboTri.tc_list[0].push_back(index);
-        }
-
-        obj.add_triangle(sgboTri);
-    }
-
-    // on rare occasion, one or more of the divided base points can be
-    // missed.  Make sure they are all in the node list so we can
-    // build a proper skirt.
-    for (unsigned int i = 0; i < divided_base.Contours(); ++i) {
-        for (unsigned int j = 0; j < divided_base.ContourSize(i); ++j) {
-            int index = nodes.add(divided_base.GetNode(i, j));
-            TG_LOG(SG_GENERAL, SG_DEBUG, "added base point " << divided_base.GetNode(i, j) << " at " << index);
-        }
-    }
-
-    // Now that we have assembled all the airport geometry nodes into
-    // a list, calculate an "average" airport elevation based on all
-    // the actual airport node points.  This is more useful than
-    // calculating an average over the entire airport surface because
-    // it avoids biases introduced from the surrounding area if the
-    // airport is located in a bowl or on a hill.
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, " calc average elevation");
-    {
-        std::vector<SGGeod> dbg = nodes.get_list();
-
-        // dump the node list
-        TG_LOG(SG_GENERAL, SG_DEBUG, " node list size is " << dbg.size());
-        for (unsigned int w = 0; w < dbg.size(); w++) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, " node " << w << " is " << dbg[w]);
-        }
-    }
-
-    double average = tgAverageElevation(root, elev_src, nodes.get_list());
-
-    // Now build the fitted airport surface ...
-
-    // calculation min/max coordinates of airport area
-    TG_LOG(SG_GENERAL, SG_DEBUG, " calculation min/max coordinates of airport area");
-
-    SGGeod min_deg = SGGeod::fromDeg(9999.0, 9999.0);
-    SGGeod max_deg = SGGeod::fromDeg(-9999.0, -9999.0);
-    for (unsigned int j = 0; j < nodes.get_list().size(); ++j) {
-        SGGeod p = nodes.get_list()[j];
-        if (p.getLongitudeDeg() < min_deg.getLongitudeDeg()) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "new min lon from node " << j << " is " << p.getLongitudeDeg());
-            min_deg.setLongitudeDeg(p.getLongitudeDeg());
-        }
-        if (p.getLongitudeDeg() > max_deg.getLongitudeDeg()) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "new max lon from node " << j << " is " << p.getLongitudeDeg());
-            max_deg.setLongitudeDeg(p.getLongitudeDeg());
-        }
-        if (p.getLatitudeDeg() < min_deg.getLatitudeDeg()) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "new min lat from node " << j << " is " << p.getLatitudeDeg());
-            min_deg.setLatitudeDeg(p.getLatitudeDeg());
-        }
-        if (p.getLatitudeDeg() > max_deg.getLatitudeDeg()) {
-            TG_LOG(SG_GENERAL, SG_DEBUG, "new max lat from node " << j << " is " << p.getLatitudeDeg());
-            max_deg.setLatitudeDeg(p.getLatitudeDeg());
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Before extending for lights: min = " << min_deg << " max = " << max_deg);
-
-    // extend the min/max coordinates of airport area to cover all
-    // lights as well
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : num rwy lights is " << rwy_lights.size());
-    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
-        TG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : rwy light " << i << "has " << rwy_lights[i].ContourSize() << " lights ");
-
-        for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); ++j) {
-            SGGeod p = rwy_lights[i].GetNode(j);
-            if (p.getLongitudeDeg() < min_deg.getLongitudeDeg()) {
-                min_deg.setLongitudeDeg(p.getLongitudeDeg());
-            }
-            if (p.getLongitudeDeg() > max_deg.getLongitudeDeg()) {
-                max_deg.setLongitudeDeg(p.getLongitudeDeg());
-            }
-            if (p.getLatitudeDeg() < min_deg.getLatitudeDeg()) {
-                min_deg.setLatitudeDeg(p.getLatitudeDeg());
-            }
-            if (p.getLatitudeDeg() > max_deg.getLatitudeDeg()) {
-                max_deg.setLatitudeDeg(p.getLatitudeDeg());
-            }
-        }
-    }
-
-    // Extend the area a bit so we don't have weird things on the edges
-    double dlon = max_deg.getLongitudeDeg() - min_deg.getLongitudeDeg();
-    double dlat = max_deg.getLatitudeDeg() - min_deg.getLatitudeDeg();
-    min_deg.setLongitudeDeg(min_deg.getLongitudeDeg() - 0.01 * dlon);
-    max_deg.setLongitudeDeg(max_deg.getLongitudeDeg() + 0.01 * dlon);
-    min_deg.setLatitudeDeg(min_deg.getLatitudeDeg() - 0.01 * dlat);
-    max_deg.setLatitudeDeg(max_deg.getLatitudeDeg() + 0.01 * dlat);
-    TG_LOG(SG_GENERAL, SG_DEBUG, "min = " << min_deg << " max = " << max_deg);
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Create Apt surface:");
-    TG_LOG(SG_GENERAL, SG_DEBUG, " root: " << root);
-    //TG_LOG(SG_GENERAL, SG_DEBUG, " elev: " << elev_src );
-    TG_LOG(SG_GENERAL, SG_DEBUG, " min: " << min_deg);
-    TG_LOG(SG_GENERAL, SG_DEBUG, " max: " << max_deg);
-    TG_LOG(SG_GENERAL, SG_DEBUG, " average: " << average);
-
-    tgRectangle aptBounds(min_deg, max_deg);
-    tgSurface apt_surf(root, elev_src, aptBounds, average, slope_max, slope_eps);
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
-
-    // add light points
-    // pass one, calculate raw elevations from Array
-    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
-        for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); j++) {
-            double light_elevation = apt_surf.calc_elevation(rwy_lights[i].GetNode(j), 0.0);
-            rwy_lights[i].SetElevation(j, light_elevation);
-        }
-    }
-
-    TG_LOG(SG_GENERAL, SG_INFO, "Done with lighting calc_elevations() num light polys is " << rwy_lights.size());
-
-    // pass two, for each light group check if we need to lift (based
-    // on flag) and do so, then output next structures.
-    // for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
-    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
-        if (rwy_lights[i].ContourSize()) {
-            sgboPt.clear();
-            sgboPt.material = rwy_lights[i].GetType();
-
-            for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); ++j) {
-                int index = nodes.add(rwy_lights[i].GetPosition(j));
-                sgboPt.v_list.push_back(index);
-
-                index = normals.add(rwy_lights[i].GetNormal(j));
-                sgboPt.n_list.push_back(index);
-            }
-            obj.add_point(sgboPt);
-        }
-    }
-
-    // calculate node elevations
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Computing airport node elevations");
-
-    std::vector<SGGeod> geod_nodes = apt_surf.calc_elevations(nodes.get_list(), 0.0);
-    divided_base = apt_surf.calc_elevations(divided_base, 0.0);
-
-    // calculate wgs84 mapping of nodes
-    std::vector<SGVec3d> wgs84_nodes;
-    for (unsigned int i = 0; i < geod_nodes.size(); ++i) {
-        wgs84_nodes.push_back(SGVec3d::fromGeod(geod_nodes[i]));
-    }
-
-    SGVec3d gbs_center = SGVec3d::fromGeod(b.get_center());
-    double radius_squared = 0;
-    for (unsigned int i = 0; i < wgs84_nodes.size(); ++i) {
-        double dist_squared = distSqr(gbs_center, wgs84_nodes[i]);
-        if (dist_squared > radius_squared) {
-            radius_squared = dist_squared;
-        }
-    }
-
-    double gbs_radius = sqrt(radius_squared);
-
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Done with wgs84 node mapping");
-    TG_LOG(SG_GENERAL, SG_DEBUG, "  center = " << gbs_center << " radius = " << gbs_radius);
-
-    // null structures
-    std::string objpath = root + "/AirportObj";
-    std::string name = icao + ".btg";
-
-    obj.set_gbs_center(gbs_center);
-    obj.set_gbs_radius(gbs_radius);
-    obj.set_wgs84_nodes(wgs84_nodes);
-    obj.set_normals(normals.get_list());
-    obj.set_texcoords(texcoords.get_list());
-
-    bool result;
-    result = obj.write_bin(objpath, name, b);
-    if (!result) {
-        throw sg_exception("error writing file. :-(");
-    }
-
-    std::string indexFileName = objpath + "/" + b.gen_base_path() + "/" + b.gen_index_str() + ".ind";
-    if (cleanIndexFiles.find(indexFileName) == cleanIndexFiles.end()) {
-        truncate_index_file(indexFileName);
-        cleanIndexFiles.insert(indexFileName);
-    }
-
-    // write out airport object reference
-    write_index_object(objpath, b, name);
-
-#if 0 // TODO : along with taxiway signs
-    // write out tower references
-    for ( i = 0; i < (int)tower_nodes.size(); ++i )
-    {
-        write_index_object_shared( objpath, b, tower_nodes[i],
-                                  "Models/Airport/tower.xml",
-                                  0.0 );
-    }
-#endif
-
-    // calc elevations and write out windsock references
-    TG_LOG(SG_GENERAL, SG_DEBUG, "Computing windsock node elevations");
-
-    for (unsigned int i = 0; i < windsocks.size(); ++i) {
-        SGGeod ref_geod = windsocks[i]->GetLoc();
-        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
-
-        if (windsocks[i]->IsLit()) {
-            write_index_object_shared(objpath, b, ref_geod,
-                                      "Models/Airport/windsock_lit.xml", 0.0);
-        } else {
-            write_index_object_shared(objpath, b, ref_geod,
-                                      "Models/Airport/windsock.xml", 0.0);
-        }
-    }
-
-    // write out beacon references
-    for (unsigned int i = 0; i < beacons.size(); ++i) {
-        SGGeod ref_geod = beacons[i]->GetLoc();
-        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
-
-        write_index_object_shared(objpath, b, ref_geod,
-                                  "Models/Airport/beacon.xml",
-                                  0.0);
-    }
-
-    // write out taxiway signs references
-    for (unsigned int i = 0; i < signs.size(); ++i) {
-        SGGeod ref_geod = signs[i]->GetLoc();
-        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
-        write_index_object_sign(objpath, b, ref_geod,
-                                signs[i]->GetDefinition(),
-                                signs[i]->GetHeading(),
-                                signs[i]->GetSize());
-    }
-
-    // write out water buoys
-    for (unsigned int i = 0; i < waterrunways.size(); ++i) {
-        tgContour buoys = waterrunways[i]->GetBuoys();
-
-        for (unsigned int j = 0; j < buoys.GetSize(); ++j) {
-            SGGeod ref_geod = buoys.GetNode(j);
-            ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
-            write_index_object_shared(objpath, b, ref_geod,
-                                      "Models/Airport/water_rw_buoy.xml",
-                                      0.0);
-        }
-    }
-
-    std::string holepath = root + "/AirportArea";
-    tgChopper chopper(holepath);
-
-    divided_base.SetPreserve3D(true);
-    apt_clearing.SetPreserve3D(false);
-    apt_clearing.SetTexMethod(TG_TEX_BY_GEODE);
-
-    chopper.Add(divided_base, "Hole");
-    chopper.Add(apt_clearing, "Airport");
-    chopper.Save(false);
-}
-
-bool Airport::CheckZFightingTriangles(const char* prefix, const char* debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys)
-{
-    char layer[128];
-    char desc[128];
-
-    snprintf(layer, 128, "z-fighting_%s", prefix);
-    double min_area_thresh = 1.0e-10;
-
-    bool zfighting = false;
-
-    if (rwy_polys.size()) {
-        for (unsigned int i = 0; i < rwy_polys.size(); ++i) {
-            tgPolygon subject = rwy_polys[i];
-            for (unsigned int j = 0; j < subject.Triangles(); ++j) {
-                tgTriangle subTri = subject.GetTriangle(j);
-                tgRectangle subBB = subTri.GetBoundingBox();
-
-                for (unsigned int k = 0; k < pvmt_polys.size(); ++k) {
-                    tgPolygon test = pvmt_polys[k];
-                    for (unsigned int l = 0; l < test.Triangles(); ++l) {
-                        tgTriangle testTri = test.GetTriangle(l);
-                        tgRectangle testBB = testTri.GetBoundingBox();
-
-                        if (subBB.intersects(testBB)) {
-                            // find the intersection
-                            tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
-
-                            for (unsigned int m = 0; m < intersection.Contours(); m++) {
-                                tgContour intContour = intersection.GetContour(m);
-                                if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
-                                    TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between runway poly " << i << " and pavement poly " << k << " contour has " << intContour.GetSize() << " nodes "
-                                                                        << " area is " << intContour.GetArea());
-                                    sprintf(desc, "rwy_%06u_pvmt_%06u", i, j);
-                                    tgShapefile::FromContour(intContour, debug_root, layer, desc);
-                                    zfighting = true;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // intersect each pavement poly with each pavement, runway, and base poly
-    if (pvmt_polys.size()) {
-        for (unsigned int i = 0; i < pvmt_polys.size(); ++i) {
-            tgPolygon subject = pvmt_polys[i];
-            for (unsigned int j = 0; j < subject.Triangles(); ++j) {
-                tgTriangle subTri = subject.GetTriangle(j);
-                tgRectangle subBB = subTri.GetBoundingBox();
-
-                for (unsigned int k = 0; k < rwy_polys.size(); ++k) {
-                    tgPolygon test = rwy_polys[k];
-                    for (unsigned int l = 0; l < test.Triangles(); ++l) {
-                        tgTriangle testTri = test.GetTriangle(l);
-                        tgRectangle testBB = testTri.GetBoundingBox();
-
-                        if (subBB.intersects(testBB)) {
-                            // find the intersection
-                            tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
-
-                            for (unsigned int m = 0; m < intersection.Contours(); m++) {
-                                tgContour intContour = intersection.GetContour(m);
-                                if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
-                                    TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between pavement poly " << i << " and runway poly " << k << " contour has " << intContour.GetSize() << " nodes "
-                                                                        << " area is " << intContour.GetArea());
-                                    sprintf(desc, "pvmt_%06u_rwy_%06u", i, j);
-                                    tgShapefile::FromContour(intContour, debug_root, layer, desc);
-                                    zfighting = true;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // intersect base poly with each runway and pavement poly
-    tgPolygon subject = base_poly;
-
-    for (unsigned int i = 0; i < subject.Triangles(); ++i) {
-        tgTriangle subTri = subject.GetTriangle(i);
-        tgRectangle subBB = subTri.GetBoundingBox();
-
-        for (unsigned int j = 0; j < rwy_polys.size(); ++j) {
-            tgPolygon test = rwy_polys[j];
-            for (unsigned int k = 0; k < test.Triangles(); ++k) {
-                tgTriangle testTri = test.GetTriangle(k);
-                tgRectangle testBB = testTri.GetBoundingBox();
-
-                if (subBB.intersects(testBB)) {
-                    // find the intersection
-                    tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
-
-                    for (unsigned int m = 0; m < intersection.Contours(); m++) {
-                        tgContour intContour = intersection.GetContour(m);
-                        if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
-                            TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and runway poly " << j << " contour has " << intContour.GetSize() << " nodes "
-                                                                << " area is " << intContour.GetArea());
-                            sprintf(desc, "base_rwy_%06u", j);
-                            tgShapefile::FromContour(intContour, debug_root, layer, desc);
-                            zfighting = true;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    for (unsigned int i = 0; i < subject.Triangles(); ++i) {
-        tgTriangle subTri = subject.GetTriangle(i);
-        tgRectangle subBB = subTri.GetBoundingBox();
-
-        for (unsigned int j = 0; j < pvmt_polys.size(); ++j) {
-            tgPolygon test = pvmt_polys[j];
-            for (unsigned int k = 0; k < test.Triangles(); ++k) {
-                tgTriangle testTri = test.GetTriangle(k);
-                tgRectangle testBB = testTri.GetBoundingBox();
-
-                if (subBB.intersects(testBB)) {
-                    // find the intersection
-                    tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
-
-                    for (unsigned int m = 0; m < intersection.Contours(); m++) {
-                        tgContour intContour = intersection.GetContour(m);
-                        if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
-                            TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and pavement poly " << j << " contour has " << intContour.GetSize() << " nodes "
-                                                                << " area is " << intContour.GetArea());
-                            sprintf(desc, "base_pvmt_%06u", j);
-                            tgShapefile::FromContour(intContour, debug_root, layer, desc);
-                            zfighting = true;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    return zfighting;
-}
\ No newline at end of file
+#include <string>
+
+#include <simgear/bucket/newbucket.hxx>
+#include <simgear/compiler.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/io/sg_binobj.hxx>
+#include <simgear/math/SGGeometry.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/misc/texcoord.hxx>
+#include <simgear/structure/exception.hxx>
+
+#include <terragear/tg_chopper.hxx>
+#include <terragear/tg_polygon.hxx>
+#include <terragear/tg_shapefile.hxx>
+#include <terragear/tg_unique_geod.hxx>
+#include <terragear/tg_unique_vec2f.hxx>
+#include <terragear/tg_unique_vec3f.hxx>
+
+#include "airport.hxx"
+#include "beznode.hxx"
+#include "debug.hxx"
+#include "elevations.hxx"
+#include "global.hxx"
+#include "helipad.hxx"
+#include "output.hxx"
+#include "runway.hxx"
+
+
+Airport::Airport(int c, char* def)
+{
+    int numParams;
+    char* tok;
+
+    code = c;
+
+    // we need to tokenize airports, since we can't scanf two strings next to each other...
+    numParams = 0;
+    bool done = false;
+
+    while (!done) {
+        // trim leading whitespace
+        while (isspace(*def)) def++;
+
+        tok = strtok(def, " \t\r\n");
+
+        if (tok) {
+            def += strlen(tok) + 1;
+
+            switch (numParams) {
+            case 0:
+                // airport elevation (feet MSL)
+                altitude = atoi(tok);
+                break;
+
+            case 1:
+                // Airport has a control tower (1=yes, 0=no)
+                // deprecated v10.00
+                break;
+
+            case 2:
+                // default airport buildings (1=yes, 0=no)
+                // deprecated v8.50
+                break;
+
+            case 3:
+                // ICAO code (FAA code when ICAO doesn't exist)
+                icao = tok;
+                // tok-4 = airport name
+                description = def;
+                done = true;
+                break;
+            }
+        }
+        numParams++;
+    }
+
+    altitude *= SG_FEET_TO_METER;
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Read airport with icao " << icao << ", and description " << description);
+}
+
+Airport::~Airport()
+{
+    std::fill(features.begin(), features.end(), nullptr);
+    std::fill(helipads.begin(), helipads.end(), nullptr);
+    std::fill(runways.begin(), runways.end(), nullptr);
+    std::fill(waterRunways.begin(), waterRunways.end(), nullptr);
+    std::fill(pavements.begin(), pavements.end(), nullptr);
+    std::fill(taxiways.begin(), taxiways.end(), nullptr);
+    std::fill(lightObjects.begin(), lightObjects.end(), nullptr);
+    std::fill(windsocks.begin(), windsocks.end(), nullptr);
+    std::fill(beacons.begin(), beacons.end(), nullptr);
+    std::fill(signs.begin(), signs.end(), nullptr);
+    std::fill(boundaries.begin(), boundaries.end(), nullptr);
+}
+
+bool Airport::isDebugRunway(int idxRunway) const
+{
+    bool dbg = false;
+
+    debug_map_const_iterator it = debug_runways.find(icao);
+    if (it == debug_runways.end())
+        return dbg;
+
+    for (unsigned int i = 0; i < it->second.size() && !dbg; ++i) {
+        if (it->second[i] == std::numeric_limits<int>::max())
+            dbg = true;
+        else if (it->second[i] == idxRunway + 1)
+            dbg = true;
+    }
+
+    return dbg;
+}
+
+bool Airport::isDebugPavement(int idxPavement) const
+{
+    bool dbg = false;
+
+    debug_map_const_iterator it = debug_pavements.find(icao);
+    if (it != debug_pavements.end()) {
+        for (unsigned int i = 0; i < it->second.size() && !dbg; ++i) {
+            if (it->second[i] == std::numeric_limits<int>::max())
+                dbg = true;
+            else if (it->second[i] == idxPavement + 1)
+                dbg = true;
+        }
+    }
+
+    return dbg;
+}
+
+bool Airport::isDebugTaxiway(int taxi) const
+{
+    bool dbg = false;
+
+    debug_map_const_iterator it = debug_taxiways.find(icao);
+    if (it != debug_taxiways.end()) {
+        for (unsigned int i = 0; i < it->second.size() && !dbg; ++i) {
+            if (it->second[i] == std::numeric_limits<int>::max())
+                dbg = true;
+            else if (it->second[i] == taxi + 1)
+                dbg = true;
+        }
+    }
+
+    return dbg;
+}
+
+bool Airport::isDebugFeature(int feat) const
+{
+    bool dbg = false;
+
+    debug_map_const_iterator it = debug_features.find(icao);
+    if (it != debug_features.end()) {
+        for (unsigned int i = 0; i < it->second.size() && !dbg; ++i) {
+            if (it->second[i] == std::numeric_limits<int>::max())
+                dbg = true;
+            else if (it->second[i] == feat + 1)
+                dbg = true;
+        }
+    }
+
+    return dbg;
+}
+
+void Airport::BuildBtg(const std::string& root, const string_list& elev_src)
+{
+    using namespace std::string_literals;
+
+    tgcontour_list slivers;
+    tgcontour_list line_slivers;
+
+    tgpolygon_list apt_base_polys;
+    tgpolygon_list apt_clearing_polys;
+    tgpolygon_list rwy_polys;
+    tgpolygon_list pvmt_polys;
+    tgpolygon_list line_polys;
+
+    tglightcontour_list rwy_lights;
+
+    std::string debug_root {"./airport_dbf/"s + icao + "/"s};
+
+    // parse main airport information
+    double apt_lon = 0.0, apt_lat = 0.0;
+
+    SGTimeStamp build_start;
+    SGTimeStamp build_end;
+    SGTimeStamp cleanup_start;
+    SGTimeStamp cleanup_end;
+    SGTimeStamp triangulation_start;
+    SGTimeStamp triangulation_end;
+    time_t log_time;
+
+    std::string shapefile_name {};
+    std::string shapefile {};
+
+    // Find the average of all the runway and heliport long / lats
+    int num_samples = 0;
+    for (auto& runway : runways) {
+        apt_lon += runway->GetMidpoint().getLongitudeDeg();
+        apt_lat += runway->GetMidpoint().getLatitudeDeg();
+        num_samples++;
+    }
+
+    for (auto& helipad : helipads) {
+        apt_lon += helipad->GetLoc().getLongitudeDeg();
+        apt_lat += helipad->GetLoc().getLatitudeDeg();
+        num_samples++;+    }
+
+    apt_lon = apt_lon / (double)num_samples;
+    apt_lat = apt_lat / (double)num_samples;
+
+    SGBucket b(SGGeod::fromDeg(apt_lon, apt_lat));
+    TG_LOG(SG_GENERAL, SG_DEBUG, b.gen_base_path() << "/" << b.gen_index_str());
+
+    // If we are cutting in the linear features, add them first
+    if (pavements.size()) {
+        for (auto& pavement : pavements) {
+            AddFeatures(pavement->GetFeatures());
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Parse Complete - Runways: " << runways.size() <<
+                                " Pavements: " << pavements.size() <<
+                                " Features: " << features.size() <<
+                                " Taxiways: " << taxiways.size());
+
+    // Starting to clip the polys (for now - only UNIX builds)
+    build_start.stamp();
+
+    // Add the linear features
+    if (features.size()) {
+        tgAccumulator lf_accum(icao);
+
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << features.size() << " Linear Feature Polys");
+
+        unsigned i = 0;
+        bool make_shapefiles = false;
+        for (auto& feature : features) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << ++i << " of " << features.size() << " : " << feature->GetDescription());
+
+            feature->BuildBtg(line_polys, rwy_lights, lf_accum, make_shapefiles);
+        }
+
+        log_time = time(0);
+        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << DebugTimeToString(log_time));
+    }
+
+    /* Initialize a new accumulator for the other objects */
+    tgAccumulator pvmt_accum(icao);
+
+    // Build runways next
+    if (runways.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Polys");
+
+        unsigned i = 0;
+        for (auto& runway : runways) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i+1 << " of " << runways.size());
+
+            if (isDebugRunway(i))
+                shapefile_name = "runway_"s + std::to_string(i);
+            else
+                shapefile_name = ""s;
+            shapefile = shapefile_name;
+
+            if (boundaries.size())
+                runway->BuildBtg(rwy_polys, rwy_lights, slivers, pvmt_accum, shapefile);
+            else
+                runway->BuildBtg(rwy_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
+            ++i;
+        }
+
+        log_time = time(0);
+        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << DebugTimeToString(log_time));
+    }
+
+    if (lightObjects.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << lightObjects.size() << " Light Objects ");
+
+        unsigned i = 0;
+        for (auto& light : lightObjects) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build runway light " << ++i << " of " << lightObjects.size());
+
+            light->BuildBtg(rwy_lights);
+        }
+    }
+
+    // Build helipads (use runway poly- and texture list for this)
+    if (helipads.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << helipads.size() << " Helipad Polys ");
+
+        unsigned i = 0;
+        for (auto& helipad : helipads) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << ++i << " of " << helipads.size());
+
+            if (boundaries.size())
+                helipad->BuildBtg(rwy_polys, rwy_lights, slivers, pvmt_accum);
+            else
+                helipad->BuildBtg(rwy_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum);
+        }
+    }
+
+    // Build the pavements
+    if (pavements.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << pavements.size() << " Pavement Polys ");
+
+        unsigned i = 0;
+        for (auto& pavement : pavements) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i+1 << " of " << pavements.size() << " : " << pavement->GetDescription());
+
+            if (isDebugPavement(i))
+                shapefile_name = "pvmnt_"s + std::to_string(i);
+            else
+                shapefile_name = ""s;
+            shapefile = shapefile_name;
+
+            if (boundaries.size())
+                pavement->BuildBtg(pvmt_polys, slivers, pvmt_accum, shapefile);
+            else
+                pavement->BuildBtg(pvmt_polys, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
+            ++i;
+        }
+
+        log_time = time(0);
+        TG_LOG(SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << DebugTimeToString(log_time));
+    }
+
+    // Build the legacy taxiways
+    if (taxiways.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << taxiways.size() << " Taxiway Polys ");
+
+        unsigned i = 0;
+        for (auto& taxiway : taxiways) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Taxiway " << i+1 << " of " << taxiways.size());
+
+            if (isDebugTaxiway(i))
+                shapefile_name = "taxiway_"s + std::to_string(i);
+            else
+                shapefile_name = ""s;
+            shapefile = shapefile_name;
+
+            if (boundaries.size())
+                taxiway->BuildBtg(pvmt_polys, rwy_lights, slivers, pvmt_accum, shapefile);
+            else
+                taxiway->BuildBtg(pvmt_polys, rwy_lights, slivers, apt_base_polys, apt_clearing_polys, pvmt_accum, shapefile);
+            ++i;
+        }
+    }
+
+    // Build runway shoulders here
+    if (runways.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Shoulder Polys ");
+
+        unsigned i = 0;
+        for (auto& runway : runways) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << ++i << " of " << runways.size());
+
+            if (runway->GetsShoulder())
+                runway->BuildShoulder(rwy_polys, slivers, pvmt_accum);
+        }
+    }
+
+    // Build helipad shoulders here
+    if (helipads.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Helipad Shoulder Polys ");
+
+        unsigned i = 0;
+        for (auto& helipad : helipads) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build Helipad shoulder " << ++i << " of " << helipads.size());
+
+            if (helipad->GetsShoulder())
+                helipad->BuildShoulder(rwy_polys, slivers, pvmt_accum);
+        }
+    }
+
+    // build the base and clearing if there's a boundary
+    tgPolygon apt_base, apt_clearing;
+    if (boundaries.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Build " << boundaries.size() << " Boundary Polys ");
+
+        shapefile = ""s;
+        unsigned i = 0;
+        for (auto& boundary : boundaries) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Build user-defined boundary " << ++i << " of " << boundaries.size());
+
+            boundary->BuildBtg(apt_base, apt_clearing, shapefile);
+        }
+    } else {
+        apt_base = tgPolygon::Union(apt_base_polys);
+        apt_clearing = tgPolygon::Union(apt_clearing_polys);
+    }
+
+    if (apt_base.TotalNodes() == 0) {
+        TG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
+        return;
+    }
+
+    tgPolygon filled_base = tgPolygon::StripHoles(apt_base);
+    tgPolygon divided_base = tgPolygon::SplitLongEdges(filled_base, 200.0);
+    tgPolygon base_poly = pvmt_accum.Diff(divided_base);
+
+    build_end.stamp();
+    build_time = build_end - build_start;
+
+    cleanup_start.stamp();
+
+    // add segments to polygons to remove any possible "T" intersections
+    UniqueSGGeodSet tmp_pvmt_nodes;
+    UniqueSGGeodSet tmp_feat_nodes;
+
+    // build temporary node list from runways...
+    TG_LOG(SG_GENERAL, SG_INFO, "Build Node List ");
+
+    for (tgPolygon poly : rwy_polys) {
+        for (unsigned int i = 0; i < poly.Contours(); ++i) {
+            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
+                tmp_pvmt_nodes.add(poly.GetNode(i, j));
+            }
+        }
+    }
+
+    // and pavements
+    for (tgPolygon poly : pvmt_polys) {
+        for (unsigned int i = 0; i < poly.Contours(); ++i) {
+            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
+                tmp_pvmt_nodes.add(poly.GetNode(i, j));
+            }
+        }
+    }
+
+    // and linear features (keep linear feature nodes separate)
+    for (tgPolygon poly : line_polys) {
+        for (unsigned int i = 0; i < poly.Contours(); ++i) {
+            for (unsigned int j = 0; j < poly.ContourSize(i); ++j) {
+                tmp_feat_nodes.add(poly.GetNode(i, j));
+            }
+        }
+    }
+
+    // and the base
+    for (unsigned int i = 0; i < base_poly.Contours(); ++i) {
+        for (unsigned int j = 0; j < base_poly.ContourSize(i); ++j) {
+            tmp_pvmt_nodes.add(base_poly.GetNode(i, j));
+        }
+    }
+
+    // the divided base could contain points not found in base_poly,
+    // so we should add them because the skirt needs them.
+    for (unsigned int i = 0; i < divided_base.Contours(); ++i) {
+        for (unsigned int j = 0; j < divided_base.ContourSize(i); ++j) {
+            tmp_pvmt_nodes.add(divided_base.GetNode(i, j));
+        }
+    }
+
+    log_time = time(0);
+    TG_LOG(SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << DebugTimeToString(log_time));
+
+    // second pass : runways
+    for (tgPolygon poly : rwy_polys) {
+        poly = tgPolygon::AddColinearNodes(poly, tmp_pvmt_nodes);
+
+        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
+    }
+
+    // second pass : and pavements
+    for (tgPolygon poly : pvmt_polys) {
+        poly = tgPolygon::AddColinearNodes(poly, tmp_pvmt_nodes);
+
+        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
+    }
+
+    // second pass : and lines
+    for (tgPolygon poly : line_polys) {
+        poly = tgPolygon::AddColinearNodes(poly, tmp_feat_nodes);
+
+        TG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.TotalNodes());
+    }
+
+    log_time = time(0);
+    TG_LOG(SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << DebugTimeToString(log_time));
+
+    unsigned k = 0;
+    for (tgPolygon poly : line_polys) {
+        poly = tgPolygon::RemoveCycles(poly);
+        poly = tgPolygon::RemoveDups(poly);
+        poly = tgPolygon::RemoveBadContours(poly);
+
+        line_polys[k++] = poly;
+    }
+
+    log_time = time(0);
+    TG_LOG(SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << DebugTimeToString(log_time));
+
+    base_poly = tgPolygon::AddColinearNodes(base_poly, tmp_pvmt_nodes);
+
+    cleanup_end.stamp();
+    cleanup_time = cleanup_end - cleanup_start;
+
+    // before tessellating the base, make sure there are no intersecting contours
+    base_poly = tgPolygon::Simplify(base_poly);
+
+    triangulation_start.stamp();
+
+    // tesselate the polygons and prepare them for final output
+    if (rwy_polys.size()) {
+        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << rwy_polys.size() << " Runway Polys ");
+
+        for (unsigned int i = 0; i < rwy_polys.size(); ++i) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating runway poly = " << i + 1 << " of " << rwy_polys.size());
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes());
+            rwy_polys[i].Tesselate();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
+            rwy_polys[i].Texture();
+        }
+    }
+
+    if (pvmt_polys.size()) {
+        // tesselate the polygons and prepare them for final output
+        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << pvmt_polys.size() << " Pavement Polys ");
+
+        for (unsigned int i = 0; i < pvmt_polys.size(); ++i) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating pavement poly = " << i + 1 << " of " << pvmt_polys.size());
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes());
+            pvmt_polys[i].Tesselate();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles());
+            pvmt_polys[i].Texture();
+        }
+    }
+
+    if (line_polys.size()) {
+        // tesselate the polygons and prepare them for final output
+        TG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << line_polys.size() << " Linear Feature Polys ");
+
+        for (unsigned int i = 0; i < line_polys.size(); ++i) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating line poly = " << i + 1 << " of " << line_polys.size());
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes());
+            line_polys[i].Tesselate();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles());
+            line_polys[i].Texture();
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly : " << base_poly.Contours() << " contours ");
+    base_poly.Tesselate();
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done : Triangles = " << base_poly.Triangles());
+
+    // should we texture base here?
+    base_poly.SetTexMethod(TG_TEX_BY_GEODE, b.get_center_lat());
+    base_poly.Texture();
+
+    triangulation_end.stamp();
+
+    // a few airports fail here
+    if (base_poly.Triangles() == 0) {
+        TG_LOG(SG_GENERAL, SG_ALERT, "no base poly triangles");
+        return;
+    }
+
+    triangulation_time = triangulation_end - triangulation_start;
+
+    //
+    // We should now have the runway polygons all generated with their
+    // corresponding triangles and texture coordinates, and the
+    // surrounding base area.
+    //
+    // Next we need to create the output lists ... vertices, normals,
+    // texture coordinates, and tri-strips
+    //
+
+    // traverse the tri list and create ordered node and texture
+    // coordinate lists
+    // start with just nodes
+    SGBinObject obj;
+    SGBinObjectTriangle sgboTri;
+    SGBinObjectPoint sgboPt;
+
+    UniqueSGGeodSet nodes;
+    UniqueSGVec3fSet normals;
+    UniqueSGVec2fSet texcoords;
+
+    group_list pts_v;
+    pts_v.clear();
+    group_list pts_n;
+    pts_n.clear();
+    string_list pt_materials;
+    pt_materials.clear();
+
+    group_list tris_v;
+    tris_v.clear();
+    group_list tris_n;
+    tris_n.clear();
+    group_list tris_tc;
+    tris_tc.clear();
+    string_list tri_materials;
+    tri_materials.clear();
+
+    group_list strips_v;
+    strips_v.clear();
+    group_list strips_n;
+    strips_n.clear();
+    group_list strips_tc;
+    strips_tc.clear();
+    string_list strip_materials;
+    strip_materials.clear();
+
+    int_list pt_v, tri_v, strip_v;
+    int_list pt_n, tri_n, strip_n;
+    int_list tri_tc, strip_tc;
+
+    // calculate "the" normal for this airport
+    SGVec3f vnt = SGVec3f::fromGeod(base_poly.GetNode(0, 0));
+    vnt = normalize(vnt);
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Adding runway nodes and normals");
+    {
+        unsigned k = 0;
+        for (tgPolygon poly : rwy_polys) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k++);
+
+            std::string material = poly.GetMaterial();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << poly.Triangles());
+
+            for (unsigned int i = 0; i < poly.Triangles(); ++i) {
+                sgboTri.clear();
+                sgboTri.material = material;
+
+                for (int l = 0; l < 3; ++l) {
+                    int index = nodes.add(poly.GetTriNode(i, l));
+                    sgboTri.v_list.push_back(index);
+
+                    // use 'the' normal
+                    index = normals.add(vnt);
+                    sgboTri.n_list.push_back(index);
+
+                    index = texcoords.add(poly.GetTriTexCoord(i, l));
+                    sgboTri.tc_list[0].push_back(index);
+                }
+
+                obj.add_triangle(sgboTri);
+            }
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Adding pavement nodes and normals");
+    {
+        unsigned k = 0;
+        for (tgPolygon poly : pvmt_polys) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k++);
+
+            std::string material = poly.GetMaterial();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << poly.Triangles());
+
+            for (unsigned int i = 0; i < poly.Triangles(); ++i) {
+                sgboTri.clear();
+                sgboTri.material = material;
+
+                for (int l = 0; l < 3; ++l) {
+                    int index = nodes.add(poly.GetTriNode(i, l));
+                    sgboTri.v_list.push_back(index);
+
+                    // use 'the' normal
+                    index = normals.add(vnt);
+                    sgboTri.n_list.push_back(index);
+
+                    index = texcoords.add(poly.GetTriTexCoord(i, l));
+                    sgboTri.tc_list[0].push_back(index);
+                }
+
+                obj.add_triangle(sgboTri);
+            }
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Adding line nodes and normals");
+    {
+        unsigned k = 0;
+        for (tgPolygon poly : line_polys) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k++);
+
+            std::string material = poly.GetMaterial();
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
+            TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << poly.Triangles());
+
+            for (unsigned int i = 0; i < poly.Triangles(); ++i) {
+                sgboTri.clear();
+                sgboTri.material = material;
+
+                for (int l = 0; l < 3; ++l) {
+                    int index = nodes.add(poly.GetTriNode(i, l));
+                    sgboTri.v_list.push_back(index);
+
+                    // use 'the' normal
+                    index = normals.add(vnt);
+                    sgboTri.n_list.push_back(index);
+
+                    index = texcoords.add(poly.GetTriTexCoord(i, l));
+                    sgboTri.tc_list[0].push_back(index);
+                }
+
+                obj.add_triangle(sgboTri);
+            }
+        }
+    }
+
+    // add base points
+    TG_LOG(SG_GENERAL, SG_INFO, "Adding base triangles");
+
+    std::string material = "Grass";
+    for (unsigned int k = 0; k < base_poly.Triangles(); ++k) {
+        sgboTri.clear();
+        sgboTri.material = material;
+
+        for (int l = 0; l < 3; ++l) {
+            int index = nodes.add(base_poly.GetTriNode(k, l));
+            sgboTri.v_list.push_back(index);
+
+            // use 'the' normal
+            index = normals.add(vnt);
+            sgboTri.n_list.push_back(index);
+
+            index = texcoords.add(base_poly.GetTriTexCoord(k, l));
+            sgboTri.tc_list[0].push_back(index);
+        }
+
+        obj.add_triangle(sgboTri);
+    }
+
+    // on rare occasion, one or more of the divided base points can be
+    // missed.  Make sure they are all in the node list so we can
+    // build a proper skirt.
+    for (unsigned int i = 0; i < divided_base.Contours(); ++i) {
+        for (unsigned int j = 0; j < divided_base.ContourSize(i); ++j) {
+            int index = nodes.add(divided_base.GetNode(i, j));
+
+            TG_LOG(SG_GENERAL, SG_DEBUG, "added base point " << divided_base.GetNode(i, j) << " at " << index);
+        }
+    }
+
+    // Now that we have assembled all the airport geometry nodes into
+    // a list, calculate an "average" airport elevation based on all
+    // the actual airport node points.  This is more useful than
+    // calculating an average over the entire airport surface because
+    // it avoids biases introduced from the surrounding area if the
+    // airport is located in a bowl or on a hill.
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, " calc average elevation");
+    {
+        std::vector<SGGeod> dbg = nodes.get_list();
+
+        // dump the node list
+        TG_LOG(SG_GENERAL, SG_DEBUG, " node list size is " << dbg.size());
+
+        for (unsigned int w = 0; w < dbg.size(); w++) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, " node " << w << " is " << dbg[w]);
+        }
+    }
+
+    double average = tgAverageElevation(root, elev_src, nodes.get_list());
+
+    // Now build the fitted airport surface ...
+
+    // calculation min/max coordinates of airport area
+    TG_LOG(SG_GENERAL, SG_DEBUG, " calculation min/max coordinates of airport area");
+
+    SGGeod min_deg = SGGeod::fromDeg(9999.0, 9999.0);
+    SGGeod max_deg = SGGeod::fromDeg(-9999.0, -9999.0);
+
+    for (unsigned int j = 0; j < nodes.get_list().size(); ++j) {
+        SGGeod p = nodes.get_list()[j];
+
+        if (p.getLongitudeDeg() < min_deg.getLongitudeDeg()) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "new min lon from node " << j << " is " << p.getLongitudeDeg());
+            min_deg.setLongitudeDeg(p.getLongitudeDeg());
+        }
+
+        if (p.getLongitudeDeg() > max_deg.getLongitudeDeg()) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "new max lon from node " << j << " is " << p.getLongitudeDeg());
+            max_deg.setLongitudeDeg(p.getLongitudeDeg());
+        }
+
+        if (p.getLatitudeDeg() < min_deg.getLatitudeDeg()) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "new min lat from node " << j << " is " << p.getLatitudeDeg());
+            min_deg.setLatitudeDeg(p.getLatitudeDeg());
+        }
+
+        if (p.getLatitudeDeg() > max_deg.getLatitudeDeg()) {
+            TG_LOG(SG_GENERAL, SG_DEBUG, "new max lat from node " << j << " is " << p.getLatitudeDeg());
+            max_deg.setLatitudeDeg(p.getLatitudeDeg());
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Before extending for lights: min = " << min_deg << " max = " << max_deg);
+
+    // extend the min/max coordinates of airport area to cover all lights as well
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : num rwy lights is " << rwy_lights.size());
+
+    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
+        TG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : rwy light " << i << "has " << rwy_lights[i].ContourSize() << " lights ");
+
+        for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); ++j) {
+            SGGeod p = rwy_lights[i].GetNode(j);
+
+            if (p.getLongitudeDeg() < min_deg.getLongitudeDeg()) {
+                min_deg.setLongitudeDeg(p.getLongitudeDeg());
+            }
+
+            if (p.getLongitudeDeg() > max_deg.getLongitudeDeg()) {
+                max_deg.setLongitudeDeg(p.getLongitudeDeg());
+            }
+
+            if (p.getLatitudeDeg() < min_deg.getLatitudeDeg()) {
+                min_deg.setLatitudeDeg(p.getLatitudeDeg());
+            }
+
+            if (p.getLatitudeDeg() > max_deg.getLatitudeDeg()) {
+                max_deg.setLatitudeDeg(p.getLatitudeDeg());
+            }
+        }
+    }
+
+    // Extend the area a bit so we don't have weird things on the edges
+    double dlon = max_deg.getLongitudeDeg() - min_deg.getLongitudeDeg();
+    double dlat = max_deg.getLatitudeDeg() - min_deg.getLatitudeDeg();
+    min_deg.setLongitudeDeg(min_deg.getLongitudeDeg() - 0.01 * dlon);
+    max_deg.setLongitudeDeg(max_deg.getLongitudeDeg() + 0.01 * dlon);
+    min_deg.setLatitudeDeg(min_deg.getLatitudeDeg() - 0.01 * dlat);
+    max_deg.setLatitudeDeg(max_deg.getLatitudeDeg() + 0.01 * dlat);
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, "min = " << min_deg << " max = " << max_deg);
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Create Apt surface:");
+    TG_LOG(SG_GENERAL, SG_DEBUG, " root: " << root);
+    TG_LOG(SG_GENERAL, SG_DEBUG, " min: " << min_deg);
+    TG_LOG(SG_GENERAL, SG_DEBUG, " max: " << max_deg);
+    TG_LOG(SG_GENERAL, SG_DEBUG, " average: " << average);
+
+    tgRectangle aptBounds(min_deg, max_deg);
+    tgSurface apt_surf(root, elev_src, aptBounds, average, slope_max, slope_eps);
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
+
+    // add light points
+    // pass one, calculate raw elevations from Array
+    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
+        for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); j++) {
+            double light_elevation = apt_surf.calc_elevation(rwy_lights[i].GetNode(j), 0.0);
+            rwy_lights[i].SetElevation(j, light_elevation);
+        }
+    }
+
+    TG_LOG(SG_GENERAL, SG_INFO, "Done with lighting calc_elevations() num light polys is " << rwy_lights.size());
+
+    // pass two, for each light group check if we need to lift (based
+    // on flag) and do so, then output next structures.
+    // for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
+    for (unsigned int i = 0; i < rwy_lights.size(); ++i) {
+        if (rwy_lights[i].ContourSize()) {
+            sgboPt.clear();
+            sgboPt.material = rwy_lights[i].GetType();
+
+            for (unsigned int j = 0; j < rwy_lights[i].ContourSize(); ++j) {
+                int index = nodes.add(rwy_lights[i].GetPosition(j));
+                sgboPt.v_list.push_back(index);
+
+                index = normals.add(rwy_lights[i].GetNormal(j));
+                sgboPt.n_list.push_back(index);
+            }
+
+            obj.add_point(sgboPt);
+        }
+    }
+
+    // calculate node elevations
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Computing airport node elevations");
+
+    std::vector<SGGeod> geod_nodes = apt_surf.calc_elevations(nodes.get_list(), 0.0);
+    divided_base = apt_surf.calc_elevations(divided_base, 0.0);
+
+    // calculate wgs84 mapping of nodes
+    std::vector<SGVec3d> wgs84_nodes;
+    for (unsigned int i = 0; i < geod_nodes.size(); ++i) {
+        wgs84_nodes.push_back(SGVec3d::fromGeod(geod_nodes[i]));
+    }
+
+    SGVec3d gbs_center = SGVec3d::fromGeod(b.get_center());
+    double radius_squared = 0;
+    for (unsigned int i = 0; i < wgs84_nodes.size(); ++i) {
+        double dist_squared = distSqr(gbs_center, wgs84_nodes[i]);
+        if (dist_squared > radius_squared) {
+            radius_squared = dist_squared;
+        }
+    }
+
+    double gbs_radius = sqrt(radius_squared);
+
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Done with wgs84 node mapping");
+    TG_LOG(SG_GENERAL, SG_DEBUG, "  center = " << gbs_center << " radius = " << gbs_radius);
+
+    // null structures
+    std::string objpath = root + "/AirportObj"s;
+    std::string name = icao + ".btg"s;
+
+    obj.set_gbs_center(gbs_center);
+    obj.set_gbs_radius(gbs_radius);
+    obj.set_wgs84_nodes(wgs84_nodes);
+    obj.set_normals(normals.get_list());
+    obj.set_texcoords(texcoords.get_list());
+
+    bool result;
+    result = obj.write_bin(objpath, name, b);
+    if (!result) {
+        throw sg_exception("error writing file. :-(");
+    }
+
+    std::string indexFileName = objpath + "/"s + b.gen_base_path() + "/"s + b.gen_index_str() + ".ind"s;
+    if (cleanIndexFiles.find(indexFileName) == cleanIndexFiles.end()) {
+        truncate_index_file(indexFileName);
+        cleanIndexFiles.insert(indexFileName);
+    }
+
+    // write out airport object reference
+    write_index_object(objpath, b, name);
+
+    // calc elevations and write out windsock references
+    TG_LOG(SG_GENERAL, SG_DEBUG, "Computing windsock node elevations");
+
+    for (unsigned int i = 0; i < windsocks.size(); ++i) {
+        SGGeod ref_geod = windsocks[i]->GetLoc();
+        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
+
+        if (windsocks[i]->IsLit()) {
+            write_index_object_shared(objpath, b, ref_geod,
+                                      "Models/Airport/windsock_lit.xml", 0.0);
+        } else {
+            write_index_object_shared(objpath, b, ref_geod,
+                                      "Models/Airport/windsock.xml", 0.0);
+        }
+    }
+
+    // write out beacon references
+    for (unsigned int i = 0; i < beacons.size(); ++i) {
+        SGGeod ref_geod = beacons[i]->GetLoc();
+        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
+
+        write_index_object_shared(objpath, b, ref_geod,
+                                  "Models/Airport/beacon.xml",
+                                  0.0);
+    }
+
+    // write out taxiway signs references
+    for (unsigned int i = 0; i < signs.size(); ++i) {
+        SGGeod ref_geod = signs[i]->GetLoc();
+        ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
+        write_index_object_sign(objpath, b, ref_geod,
+                                signs[i]->GetDefinition(),
+                                signs[i]->GetHeading(),
+                                signs[i]->GetSize());
+    }
+
+    // write out water buoys
+    for (unsigned int i = 0; i < waterRunways.size(); ++i) {
+        tgContour buoys = waterRunways[i]->GetBuoys();
+
+        for (unsigned int j = 0; j < buoys.GetSize(); ++j) {
+            SGGeod ref_geod = buoys.GetNode(j);
+            ref_geod.setElevationM(apt_surf.calc_elevation(ref_geod, 0.0));
+            write_index_object_shared(objpath, b, ref_geod,
+                                      "Models/Airport/water_rw_buoy.xml",
+                                      0.0);
+        }
+    }
+
+    std::string holepath = root + "/AirportArea"s;
+    tgChopper chopper(holepath);
+
+    divided_base.SetPreserve3D(true);
+    apt_clearing.SetPreserve3D(false);
+    apt_clearing.SetTexMethod(TG_TEX_BY_GEODE);
+
+    chopper.Add(divided_base, "Hole"s);
+    chopper.Add(apt_clearing, "Airport"s);
+    chopper.Save(false);
+}
+
+bool Airport::CheckZFightingTriangles(const std::string& prefix, const std::string& debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys)
+{
+    using namespace std::string_literals;
+
+    std::string layer{"z-fighting_"s + prefix};
+    std::string desc{};
+
+    double min_area_thresh = 1.0e-10;
+
+    bool isZFighting = false;
+
+    if (rwy_polys.size()) {
+        unsigned i = 0;
+        for (tgPolygon subject : rwy_polys) {
+            for (unsigned int j = 0; j < subject.Triangles(); ++j) {
+                tgTriangle subTri = subject.GetTriangle(j);
+                tgRectangle subBB = subTri.GetBoundingBox();
+
+                unsigned k = 0;
+                for  (tgPolygon test : pvmt_polys) {
+                    for (unsigned int l = 0; l < test.Triangles(); ++l) {
+                        tgTriangle testTri = test.GetTriangle(l);
+                        tgRectangle testBB = testTri.GetBoundingBox();
+
+                        if (subBB.intersects(testBB)) {
+                            // find the intersection
+                            tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
+
+                            for (unsigned int m = 0; m < intersection.Contours(); ++m) {
+                                tgContour intContour = intersection.GetContour(m);
+
+                                if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
+                                    TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between runway poly " << i <<
+                                                                 " and pavement poly " << k <<
+                                                                 " contour has " << intContour.GetSize() << " nodes " <<
+                                                                 " area is " << intContour.GetArea());
+
+                                    desc = "rwy_"s + std::to_string(i) + "_pvmt_"s + std::to_string(j);
+                                    tgShapefile::FromContour(intContour, debug_root, layer, desc);
+                                    isZFighting = true;
+                                }
+                            }
+                        }
+                    }
+                    ++k;
+                }
+            }
+            ++i;
+        }
+    }
+
+    // intersect each pavement poly with each pavement, runway, and base poly
+    if (pvmt_polys.size()) {
+        unsigned i = 0;
+        for (tgPolygon subject : pvmt_polys) {
+            for (unsigned int j = 0; j < subject.Triangles(); ++j) {
+                tgTriangle subTri = subject.GetTriangle(j);
+                tgRectangle subBB = subTri.GetBoundingBox();
+
+                unsigned k = 0;
+                for (tgPolygon test : rwy_polys) {
+                    for (unsigned int l = 0; l < test.Triangles(); ++l) {
+                        tgTriangle testTri = test.GetTriangle(l);
+                        tgRectangle testBB = testTri.GetBoundingBox();
+
+                        if (subBB.intersects(testBB)) {
+                            // find the intersection
+                            tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
+
+                            for (unsigned int m = 0; m < intersection.Contours(); m++) {
+                                tgContour intContour = intersection.GetContour(m);
+
+                                if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
+                                    TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between pavement poly " << i <<
+                                                                 " and runway poly " << k <<
+                                                                 " contour has " << intContour.GetSize() << " nodes " <<
+                                                                 " area is " << intContour.GetArea());
+
+                                    desc = "pvmt"s + std::to_string(i) + "_rwy_"s + std::to_string(j);
+                                    tgShapefile::FromContour(intContour, debug_root, layer, desc);
+                                    isZFighting = true;
+                                }
+                            }
+                        }
+                    }
+                    ++k;
+                }
+            }
+            ++i;
+        }
+    }
+
+    // intersect base poly with each runway and pavement poly
+    tgPolygon subject = base_poly;
+
+    for (unsigned int i = 0; i < subject.Triangles(); ++i) {
+        tgTriangle subTri = subject.GetTriangle(i);
+        tgRectangle subBB = subTri.GetBoundingBox();
+
+        unsigned j = 0;
+        for (tgPolygon test : rwy_polys) {
+            for (unsigned int k = 0; k < test.Triangles(); ++k) {
+                tgTriangle testTri = test.GetTriangle(k);
+                tgRectangle testBB = testTri.GetBoundingBox();
+
+                if (subBB.intersects(testBB)) {
+                    // find the intersection
+                    tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
+
+                    for (unsigned int m = 0; m < intersection.Contours(); m++) {
+                        tgContour intContour = intersection.GetContour(m);
+
+                        if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
+                            TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and runway poly " << j <<
+                                                         " contour has " << intContour.GetSize() << " nodes " <<
+                                                         " area is " << intContour.GetArea());
+
+                            desc = "base_rwy_"s + std::to_string(j);
+                            tgShapefile::FromContour(intContour, debug_root, layer, desc);
+                            isZFighting = true;
+                        }
+                    }
+                }
+            }
+            ++j;
+        }
+    }
+
+    for (unsigned int i = 0; i < subject.Triangles(); ++i) {
+        tgTriangle subTri = subject.GetTriangle(i);
+        tgRectangle subBB = subTri.GetBoundingBox();
+
+        unsigned j = 0;
+        for (tgPolygon test : pvmt_polys) {
+            for (unsigned int k = 0; k < test.Triangles(); ++k) {
+                tgTriangle testTri = test.GetTriangle(k);
+                tgRectangle testBB = testTri.GetBoundingBox();
+
+                if (subBB.intersects(testBB)) {
+                    // find the intersection
+                    tgPolygon intersection = tgTriangle::Intersect(subTri, testTri);
+
+                    for (unsigned int m = 0; m < intersection.Contours(); m++) {
+                        tgContour intContour = intersection.GetContour(m);
+
+                        if ((intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh)) {
+                            TG_LOG(SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and pavement poly " << j <<
+                                                         " contour has " << intContour.GetSize() << " nodes " <<
+                                                         " area is " << intContour.GetArea());
+
+                            desc = "base_pvmt_"s + std::to_string(j);
+                            tgShapefile::FromContour(intContour, debug_root, layer, desc);
+                            isZFighting = true;
+                        }
+                    }
+                }
+            }
+            ++j;
+        }
+    }
+
+    return isZFighting;
+}
diff --git a/src/Airports/GenAirports/airport.hxx b/src/Airports/GenAirports/airport.hxx
index d6aa06c0..29304aaa 100644
--- a/src/Airports/GenAirports/airport.hxx
+++ b/src/Airports/GenAirports/airport.hxx
@@ -15,6 +15,7 @@
 #include "runway.hxx"
 #include "taxiway.hxx"
 
+
 class Airport
 {
 public:
@@ -26,14 +27,14 @@ public:
         runways.push_back(runway);
     }
 
-    void AddWaterRunway(std::shared_ptr<WaterRunway> waterrunway)
+    void AddWaterRunway(std::shared_ptr<WaterRunway> runway)
     {
-        waterrunways.push_back(waterrunway);
+        waterRunways.push_back(runway);
     }
 
-    void AddObj(std::shared_ptr<LightingObj> lightobj)
+    void AddObj(std::shared_ptr<LightingObj> lightObj)
     {
-        lightobjects.push_back(lightobj);
+        lightObjects.push_back(lightObj);
     }
 
     void AddHelipad(std::shared_ptr<Helipad> helipad)
@@ -58,19 +59,19 @@ public:
 
     void AddFeatures(FeatureList feature_list)
     {
-        for (auto feature : feature_list) {
+        for (auto& feature : feature_list) {
             features.push_back(feature);
         }
     }
 
-    int NumFeatures(void)
+    int NumFeatures() const
     {
         return features.size();
     }
 
-    void AddBoundary(std::shared_ptr<ClosedPoly> bndry)
+    void AddBoundary(std::shared_ptr<ClosedPoly> boundary)
     {
-        boundary.push_back(bndry);
+        boundaries.push_back(boundary);
     }
 
     void AddWindsock(std::shared_ptr<Windsock> windsock)
@@ -88,7 +89,7 @@ public:
         signs.push_back(sign);
     }
 
-    std::string GetIcao()
+    std::string GetIcao() const
     {
         return icao;
     }
@@ -111,8 +112,6 @@ public:
     void merge_slivers(tgpolygon_list& polys, tgcontour_list& slivers);
     void BuildBtg(const std::string& root, const string_list& elev_src);
 
-    void DumpStats(void);
-
     void set_debug(std::string& path,
                    debug_map& dbg_runways,
                    debug_map& dbg_pavements,
@@ -126,13 +125,13 @@ public:
         debug_features = dbg_features;
     };
 
-    bool isDebugRunway(int i);
-    bool isDebugPavement(int i);
-    bool isDebugTaxiway(int i);
-    bool isDebugFeature(int i);
+    bool isDebugRunway(int) const;
+    bool isDebugPavement(int) const;
+    bool isDebugTaxiway(int) const;
+    bool isDebugFeature(int) const;
 
 private:
-    bool CheckZFightingTriangles(const char* prefix, const char* debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys);
+    bool CheckZFightingTriangles(const std::string& prefix, const std::string& debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys);
 
     int code;                // airport, heliport or sea port
     int altitude;            // in meters
@@ -142,14 +141,14 @@ private:
     PavementList pavements;
     FeatureList features;
     RunwayList runways;
-    WaterRunwayList waterrunways;
+    WaterRunwayList waterRunways;
     TaxiwayList taxiways;
-    LightingObjList lightobjects;
+    LightingObjList lightObjects;
     WindsockList windsocks;
     BeaconList beacons;
     SignList signs;
     HelipadList helipads;
-    PavementList boundary;
+    PavementList boundaries;
 
     // stats
     SGTimeStamp build_time;