From 7c8b6781f394a10b7cb82e7f69712613182d8e1b Mon Sep 17 00:00:00 2001
From: Christian Schmitt <chris@ilovelinux.de>
Date: Fri, 23 Sep 2011 13:52:49 +0200
Subject: [PATCH] Make helipads work

---
 src/Airports/GenAirports850/CMakeLists.txt |  3 +-
 src/Airports/GenAirports850/build.cxx      | 86 ++++++++++++++++++----
 src/Airports/GenAirports850/heli_gen.cxx   | 70 ++++++++++++++++++
 src/Airports/GenAirports850/heli_gen.hxx   | 49 ++++++++++++
 src/Airports/GenAirports850/main.cxx       | 16 ++--
 src/Airports/GenAirports850/runway.hxx     |  1 +
 src/Airports/GenAirports850/rwy_common.cxx |  8 +-
 7 files changed, 203 insertions(+), 30 deletions(-)
 create mode 100644 src/Airports/GenAirports850/heli_gen.cxx
 create mode 100644 src/Airports/GenAirports850/heli_gen.hxx

diff --git a/src/Airports/GenAirports850/CMakeLists.txt b/src/Airports/GenAirports850/CMakeLists.txt
index 791dedc3..81c46a27 100644
--- a/src/Airports/GenAirports850/CMakeLists.txt
+++ b/src/Airports/GenAirports850/CMakeLists.txt
@@ -4,7 +4,8 @@ add_executable(genapts850
     apt_surface.hxx apt_surface.cxx 
 	build.cxx build.hxx 
 	elevations.cxx elevations.hxx 
-	global.hxx 
+	global.hxx
+        heli_gen.cxx heli_gen.hxx
 	lights.hxx lights.cxx 
 	main.cxx 
 	point2d.cxx point2d.hxx 
diff --git a/src/Airports/GenAirports850/build.cxx b/src/Airports/GenAirports850/build.cxx
index e9ff5f20..e4f944cc 100644
--- a/src/Airports/GenAirports850/build.cxx
+++ b/src/Airports/GenAirports850/build.cxx
@@ -64,6 +64,7 @@
 #include "runway.hxx"
 #include "rwy_common.hxx"
 #include "rwy_gen.hxx"
+#include "heli_gen.hxx"
 #include "rwy_simple.hxx"
 #include "taxiway.hxx"
 #include "texparams.hxx"
@@ -230,24 +231,25 @@ static void build_runway( const TGRunway& rwy_info,
     if ( surface_code == 1 /* Asphalt */ ) {
             material = "pa_";
     } else if ( surface_code == 2 /* Concrete */ ) {
-            material = "pc_";
+	    material = "pc_";
     } else if ( surface_code == 3 /* Turf/Grass */ ) {
-        material = "grass_rwy";
+	    material = "grass_rwy";
     } else if ( surface_code == 4 /* Dirt */
-                || surface_code == 5 /* Gravel */ ) {
-        material = "dirt_rwy";
-    } else if ( surface_code == 12 /* Dry Lakebed */ ) {
-	material = "dirt_rwy";
-    } else if ( surface_code == 13 /* Water runway (buoy's?) */ ) {
-        // water
+	    || surface_code == 5 /* Gravel */
+	    || surface_code == 12 /* Dry lakebed */ ) {
+	    material = "dirt_rwy";
     } else {
         SG_LOG(SG_GENERAL, SG_WARN, "surface_code = " << surface_code);
 	throw sg_exception("unknown runway type!");
     }
-
+if ( rwy_info.type == 102 ){
+SG_LOG(SG_GENERAL, SG_INFO, "Generating Helipad" );
+gen_heli( rwy_info, alt_m, material,
+			   rwy_polys, texparams, accum );
+}
 
     SG_LOG(SG_GENERAL, SG_DEBUG, "marking code = " << rwy_info.marking_code1 << " / " << rwy_info.marking_code2);
-
+if ( rwy_info.type == 100 ){
       if ( surface_code == 3 /* Turf/Grass */
                 || surface_code == 4 /* Dirt */
                 || surface_code == 5 /* Gravel */ )
@@ -273,16 +275,28 @@ static void build_runway( const TGRunway& rwy_info,
                 rwy_info.marking_code1 );
 	throw sg_exception("Unknown runway code in build.cxx:build_airport()");
     }
+}
 
     TGPolygon base, safe_base;
+    if (rwy_info.type == 100){
+	base = gen_runway_area_w_extend( rwy_info, 0.0, 20.0, -rwy_info.stopway1, -rwy_info.stopway2, 20.0 );
+	// also clear a safe area around the runway
+	safe_base = gen_runway_area_w_extend( rwy_info, 0.0, 180.0, -rwy_info.stopway1, -rwy_info.stopway2, 50.0 );
+	*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
 
-    base = gen_runway_area_w_extend( rwy_info, 0.0, 20.0, -rwy_info.stopway1, -rwy_info.stopway2, 20.0 );
-    // also clear a safe area around the runway
-    safe_base = gen_runway_area_w_extend( rwy_info, 0.0, 180.0, -rwy_info.stopway1, -rwy_info.stopway2, 50.0 );
-    *apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
+	// add base to apt_base
+	*apt_base = tgPolygonUnion( base, *apt_base );
+    }
 
-    // add base to apt_base
-    *apt_base = tgPolygonUnion( base, *apt_base );
+    if (rwy_info.type == 102){
+	base = gen_runway_area_w_extend( rwy_info, 0.0, 10.0, 0, 0, 10.0 );
+	// also clear a safe area around the runway
+	safe_base = gen_runway_area_w_extend( rwy_info, 0.0, 40.0, 0, 0, 40.0 );
+	*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
+
+	// add base to apt_base
+	*apt_base = tgPolygonUnion( base, *apt_base );
+    }
 }
 
 
