diff --git a/GenAirports/Makefile.am b/GenAirports/Makefile.am new file mode 100644 index 000000000..a5d9d981c --- /dev/null +++ b/GenAirports/Makefile.am @@ -0,0 +1,61 @@ +#--------------------------------------------------------------------------- +# Makefile +# +# Written by Curtis Olson, started January 1998. +# +# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +# +# 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$ +# (Log is kept at end of this file) +#--------------------------------------------------------------------------- + + +bin_PROGRAMS = genapts + +genapts_SOURCES = area.cxx area.hxx main.cxx + +genapts_LDADD = \ + $(top_builddir)/Lib/Bucket/libBucket.a \ + $(top_builddir)/Lib/zlib/libz.a + +INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib + + +#--------------------------------------------------------------------------- +# $Log$ +# Revision 1.1 1998/09/01 19:34:32 curt +# Initial revision. +# +# Revision 1.2 1998/07/30 23:49:18 curt +# Removed libtool support. +# +# Revision 1.1 1998/07/20 12:54:53 curt +# Whoops, need to commit Makefile.am, not Makefile. +# +# Revision 1.2 1998/04/14 02:25:59 curt +# Code reorganizations. Added a Lib/ directory for more general libraries. +# +# Revision 1.1 1998/04/08 22:54:57 curt +# Adopted Gnu automake/autoconf system. +# +# Revision 1.2 1998/01/21 02:55:46 curt +# Incorporated new make system from Bob Kuehne . +# +# Revision 1.1 1998/01/15 02:45:25 curt +# Initial revision. +# + diff --git a/GenAirports/area.cxx b/GenAirports/area.cxx new file mode 100644 index 000000000..cfefd744d --- /dev/null +++ b/GenAirports/area.cxx @@ -0,0 +1,232 @@ +// area.c -- routines to assist with inserting "areas" into FG terrain +// +// Written by Curtis Olson, started March 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// 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$ +// (Log is kept at end of this file) +// + + +#include +#include + +#include + +#include "area.hxx" + + +// calc new x, y for a rotation +double rot_x(double x, double y, double theta) { + return ( x * cos(theta) + y * sin(theta) ); +} + + +// calc new x, y for a rotation +double rot_y(double x, double y, double theta) { + return ( -x * sin(theta) + y * cos(theta) ); +} + + +// calc new lon/lat given starting lon/lat, and offset radial, and +// distance. NOTE: distance is specified in meters (and converted +// internally to radians) +point2d calc_lon_lat( point2d orig, point2d offset ) { + point2d result; + + // printf("calc_lon_lat() offset.theta = %.2f offset.dist = %.2f\n", + // offset.theta, offset.dist); + + offset.dist *= METER_TO_NM * NM_TO_RAD; + + result.lat = asin( sin(orig.lat) * cos(offset.dist) + + cos(orig.lat) * sin(offset.dist) * cos(offset.theta) ); + + if ( cos(result.lat) < FG_EPSILON ) { + result.lon = orig.lon; // endpoint a pole + } else { + result.lon = + fmod(orig.lon - asin( sin(offset.theta) * sin(offset.dist) / + cos(result.lat) ) + FG_PI, FG_2PI) - FG_PI; + } + + return(result); +} + + +point2d cart_to_polar_2d(point2d in) { + point2d result; + result.dist = sqrt( in.x * in.x + in.y * in.y ); + result.theta = atan2(in.y, in.x); + + return(result); +} + + +list < point2d > +batch_cart_to_polar_2d( list < point2d > in_list) +{ + list < point2d > out_list; + list < point2d > :: iterator current; + list < point2d > :: iterator last; + point2d p; + + current = in_list.begin(); + last = in_list.end(); + while ( current != last ) { + p = cart_to_polar_2d( *current ); + out_list.push_back(p); + current++; + } + + return out_list; +} + + +// given a set of 2d coordinates relative to a center point, and the +// lon, lat of that center point (specified in degrees), as well as a +// potential orientation angle, generate the corresponding lon and lat +// of the original 2d verticies. +list < point2d > +gen_area(point2d origin, double angle, list < point2d > cart_list) +{ + list < point2d > rad_list; + list < point2d > result_list; + list < point2d > :: iterator current; + list < point2d > :: iterator last; + point2d origin_rad, p; + + origin_rad.lon = origin.lon * DEG_TO_RAD; + origin_rad.lat = origin.lat * DEG_TO_RAD; + + // convert to polar coordinates + rad_list = batch_cart_to_polar_2d(cart_list); + + /* + // display points + printf("converted to polar\n"); + current = rad_list.begin(); + last = rad_list.end(); + while ( current != last ) { + printf("(%.2f, %.2f)\n", current->theta, current->dist); + current++; + } + printf("\n"); + */ + + // rotate by specified angle + // printf("Rotating points by %.2f\n", angle); + current = rad_list.begin(); + last = rad_list.end(); + while ( current != last ) { + current->theta -= angle; + while ( current->theta > FG_2PI ) { + current->theta -= FG_2PI; + } + // printf("(%.2f, %.2f)\n", current->theta, current->dist); + current++; + } + // printf("\n"); + + // find actual lon,lat of coordinates + // printf("convert to lon, lat relative to %.2f %.2f\n", + // origin.lon, origin.lat); + current = rad_list.begin(); + last = rad_list.end(); + while ( current != last ) { + p = calc_lon_lat(origin_rad, *current); + // printf("(%.8f, %.8f)\n", p.lon, p.lat); + result_list.push_back(p); + current++; + } + // printf("\n"); + + return result_list; +} + + +// generate an area for a runway +list < point2d > +gen_runway_area( double lon, double lat, double heading, + double length, double width) +{ + list < point2d > result_list; + list < point2d > tmp_list; + list < point2d > :: iterator current; + list < point2d > :: iterator last; + + point2d p; + point2d origin; + double l, w; + int i; + + /* + printf("runway: lon = %.2f lat = %.2f hdg = %.2f len = %.2f width = %.2f\n", + lon, lat, heading, length, width); + */ + + origin.lon = lon; + origin.lat = lat; + l = length / 2.0; + w = width / 2.0; + + // generate untransformed runway area vertices + p.x = l; p.y = w; tmp_list.push_back(p); + p.x = l; p.y = -w; tmp_list.push_back(p); + p.x = -l; p.y = -w; tmp_list.push_back(p); + p.x = -l; p.y = w; tmp_list.push_back(p); + + /* + // display points + printf("Untransformed, unrotated runway\n"); + current = tmp_list.begin(); + last = tmp_list.end(); + while ( current != last ) { + printf("(%.2f, %.2f)\n", current->x, current->y); + current++; + } + printf("\n"); + */ + + // rotate, transform, and convert points to lon, lat + result_list = gen_area(origin, heading, tmp_list); + + /* + // display points + printf("Results in radians.\n"); + current = result_list.begin(); + last = result_list.end(); + while ( current != last ) { + printf("(%.8f, %.8f)\n", current->lon, current->lat); + current++; + } + printf("\n"); + */ + + return result_list; +} + + +// $Log$ +// Revision 1.1 1998/09/01 19:34:33 curt +// Initial revision. +// +// Revision 1.1 1998/07/20 12:54:05 curt +// Initial revision. +// +// diff --git a/GenAirports/area.hxx b/GenAirports/area.hxx new file mode 100644 index 000000000..8ef514694 --- /dev/null +++ b/GenAirports/area.hxx @@ -0,0 +1,63 @@ +// area.h -- routines to assist with inserting "areas" into FG terrain +// +// Written by Curtis Olson, started February 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// 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$ +// (Log is kept at end of this file) +// + + +#ifndef _AREA_H +#define _AREA_H + + +#include + + +typedef struct { + union { + double x; + double dist; + double lon; + }; + union { + double y; + double theta; + double lat; + }; +} point2d; + + +// generate an area for a runway +list < point2d > +gen_runway_area( double lon, double lat, double heading, + double length, double width); + + +#endif // _AREA_H + + +// $Log$ +// Revision 1.1 1998/09/01 19:34:33 curt +// Initial revision. +// +// Revision 1.1 1998/07/20 12:54:05 curt +// Initial revision. +// +// diff --git a/GenAirports/main.cxx b/GenAirports/main.cxx new file mode 100644 index 000000000..fa5464c56 --- /dev/null +++ b/GenAirports/main.cxx @@ -0,0 +1,236 @@ +// main.cxx -- main loop +// +// Written by Curtis Olson, started March 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// 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$ +// (Log is kept at end of this file) +// + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "area.hxx" + + +// process and airport + runway list +void process_airport( string last_airport, list < string > & runway_list ) { + list < point2d > rwy_list, apt_list; + list < point2d > :: iterator current; + list < point2d > :: iterator last; + + string line_str; + double lon, lat; + int len, width, hdg, label_hdg, elev; + char codes[10]; + char side; + + printf( "(apt) %s", last_airport.c_str() ); + + while ( runway_list.size() ) { + line_str = runway_list.front(); + runway_list.pop_front(); + printf( "%s", line_str.c_str() ); + + sscanf( line_str.c_str(), "%lf %lf %d %d %d %s %d %c %d\n", + &lon, &lat, &len, &width, &hdg, codes, &label_hdg, + &side, &elev ); + + rwy_list = gen_runway_area( lon, lat, (double)hdg * DEG_TO_RAD, + (double)len * FEET_TO_METER, + (double)width * FEET_TO_METER ); + + // add rwy_list to apt_list + current = rwy_list.begin(); + last = rwy_list.end(); + while ( current != last ) { + apt_list.push_back(*current); + current++; + } + } + + printf("Final results in degrees\n"); + current = apt_list.begin(); + last = apt_list.end(); + while ( current != last ) { + // printf( "(%.4f, %.4f)\n", + printf( "%.5f %.5f\n", + current->lon * RAD_TO_DEG, + current->lat * RAD_TO_DEG ); + current++; + } + printf("\n"); +} + + +// reads the apt_full file and extracts and processes the individual +// airport records +int main( int argc, char **argv ) { + list < string > runway_list; + string apt_path, gz_apt_path; + string airport, last_airport; + fgFile f; + char line[256]; + /* + fgBUCKET b; + point2d nodes[4]; + char base[256], path[256], command[256], file[256], exfile[256]; + double lon, lat, elevation, heading; + double length, width; + long int index; + */ + + if ( argc != 3 ) { + printf("Usage %s \n", argv[0]); + exit(0); + } + + apt_path = argv[1]; + gz_apt_path = apt_path + ".gz"; + + // first try "path.gz" + if ( (f = fgopen(gz_apt_path.c_str(), "rb")) == NULL ) { + // next try "path" + if ( (f = fgopen(apt_path.c_str(), "rb")) == NULL ) { + printf( "Cannot open file: %s\n", apt_path.c_str()); + } + } + + while ( fggets(f, line, 250) != NULL ) { + // printf("%s", line); + if ( strlen(line) == 0 ) { + // empty, skip + } else if ( line[0] == '#' ) { + // comment, skip + } else if ( line[0] == '\t' ) { + // runway entry + runway_list.push_back(line); + } else { + // start of airport record + airport = line; + + if ( last_airport.length() ) { + // process previous record + process_airport(last_airport, runway_list); + } + + last_airport = airport; + } + } + + if ( last_airport.length() ) { + // process previous record + process_airport(last_airport, runway_list); + } + + fgclose(f); + + return(1); +} + + +#if 0 + // P13 (Globe, AZ) + // lon = -110.6642442; + // lat = 33.3528903; + // heading = 102.0 * DEG_TO_RAD; + // length = 1769; + // width = 23; + + // KANE + lon = -93.2113889; + lat = 45.145; + elevation = 912 * FEET_TO_METER; + heading = 270.0 * DEG_TO_RAD; + length = 1220; + width = 23; + + gen_runway_area( lon * DEG_TO_RAD, lat * DEG_TO_RAD, + heading, length, width, nodes, &count ); + + fgBucketFind(lon, lat, &b); + printf( "Bucket = lon,lat = %d,%d x,y index = %d,%d\n", + b.lon, b.lat, b.x, b.y); + + index = fgBucketGenIndex(&b); + fgBucketGenBasePath(&b, base); + sprintf(path, "%s/Scenery/%s", argv[1], base); + sprintf(command, "mkdir -p %s\n", path); + system(command); + + sprintf(exfile, "%s/%ld.node.ex", path, index); + sprintf(file, "%s/%ld.poly", path, index); + printf( "extra node file = %s\n", exfile); + printf( "poly file = %s\n", file); + + // output extra nodes + if ( (fd = fopen(exfile, "w")) == NULL ) { + printf("Cannot open file: %s\n", exfile); + exit(-1); + } + + fprintf(fd, "%d 2 0 0\n", count); + for ( i = 0; i < count; i++ ) { + fprintf( fd, "%d %.2f %.2f %.2f\n", i + 1, + nodes[i].lon * RAD_TO_ARCSEC, nodes[i].lat * RAD_TO_ARCSEC, + elevation); + } + fclose(fd); + + // output poly + if ( (fd = fopen(file, "w")) == NULL ) { + printf("Cannot open file: %s\n", file); + exit(-1); + } + + // output empty node list + fprintf(fd, "0 2 0 0\n"); + + // output segments + fprintf(fd, "%d 0\n", count); + for ( i = 0; i < count - 1; i++ ) { + fprintf( fd, "%d %d %d\n", i + 1, i + 1, i + 2 ); + } + fprintf( fd, "%d %d %d\n", count, count, 1 ); + + // output hole center + fprintf( fd, "1\n"); + fprintf( fd, "1 %.2f %.2f\n", lon * 3600.0, lat * 3600); + + fclose(fd); + +#endif + + +// $Log: main.c,v +//