1
0
Fork 0

[rwy_gen] Maintenance, Modernize

This commit is contained in:
scttgs0 2023-05-14 17:35:21 -05:00
parent dc9a7e494e
commit cbcbb8c8f6

View file

@ -19,25 +19,20 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <stdlib.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <boost/lexical_cast.hpp>
#include <terragear/tg_shapefile.hxx>
#include "global.hxx"
#include "beznode.hxx"
#include "global.hxx"
#include "runway.hxx"
using std::string;
struct sections
{
const char* tex;
struct sections {
std::string tex;
double size;
};
@ -54,8 +49,7 @@ static const struct sections uk_prec[] = {
{"rest", 200 * SG_FEET_TO_METER},
{"tz_one_a", 400 * SG_FEET_TO_METER},
{"rest", 200 * SG_FEET_TO_METER},
{ "tz_one_b", 200 * SG_FEET_TO_METER }
};
{"tz_one_b", 200 * SG_FEET_TO_METER}};
// UK non-precision runway sections from after the designation number
// onwards to the middle (one half).
@ -78,16 +72,14 @@ static const struct sections prec[] = {
{"rest", 200 * SG_FEET_TO_METER},
{"tz_one_a", 400 * SG_FEET_TO_METER},
{"rest", 200 * SG_FEET_TO_METER},
{ "tz_one_b", 200 * SG_FEET_TO_METER }
};
{"tz_one_b", 200 * SG_FEET_TO_METER}};
// Non-precision runway sections from after the designation number
// onwards to the middle (one half).
// Set order of sections and their corresponding size
static const struct sections nprec[] = {
{"centerline", 200 * SG_FEET_TO_METER},
{ "aim", 400 * SG_FEET_TO_METER }
};
{"aim", 400 * SG_FEET_TO_METER}};
tgPolygon Runway::gen_shoulder_section(SGGeod& p0, SGGeod& p1, SGGeod& t0, SGGeod& t1, int side, double heading, double width, std::string surface)
@ -95,9 +87,9 @@ tgPolygon Runway::gen_shoulder_section( SGGeod& p0, SGGeod& p1, SGGeod& t0, SGGe
SGGeod s0, s1, s2, s3;
tgPolygon poly;
double wid_hdg = 0.0f;
double az2 = 0.0f;
double dist = 0.0f;
double wid_hdg = 0.0;
double az2 = 0.0;
double dist = 0.0;
// calc heading and distance from p0 to p1
SGGeodesy::inverse(p0, p1, wid_hdg, az2, dist);
@ -124,10 +116,10 @@ tgPolygon Runway::gen_shoulder_section( SGGeod& p0, SGGeod& p1, SGGeod& t0, SGGe
poly.SetMaterial(surface);
if (side == 0) {
poly.SetTexParams(poly.GetNode(0, 2), width, dist, heading);
poly.SetTexLimits( 0,0,1,1 );
poly.SetTexLimits(0.0, 0.0, 1.0, 1.0);
} else {
poly.SetTexParams(poly.GetNode(0, 1), width, dist, heading);
poly.SetTexLimits( 1,0,0,1 );
poly.SetTexLimits(1.0, 0.0, 0.0, 1.0);
}
poly.SetTexMethod(TG_TEX_BY_TPS_CLIPU, 0.0, 0.0, 1.0, 0.0);
@ -140,39 +132,35 @@ void Runway::gen_runway_section( const tgPolygon& runway,
double startw_pct, double endw_pct,
double minu, double maxu, double minv, double maxv,
double heading,
const string& material,
const std::string& material,
tgpolygon_list& rwy_polys,
tgpolygon_list& shoulder_polys,
tgcontour_list& slivers,
tgAccumulator& accum,
std::string& shapefile_name)
{
using namespace std::string_literals;
double width = rwy.width;
double length = rwy.length;
double lshoulder_width = 0.0f;
double rshoulder_width = 0.0f;
double lshoulder_width = 0.0;
double rshoulder_width = 0.0;
std::string shoulder_surface = "";
#if 0
static int runway_idx = 0;
static int section_idx = 0;
static int clipped_idx = 0;
char layer[64];
#endif
SGVec2d a0 = SGVec2d(runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 1).getLatitudeDeg());
SGVec2d a1 = SGVec2d(runway.GetNode(0, 2).getLongitudeDeg(), runway.GetNode(0, 2).getLatitudeDeg());
SGVec2d a2 = SGVec2d(runway.GetNode(0, 0).getLongitudeDeg(), runway.GetNode(0, 0).getLatitudeDeg());
SGVec2d a3 = SGVec2d(runway.GetNode(0, 3).getLongitudeDeg(), runway.GetNode(0, 3).getLatitudeDeg());
if ( startl_pct > 0.0 ) {
if (startl_pct > 0.0)
startl_pct -= nudge * SG_EPSILON;
}
if ( endl_pct < 1.0 ) {
if (startl_pct < 0.0)
startl_pct = 0.0;
if (endl_pct < 1.0)
endl_pct += nudge * SG_EPSILON;
}
if ( endl_pct > 1.0 ) {
if (endl_pct > 1.0)
endl_pct = 1.0;
}
// calculate if we are going to be creating shoulder polys
if ((rwy.shoulder > 0) && (rwy.surface < 3)) {
@ -182,25 +170,25 @@ void Runway::gen_runway_section( const tgPolygon& runway,
shoulder_surface = "pc_shoulder";
}
if ( startw_pct == 0.0f ) {
if (startw_pct == 0.0) {
lshoulder_width = width / 4.0;
}
if ( endw_pct == 1.0f ) {
if (endw_pct == 1.0) {
rshoulder_width = width / 4.0;
}
} else {
// We add a fake shoulder if the runway has an asphalt or concrete surface
if ((rwy.surface == 1) || (rwy.surface == 2)) {
if (rwy.surface == 1) {
shoulder_surface = "pa_shoulder_f";
shoulder_surface = "pa_shoulder_f"s;
} else if (rwy.surface == 2) {
shoulder_surface = "pc_shoulder_f";
shoulder_surface = "pc_shoulder_f"s;
}
if ( startw_pct == 0.0f ) {
if (startw_pct == 0.0) {
lshoulder_width = 1.0;
}
if ( endw_pct == 1.0f ) {
if (endw_pct == 1.0) {
rshoulder_width = 1.0;
}
}
@ -211,14 +199,10 @@ void Runway::gen_runway_section( const tgPolygon& runway,
// with our polygon clipping code. This attempts to compensate
// for that by nudging the areas a bit bigger so we don't end up
// with polygon slivers.
if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
if ( startw_pct > 0.0 ) {
if (startw_pct > 0.0)
startw_pct -= nudge * SG_EPSILON;
}
if ( endw_pct < 1.0 ) {
if (endw_pct < 1.0)
endw_pct += nudge * SG_EPSILON;
}
}
TG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct << " end len % = " << endl_pct);
@ -263,7 +247,6 @@ void Runway::gen_runway_section( const tgPolygon& runway,
SGVec2d p3 = SGVec2d(t3.x() + dwx * endw_pct,
t3.y() + dwy * endw_pct);
// convert vectors back to GEOD
SGGeod pg0 = SGGeod::fromDeg(p0.x(), p0.y());
SGGeod pg1 = SGGeod::fromDeg(p1.x(), p1.y());
@ -303,18 +286,16 @@ void Runway::gen_runway_section( const tgPolygon& runway,
TG_LOG(SG_GENERAL, SG_DEBUG, section);
if (shapefile_name.size()) {
tgShapefile::FromPolygon( section, "./airport_dbg", std::string("preclip"), shapefile_name );
tgShapefile::FromPolygon(section, "./airport_dbg"s, "preclip"s, shapefile_name);
}
// Clip the new polygon against what ever has already been created.
tgPolygon clipped = accum.Diff(section);
if (shapefile_name.size()) {
tgShapefile::FromPolygon( clipped, "./airport_dbg", std::string("postclip"), shapefile_name );
tgShapefile::FromPolygon(clipped, "./airport_dbg"s, "postclip"s, shapefile_name);
}
//tgPolygon::RemoveSlivers( clipped, slivers );
// Split long edges to create an object that can better flow with
// the surface terrain
tgPolygon split = tgPolygon::SplitLongEdges(clipped, 400.0);
@ -323,7 +304,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
// Store away what we need to know for texture coordinate
// calculation. (CLO 10/20/02: why can't we calculate texture
// coordinates here? Oh, becuase later we need to massage the
// coordinates here? Oh, because later we need to massage the
// polygons to avoid "T" intersections and clean up other
// potential artifacts and we may add or remove points and need to
// do new texture coordinate calcs later.
@ -337,8 +318,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
split.SetTexLimits(minu, minv, maxu, maxv);
split.SetTexMethod(TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0);
// Create the final output and push on to the runway super_polygon
// list
// Create the final output and push on to the runway super_polygon list
rwy_polys.push_back(split);
}
@ -348,7 +328,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
double startw_pct, double endw_pct,
double minu, double maxu, double minv, double maxv,
double heading,
const string& material,
const std::string& material,
tgpolygon_list& rwy_polys,
tgcontour_list& slivers,
tgAccumulator& accum,
@ -362,29 +342,27 @@ void Runway::gen_runway_section( const tgPolygon& runway,
SGVec2d a2 = SGVec2d(runway.GetNode(0, 0).getLongitudeDeg(), runway.GetNode(0, 0).getLatitudeDeg());
SGVec2d a3 = SGVec2d(runway.GetNode(0, 3).getLongitudeDeg(), runway.GetNode(0, 3).getLatitudeDeg());
if ( startl_pct > 0.0 ) {
if (startl_pct > 0.0)
startl_pct -= nudge * SG_EPSILON;
}
if ( endl_pct < 1.0 ) {
if (startl_pct < 0.0)
startl_pct = 0.0;
if (endl_pct < 1.0)
endl_pct += nudge * SG_EPSILON;
}
if ( endl_pct > 1.0 ) {
if (endl_pct > 1.0)
endl_pct = 1.0;
}
// partial "w" percentages could introduce "T" intersections which
// we compensate for later, but could still cause problems now
// with our polygon clipping code. This attempts to compensate
// for that by nudging the areas a bit bigger so we don't end up
// with polygon slivers.
if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
if (startw_pct > 0.0) {
startw_pct -= nudge * SG_EPSILON;
}
if (endw_pct < 1.0) {
endw_pct += nudge * SG_EPSILON;
}
}
TG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct << " end len % = " << endl_pct);
@ -451,8 +429,6 @@ void Runway::gen_runway_section( const tgPolygon& runway,
// Clip the new polygon against what ever has already been created.
tgPolygon clipped = accum.Diff(section);
//tgPolygon::RemoveSlivers( clipped, slivers );
// Split long edges to create an object that can better flow with
// the surface terrain
tgPolygon split = tgPolygon::SplitLongEdges(clipped, 400.0);
@ -461,7 +437,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
// Store away what we need to know for texture coordinate
// calculation. (CLO 10/20/02: why can't we calculate texture
// coordinates here? Oh, becuase later we need to massage the
// coordinates here? Oh, because later we need to massage the
// polygons to avoid "T" intersections and clean up other
// potential artifacts and we may add or remove points and need to
// do new texture coordinate calcs later.
@ -475,23 +451,24 @@ void Runway::gen_runway_section( const tgPolygon& runway,
split.SetTexLimits(minu, minv, maxu, maxv);
split.SetTexMethod(TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0);
// Create the final output and push on to the runway super_polygon
// list
// Create the final output and push on to the runway super_polygon list
rwy_polys.push_back(split);
}
void Runway::gen_rw_designation( tgPolygon poly, double heading, string rwname,
void Runway::gen_rw_designation(tgPolygon poly, double heading, std::string rwname,
double& start_pct, double& end_pct,
tgpolygon_list& rwy_polys,
tgcontour_list& slivers,
tgAccumulator& accum,
std::string& shapefile_name)
{
using namespace std::string_literals;
if (rwname != "XX") { /* Do not create a designation block if the runway name is set to none */
string letter = "";
std::string letter = ""s;
double length = rwy.length / 2.0;
for (unsigned int i = 0; i < rwname.length(); ++i) {
string tmp = rwname.substr(i, 1);
std::string tmp = rwname.substr(i, 1);
if (tmp == "L" || tmp == "R" || tmp == "C") {
rwname = rwname.substr(0, i);
letter = tmp;
@ -516,23 +493,21 @@ void Runway::gen_rw_designation( tgPolygon poly, double heading, string rwname,
shapefile_name);
}
// create runway designation number(s)
if (rwname == "0") {
if (rwname == "0")
rwname = "36";
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwname);
char tex1[32]; tex1[0] = '\0';
char tex2[32]; tex2[0] = '\0';
std::string tex1;
std::string tex2;
start_pct = end_pct;
end_pct = start_pct + (80.0 * SG_FEET_TO_METER / length);
if (rwname.length() == 2) {
sprintf( tex1, "%c%c", rwname[0], 'l');
sprintf( tex2, "%c%c", rwname[1], 'r');
tex1 = rwname[0] + "l"s;
tex2 = rwname[1] + "r"s;
gen_runway_section(poly,
start_pct, end_pct,
@ -558,7 +533,7 @@ void Runway::gen_rw_designation( tgPolygon poly, double heading, string rwname,
shapefile_name);
} else if (rwname.length() == 1) {
sprintf( tex1, "%c%c", rwname[0], 'c');
tex1 = rwname[0] + "c"s;
gen_runway_section(poly,
start_pct, end_pct,
@ -585,7 +560,7 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
std::string& shapefile_name)
{
TG_LOG(SG_GENERAL, SG_DEBUG, "Building runway = " << rwy.rwnum[0] << " / " << rwy.rwnum[1]);
std::string section_name = "";
std::string section_name {""};
bool debug = shapefile_name.size() != 0;
//
@ -595,7 +570,6 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
tgPolygon runway_half;
for (int rwhalf = 0; rwhalf < 2; ++rwhalf) {
double start1_pct = 0.0;
double end1_pct = 0.0;
double heading = 0.0;
@ -610,8 +584,7 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
runway_half.AddNode(0, runway.GetNode(4));
runway_half.AddNode(0, runway.GetNode(5));
runway_half.AddNode(0, runway.GetNode(2));
}
else {
} else {
heading = rwy.heading;
//Create the second runway half from apt.dat
@ -648,8 +621,7 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// If a runway has a displaced threshold we have to make sure
// it is long enough to build all the features
if (rwy.threshold[rwhalf] > 24.0)
{
if (rwy.threshold[rwhalf] > 24.0) {
// reserve 24m for final arrows
final_arrow = 24.0;
double thresh = rwy.threshold[rwhalf] - final_arrow;
@ -664,7 +636,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// starting (possibly partial chunk)
start1_pct = end1_pct;
end1_pct = start1_pct + (part_len / length);
if ( debug ) { section_name = shapefile_name + "_disp_start"; }
if (debug) {
section_name = shapefile_name + "_disp_start";
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -681,7 +657,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
for (int i = 0; i < count; ++i) {
start1_pct = end1_pct;
end1_pct = start1_pct + (60.0 / length);
if ( debug ) { section_name = shapefile_name + "_disp_" + boost::lexical_cast<std::string>(i); }
if (debug) {
section_name = shapefile_name + "_disp_" + std::to_string(i);
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -699,7 +679,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// final arrows
start1_pct = end1_pct;
end1_pct = start1_pct + (final_arrow / length);
if ( debug ) { section_name = shapefile_name + "_disp_end"; }
if (debug) {
section_name = shapefile_name + "_disp_end";
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -717,7 +701,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// No marking
start1_pct = end1_pct;
end1_pct = start1_pct + (10 / length);
if ( debug ) { section_name = shapefile_name + "_nothresh"; }
if (debug) {
section_name = shapefile_name + "_nothresh";
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -733,7 +721,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// Thresholds for all others
start1_pct = end1_pct;
end1_pct = start1_pct + (202.0 * SG_FEET_TO_METER / length);
if ( debug ) { section_name = shapefile_name + "thresh"; }
if (debug) {
section_name = shapefile_name + "thresh";
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -779,12 +771,19 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
// Now create the marking sections of the runway type
for (unsigned int i = 0; i < rw_marking_list.size(); ++i) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Runway section texture = " << rw_marking_list[i].tex << " start_pct: " << start1_pct << " end_pct: " << end1_pct << " length: " << rw_marking_list[i].size);
TG_LOG(SG_GENERAL, SG_DEBUG, "Runway section texture = " << rw_marking_list[i].tex <<
" start_pct: " << start1_pct <<
" end_pct: " << end1_pct <<
" length: " << rw_marking_list[i].size);
if (end1_pct < 1.0) {
start1_pct = end1_pct;
end1_pct = start1_pct + (rw_marking_list[i].size / length);
if ( debug ) { section_name = shapefile_name + "_" + rw_marking_list[i].tex; }
if (debug) {
section_name = shapefile_name + "_" + rw_marking_list[i].tex;
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -814,7 +813,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
while (end1_pct < 1.0) {
start1_pct = end1_pct;
end1_pct = start1_pct + rest1_inc;
if ( debug ) { section_name = shapefile_name + "rest_" + boost::lexical_cast<std::string>(end1_pct); }
if (debug) {
section_name = shapefile_name + "rest_" + std::to_string(end1_pct);
}
gen_runway_section(runway_half,
start1_pct, end1_pct,
0.0, 1.0,
@ -842,7 +845,11 @@ void Runway::gen_rwy( tgpolygon_list& rwy_polys,
for (int i = 0; i < count; ++i) {
start1_pct = end1_pct;
end1_pct = start1_pct + (part_len / length);
if ( debug ) { section_name = shapefile_name + "stopway"; }
if (debug) {
section_name = shapefile_name + "stopway";
}
gen_runway_section(runway_half,
-end1_pct, -start1_pct,
0.0, 1.0,