@@ -329,6 +343,12 @@ void build_airport( string airport_id, float alt_m,
 	TGRunway rwy;
 
 	SG_LOG(SG_GENERAL, SG_DEBUG, rwy_str);
+
+	rwy.type = atoi( token[0].c_str() );
+	SG_LOG( SG_GENERAL, SG_INFO, "apt_type = " << rwy.type );
+
+     if (rwy.type == 100) /*Land runway*/{
+
 	rwy.rwy_no1 = token[8];
 	rwy.rwy_no2 = token[17];
         rwy.generated = false;
@@ -397,7 +417,41 @@ void build_airport( string airport_id, float alt_m,
 	SG_LOG( SG_GENERAL, SG_DEBUG, "  dspth2= " << rwy.disp_thresh2);
 	SG_LOG( SG_GENERAL, SG_DEBUG, "  stop1 = " << rwy.stopway1);
 	SG_LOG( SG_GENERAL, SG_DEBUG, "  stop2 = " << rwy.stopway2);
+     }
 
+     if (rwy.type == 102) /*Helipad*/{
+
+
+	rwy.rwy_no1 = token[1];
+        rwy.generated = false;
+
+	rwy.surface_code = atoi( token[7].c_str() );
+	rwy.shoulder_code = atoi( token[9].c_str() );
+        rwy.smoothness = atof( token[10].c_str() );
+
+	rwy.edge_lights = atoi( token[11].c_str() );
+
+	rwy.lat = atof( token[2].c_str() );
+	rwy.lon = atof( token[3].c_str() );
+
+	apt_lat += rwy.lat;
+	apt_lon += rwy.lon;
+
+	rwy.heading = atof( token[4].c_str() );
+
+	rwy.length = atof( token[5].c_str() );
+	rwy.width = atoi( token[6].c_str() );
+
+
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  no1    = " << rwy.rwy_no1 );
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  lat   = " << rwy.lat);
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  lon   = " << rwy.lon);
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  hdg   = " << rwy.heading);
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  len   = " << rwy.length);
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  width = " << rwy.width);
+	SG_LOG( SG_GENERAL, SG_DEBUG, "  sfc   = " << rwy.surface_code);
+
+     }
         runways.push_back( rwy );
     }
     SG_LOG(SG_GENERAL, SG_INFO, "Runway count = " << runways.size() );
diff --git a/src/Airports/GenAirports850/heli_gen.cxx b/src/Airports/GenAirports850/heli_gen.cxx
new file mode 100644
index 00000000..0902b4d0
--- /dev/null
+++ b/src/Airports/GenAirports850/heli_gen.cxx
@@ -0,0 +1,70 @@
+// rwy_gen.cxx -- Build a runway
+//
+// Written by Curtis Olson, started February 2002.
+//
+// Copyright (C) 2002  Curtis L. Olson  - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include <simgear/compiler.h>
+#include <simgear/constants.h>
+#include <simgear/debug/logstream.hxx>
+
+#include "rwy_common.hxx"
+
+#include <stdlib.h>
+
+using std::string;
+
+
+void gen_heli( const TGRunway& rwy_info,
+                        double alt_m,
+			const string& material,
+			superpoly_list *rwy_polys,
+			texparams_list *texparams,
+			TGPolygon *accum )
+{
+    SG_LOG( SG_GENERAL, SG_INFO, "Building helipad = " << rwy_info.rwy_no1 );
+
+    //
+    // Generate the basic helipad outlines
+    //
+    Point3D helicenter = Point3D( rwy_info.lon, rwy_info.lat, 0.0);
+
+    TGPolygon helipad = gen_wgs84_area( helicenter, rwy_info.length, 0, 0, rwy_info.width, rwy_info.heading,
+                                        alt_m, false);
+
+    double start1_pct = 0.0;
+    double end1_pct = 0.0;
+    double maxsize = rwy_info.width - rwy_info.length;
+
+    if (maxsize <= 0)
+        maxsize = rwy_info.width;
+    else if (maxsize > 0)
+        maxsize = rwy_info.length;
+
+    double percent = (maxsize / rwy_info.length) /2;
+
+    start1_pct = 0.5 - percent;
+    end1_pct = 0.5 + percent;
+    gen_runway_section( rwy_info, helipad,
+                        start1_pct, end1_pct,
+                        0.0, 1.0,
+                        0.0, 1.0, 0.0, 1.0,
+                        rwy_info.heading,
+                        material, "heli",
+                        rwy_polys, texparams, accum );
+}
diff --git a/src/Airports/GenAirports850/heli_gen.hxx b/src/Airports/GenAirports850/heli_gen.hxx
new file mode 100644
index 00000000..b2c770f4
--- /dev/null
+++ b/src/Airports/GenAirports850/heli_gen.hxx
@@ -0,0 +1,49 @@
+// rwy_gen.hxx -- Build a runway
+//
+// Written by Curtis Olson, started February 2002.
+//
+// Copyright (C) 2002  Curtis L. Olson  - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: rwy_prec.hxx,v 1.5 2004-11-19 22:25:49 curt Exp $
+//
+
+
+#ifndef _HELI_GEN_HXX
+#define _HELI_GEN_HXX
+
+
+#include <Polygon/polygon.hxx>
+#include <Polygon/superpoly.hxx>
+
+#include "runway.hxx"
+#include "texparams.hxx"
+
+
+// generate a runway.  The routine modifies
+// rwy_polys, texparams, and accum.  For specific details and
+// dimensions of precision runway markings, please refer to FAA
+// document AC 150/5340-1H
+
+void gen_heli( const TGRunway& rwy_info,
+                        double alt_m,
+			const std::string& material,
+			superpoly_list *rwy_polys,
+			texparams_list *texparams,
+			TGPolygon *accum );
+
+
+#endif // _RWY_PREC_HXX
diff --git a/src/Airports/GenAirports850/main.cxx b/src/Airports/GenAirports850/main.cxx
index ed8e6b2f..ed362119 100644
--- a/src/Airports/GenAirports850/main.cxx
+++ b/src/Airports/GenAirports850/main.cxx
@@ -324,10 +324,8 @@ int main( int argc, char **argv ) {
                         // process previous record
                         // process_airport(last_apt_id, runways_list, argv[2]);
                         try {
-                            if ( last_apt_type == "16" /* Seaplane base */ ||
-                                 last_apt_type == "17" /* Heliport */ ) {
-                                // skip building heliports and
-                                // seaplane bases
+                            if ( last_apt_type == "16" /* Seaplane base */ ) {
+                                // skip building seaplane bases
                             } else {
                                 if( is_in_range( runways_list, min_lat, max_lat, min_lon, max_lon ) ) {
                                     build_airport( last_apt_id,
@@ -370,7 +368,7 @@ int main( int argc, char **argv ) {
             tower_list.clear();
             windsock_list.clear();
 	    light_list.clear();
-        } else if ( token[0] == "100" ) {
+        } else if ( token[0] == "100" || token[0] == "102") {
             // runway entry
             runways_list.push_back(line);
         } else if ( token[0] == "18" ) {
@@ -396,6 +394,8 @@ int main( int argc, char **argv ) {
             SG_LOG( SG_GENERAL, SG_ALERT, "End of file reached" );
 	} else if ( token[0] == "00" ) {
 		// ??
+	} else if ( token[0] >= "110" ) {
+		//ignore lines for now
         } else {
             SG_LOG( SG_GENERAL, SG_ALERT, 
                     "Unknown line in file: " << line );
@@ -432,10 +432,8 @@ int main( int argc, char **argv ) {
             // process previous record
             // process_airport(last_apt_id, runways_list, argv[2]);
             try {
-                if ( last_apt_type == "16" /* Seaplane base */ ||
-                     last_apt_type == "17" /* Heliport */ ) {
-                    // skip building heliports and
-                    // seaplane bases
+                if ( last_apt_type == "16" /* Seaplane base */ ) {
+                    // skip building seaplane bases
                 } else {
                     if( is_in_range( runways_list, min_lat, max_lat, min_lon, max_lon ) ) {
                         build_airport( last_apt_id, elev * SG_FEET_TO_METER,
diff --git a/src/Airports/GenAirports850/runway.hxx b/src/Airports/GenAirports850/runway.hxx
index c08435bb..34f6ab1d 100644
--- a/src/Airports/GenAirports850/runway.hxx
+++ b/src/Airports/GenAirports850/runway.hxx
@@ -35,6 +35,7 @@
 
 
 struct TGRunway {
+    int type;
     std::string rwy_no1;
     std::string rwy_no2;
 
diff --git a/src/Airports/GenAirports850/rwy_common.cxx b/src/Airports/GenAirports850/rwy_common.cxx
index c3d8e718..9dcf5c1a 100644
--- a/src/Airports/GenAirports850/rwy_common.cxx
+++ b/src/Airports/GenAirports850/rwy_common.cxx
@@ -273,16 +273,16 @@ void gen_runway_section( const TGRunway& rwy_info,
     // potential artifacts and we may add or remove points and need to
     // do new texture coordinate calcs later.
 
-    // we add 2' to the length for texture overlap.  This puts the
+    // we add 0.5m to the length for texture overlap.  This puts the
     // lines on the texture back to the edge of the runway where they
     // belong.
-    double len = rwy_info.length / 2.0 + 2 * SG_FEET_TO_METER;
+    double len = rwy_info.length / 2.0 + 0.5;
     double sect_len = len * ( endl_pct - startl_pct );
 
-    // we add 2' to both sides of the runway (4' total) for texture
+    // we add 0.5m to both sides of the runway (4' total) for texture
     // overlap.  This puts the lines on the texture back to the edge
     // of the runway where they belong.
-    double wid = rwy_info.width + 4 * SG_FEET_TO_METER;
+    double wid = rwy_info.width + 0.5;
     double sect_wid = wid * ( endw_pct - startw_pct );
 
     TGTexParams tp;