Make FGTaxiNode and FGParking inherit FGPositioned.
In preparation for caching the groundnet in the NavCache, make taxi-nodes and parkings inherit from FGPositioned. As part of this, make them heap (as opposed to value) classes, disable their copy-constructors, remove many mutating operations, and give them real constructors.
This commit is contained in:
parent
a2cfef95fb
commit
b1ff365a8f
17 changed files with 504 additions and 730 deletions
|
@ -313,7 +313,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
|||
FGTaxiNode *tn =
|
||||
apt->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
FGAIWaypoint *wpt =
|
||||
createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
|
||||
createOnGround(ac, buffer, tn->geod(), apt->getElevation(),
|
||||
ac->getPerformance()->vTaxi());
|
||||
wpt->setRouteIndex(route);
|
||||
//cerr << "Nodes left " << taxiRoute->nodesLeft() << " ";
|
||||
|
@ -356,7 +356,7 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
|
|||
|
||||
FGParking* parkPos = aAirport->getDynamics()->getParking(gateId);
|
||||
if (parkPos) {
|
||||
wpt = createOnGround(ac, "ENDtaxi", parkPos->getGeod(), airportElev,
|
||||
wpt = createOnGround(ac, "ENDtaxi", parkPos->geod(), airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
|||
snprintf(buffer, 10, "%d", node);
|
||||
FGTaxiNode *tn = gn->findNode(node);
|
||||
FGAIWaypoint *wpt =
|
||||
createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
|
||||
createOnGround(ac, buffer, tn->geod(), apt->getElevation(),
|
||||
ac->getPerformance()->vTaxi());
|
||||
wpt->setRouteIndex(route);
|
||||
pushBackWaypoint(wpt);
|
||||
|
@ -969,14 +969,14 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
if (!tn)
|
||||
break;
|
||||
|
||||
double dist = SGGeodesy::distanceM(coord, tn->getGeod());
|
||||
double dist = SGGeodesy::distanceM(coord, tn->geod());
|
||||
if (dist < (min + 0.75)) {
|
||||
break;
|
||||
}
|
||||
min = dist;
|
||||
}
|
||||
if (tn) {
|
||||
wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
|
||||
wpt = createOnGround(ac, buffer, tn->geod(), currElev, vTaxi);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
|
@ -1024,18 +1024,18 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
|||
double az; // unused
|
||||
SGGeod pos;
|
||||
|
||||
SGGeodesy::direct(parking->getGeod(), heading, 2.2 * parking->getRadius(),
|
||||
SGGeodesy::direct(parking->geod(), heading, 2.2 * parking->getRadius(),
|
||||
pos, az);
|
||||
|
||||
wpt = createOnGround(ac, "taxiStart", pos, aptElev, vTaxiReduced);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
SGGeodesy::direct(parking->getGeod(), heading, 0.1 * parking->getRadius(),
|
||||
SGGeodesy::direct(parking->geod(), heading, 0.1 * parking->getRadius(),
|
||||
pos, az);
|
||||
wpt = createOnGround(ac, "taxiStart2", pos, aptElev, vTaxiReduced);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
wpt = createOnGround(ac, "END-Parking", parking->getGeod(), aptElev,
|
||||
wpt = createOnGround(ac, "END-Parking", parking->geod(), aptElev,
|
||||
vTaxiReduced);
|
||||
pushBackWaypoint(wpt);
|
||||
return true;
|
||||
|
|
|
@ -93,8 +93,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
FGTaxiRoute route;
|
||||
//cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
|
||||
route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
|
||||
parking->setPushBackRoute(new FGTaxiRoute(route));
|
||||
|
||||
parking->setPushBackRoute(std::auto_ptr<FGTaxiRoute>(new FGTaxiRoute(route)));
|
||||
|
||||
pushBackRoute = parking->getPushBackRoute();
|
||||
int size = pushBackRoute->size();
|
||||
|
@ -111,7 +110,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
//ids.pop_back();
|
||||
//wpt = new waypoint;
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->getGeod(), dep->getElevation(), vTaxiBackward);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->geod(), dep->getElevation(), vTaxiBackward);
|
||||
|
||||
wpt->setRouteIndex(rte);
|
||||
pushBackWaypoint(wpt);
|
||||
|
@ -126,34 +125,29 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
|
||||
//cerr << "Creating final push forward point for gate " << gateId << endl;
|
||||
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
|
||||
FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
|
||||
FGTaxiSegmentVectorIterator te = tn->getEndRoute();
|
||||
// if the starting node equals the ending node, then there aren't any routes for this parking.
|
||||
// there aren't any routes for this parking.
|
||||
// in cases like these we should flag the gate as being inoperative and return false
|
||||
if (ts == te) {
|
||||
if (tn->arcs().empty()) {
|
||||
SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
|
||||
parking->setAvailable(false);
|
||||
return false;
|
||||
}
|
||||
tn = (*ts)->getEnd();
|
||||
lastNodeVisited = tn->getIndex();
|
||||
if (tn == NULL) {
|
||||
SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
|
||||
exit(1);
|
||||
}
|
||||
double distance = (*ts)->getLength();
|
||||
|
||||
FGTaxiSegment* pushForwardSegment = tn->arcs().front();
|
||||
lastNodeVisited = pushForwardSegment->getEnd()->getIndex();
|
||||
double distance = pushForwardSegment->getLength();
|
||||
|
||||
double parkingHeading = parking->getHeading();
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
SGGeod pushForwardPt;
|
||||
SGGeodesy::direct(parking->getGeod(), parkingHeading,
|
||||
SGGeodesy::direct(parking->geod(), parkingHeading,
|
||||
((i / 10.0) * distance), pushForwardPt, az2);
|
||||
char buffer[16];
|
||||
snprintf(buffer, 16, "pushback-%02d", i);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), pushForwardPt, dep->getElevation(), vTaxiReduced);
|
||||
|
||||
wpt->setRouteIndex((*ts)->getIndex());
|
||||
wpt->setRouteIndex(pushForwardSegment->getIndex());
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
// cerr << "Done " << endl;
|
||||
|
|
|
@ -1340,10 +1340,10 @@ void FGStartupController::render(bool visible)
|
|||
if (pos > 0) {
|
||||
FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(pos);
|
||||
SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
|
||||
SGGeod end (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude()));
|
||||
SGGeod end (segment->getEnd()->geod());
|
||||
|
||||
double length = SGGeodesy::distanceM(start, end);
|
||||
//heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
|
||||
//heading = SGGeodesy::headingDeg(start->geod(), end->geod());
|
||||
|
||||
double az2, heading; //, distanceM;
|
||||
SGGeodesy::inverse(start, end, heading, az2, length);
|
||||
|
@ -1428,7 +1428,7 @@ void FGStartupController::render(bool visible)
|
|||
double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
double elevationEnd = segment->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
|
||||
SGGeod center2 = segment->getStart()->getGeod();
|
||||
SGGeod center2 = segment->getStart()->geod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
|
||||
//elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
|
||||
|
@ -1440,7 +1440,7 @@ void FGStartupController::render(bool visible)
|
|||
segment->getStart()->setElevation(elevationStart);
|
||||
}
|
||||
if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
|
||||
SGGeod center2 = segment->getEnd()->getGeod();
|
||||
SGGeod center2 = segment->getEnd()->geod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
|
||||
//elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
|
||||
|
@ -1459,8 +1459,9 @@ void FGStartupController::render(bool visible)
|
|||
|
||||
//cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
|
||||
|
||||
|
||||
WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
|
||||
SGGeod segCenter(segment->getCenter());
|
||||
WorldCoordinate( obj_pos, segCenter.getLatitudeDeg(),
|
||||
segCenter.getLongitudeDeg(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
|
||||
|
||||
//WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
|
||||
|
||||
|
|
|
@ -21,8 +21,32 @@
|
|||
|
||||
#include "dynamicloader.hxx"
|
||||
|
||||
/*****************************************************************************
|
||||
* Helper function for parsing position string
|
||||
****************************************************************************/
|
||||
static double processPosition(const string &pos)
|
||||
{
|
||||
string prefix;
|
||||
string subs;
|
||||
string degree;
|
||||
string decimal;
|
||||
int sign = 1;
|
||||
double value;
|
||||
subs = pos;
|
||||
prefix= subs.substr(0,1);
|
||||
if (prefix == string("S") || (prefix == string("W")))
|
||||
sign = -1;
|
||||
subs = subs.substr(1, subs.length());
|
||||
degree = subs.substr(0, subs.find(" ",0));
|
||||
decimal = subs.substr(subs.find(" ",0), subs.length());
|
||||
|
||||
value = sign * (atof(degree.c_str()) + atof(decimal.c_str())/60.0);
|
||||
return value;
|
||||
}
|
||||
|
||||
FGAirportDynamicsXMLLoader::FGAirportDynamicsXMLLoader(FGAirportDynamics* dyn):
|
||||
XMLVisitor(), _dynamics(dyn) {}
|
||||
XMLVisitor(), _dynamics(dyn)
|
||||
{}
|
||||
|
||||
void FGAirportDynamicsXMLLoader::startXML () {
|
||||
//cout << "FGAirportDynamicsLoader::Start XML" << endl;
|
||||
|
@ -32,150 +56,142 @@ void FGAirportDynamicsXMLLoader::endXML () {
|
|||
//cout << "End XML" << endl;
|
||||
}
|
||||
|
||||
void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttributes &atts) {
|
||||
// const char *attval;
|
||||
FGParking park;
|
||||
FGTaxiNode taxiNode;
|
||||
FGTaxiSegment taxiSegment;
|
||||
int index = 0;
|
||||
string idxStr;
|
||||
taxiSegment.setIndex(index);
|
||||
//cout << "Start element " << name << endl;
|
||||
string attname;
|
||||
string value;
|
||||
string gateName;
|
||||
string gateNumber;
|
||||
string attval;
|
||||
string lat;
|
||||
string lon;
|
||||
int holdPointType;
|
||||
int pushBackPoint;
|
||||
|
||||
if (name == string("Parking"))
|
||||
void FGAirportDynamicsXMLLoader::startParking(const XMLAttributes &atts)
|
||||
{
|
||||
pushBackPoint = 0;
|
||||
string type;
|
||||
int index;
|
||||
string gateName, gateNumber;
|
||||
string lat, lon;
|
||||
double heading = 0.0;
|
||||
double radius = 1.0;
|
||||
string airlineCodes;
|
||||
int pushBackRoute = 0;
|
||||
|
||||
for (int i = 0; i < atts.size(); i++)
|
||||
{
|
||||
//cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
|
||||
attname = atts.getName(i);
|
||||
if (attname == string("index")) {
|
||||
park.setIndex(std::atoi(atts.getValue(i)));
|
||||
idxStr = atts.getValue(i);
|
||||
}
|
||||
else if (attname == string("type"))
|
||||
park.setType(atts.getValue(i));
|
||||
else if (attname == string("name"))
|
||||
string attname(atts.getName(i));
|
||||
if (attname == "index") {
|
||||
index = std::atoi(atts.getValue(i));
|
||||
} else if (attname == "type")
|
||||
type = atts.getValue(i);
|
||||
else if (attname == "name")
|
||||
gateName = atts.getValue(i);
|
||||
else if (attname == string("number"))
|
||||
else if (attname == "number")
|
||||
gateNumber = atts.getValue(i);
|
||||
else if (attname == string("lat"))
|
||||
park.setLatitude(atts.getValue(i));
|
||||
else if (attname == string("lon"))
|
||||
park.setLongitude(atts.getValue(i));
|
||||
else if (attname == string("heading"))
|
||||
park.setHeading(std::atof(atts.getValue(i)));
|
||||
else if (attname == string("radius")) {
|
||||
string radius = atts.getValue(i);
|
||||
if (radius.find("M") != string::npos)
|
||||
radius = radius.substr(0, radius.find("M",0));
|
||||
//cerr << "Radius " << radius <<endl;
|
||||
park.setRadius(std::atof(radius.c_str()));
|
||||
else if (attname == "lat")
|
||||
lat = atts.getValue(i);
|
||||
else if (attname == "lon")
|
||||
lon = atts.getValue(i);
|
||||
else if (attname == "heading")
|
||||
heading = std::atof(atts.getValue(i));
|
||||
else if (attname == "radius") {
|
||||
string radiusStr = atts.getValue(i);
|
||||
if (radiusStr.find("M") != string::npos)
|
||||
radiusStr = radiusStr.substr(0, radiusStr.find("M",0));
|
||||
radius = std::atof(radiusStr.c_str());
|
||||
}
|
||||
else if (attname == "airlineCodes")
|
||||
airlineCodes = atts.getValue(i);
|
||||
else if (attname == "pushBackRoute") {
|
||||
pushBackRoute = std::atoi(atts.getValue(i));
|
||||
}
|
||||
}
|
||||
else if (attname == string("airlineCodes"))
|
||||
park.setCodes(atts.getValue(i));
|
||||
else if (attname == string("pushBackRoute")) {
|
||||
pushBackPoint = std::atoi(atts.getValue(i));
|
||||
//park.setPushBackPoint(std::atoi(atts.getValue(i)));
|
||||
|
||||
SGGeod pos(SGGeod::fromDeg(processPosition(lon), processPosition(lat)));
|
||||
|
||||
FGParking* pk = new FGParking(0, index, pos, heading, radius,
|
||||
gateName + gateNumber, type, airlineCodes);
|
||||
pk->setPushBackPoint(pushBackRoute);
|
||||
_dynamics->addParking(pk);
|
||||
}
|
||||
}
|
||||
park.setPushBackPoint(pushBackPoint);
|
||||
park.setName((gateName+gateNumber));
|
||||
//cerr << "Parking " << idxStr << "( " << gateName << gateNumber << ") has pushBackPoint " << pushBackPoint << endl;
|
||||
_dynamics->addParking(park);
|
||||
}
|
||||
if (name == string("node"))
|
||||
|
||||
void FGAirportDynamicsXMLLoader::startNode(const XMLAttributes &atts)
|
||||
{
|
||||
int index;
|
||||
string lat, lon;
|
||||
bool onRunway;
|
||||
int holdPointType;
|
||||
|
||||
for (int i = 0; i < atts.size() ; i++)
|
||||
{
|
||||
attname = atts.getName(i);
|
||||
if (attname == string("index"))
|
||||
taxiNode.setIndex(std::atoi(atts.getValue(i)));
|
||||
if (attname == string("lat"))
|
||||
taxiNode.setLatitude(atts.getValue(i));
|
||||
if (attname == string("lon"))
|
||||
taxiNode.setLongitude(atts.getValue(i));
|
||||
if (attname == string("isOnRunway"))
|
||||
taxiNode.setOnRunway((bool) std::atoi(atts.getValue(i)));
|
||||
if (attname == string("holdPointType")) {
|
||||
attval = atts.getValue(i);
|
||||
if (attval==string("none")) {
|
||||
string attname(atts.getName(i));
|
||||
if (attname == "index")
|
||||
index = std::atoi(atts.getValue(i));
|
||||
else if (attname == "lat")
|
||||
lat = atts.getValue(i);
|
||||
else if (attname == "lon")
|
||||
lon = atts.getValue(i);
|
||||
else if (attname == "isOnRunway")
|
||||
onRunway = (bool) std::atoi(atts.getValue(i));
|
||||
else if (attname == "holdPointType") {
|
||||
string attval = atts.getValue(i);
|
||||
if (attval=="none") {
|
||||
holdPointType=0;
|
||||
} else if (attval==string("normal")) {
|
||||
} else if (attval=="normal") {
|
||||
holdPointType=1;
|
||||
} else if (attval==string("CAT II/III")) {
|
||||
} else if (attval=="CAT II/III") {
|
||||
holdPointType=3;
|
||||
} else if (attval==string("PushBack")) {
|
||||
} else if (attval=="PushBack") {
|
||||
holdPointType=3;
|
||||
} else {
|
||||
holdPointType=0;
|
||||
}
|
||||
//cerr << "Setting Holding point to " << holdPointType << endl;
|
||||
taxiNode.setHoldPointType(holdPointType);
|
||||
}
|
||||
}
|
||||
|
||||
SGGeod pos(SGGeod::fromDeg(processPosition(lon), processPosition(lat)));
|
||||
FGTaxiNode* taxiNode = new FGTaxiNode(0, index, pos, onRunway, holdPointType);
|
||||
_dynamics->getGroundNetwork()->addNode(taxiNode);
|
||||
}
|
||||
if (name == string("arc"))
|
||||
|
||||
void FGAirportDynamicsXMLLoader::startArc(const XMLAttributes &atts)
|
||||
{
|
||||
taxiSegment.setIndex(++index);
|
||||
int begin, end;
|
||||
bool isPushBackRoute = false;
|
||||
|
||||
for (int i = 0; i < atts.size() ; i++)
|
||||
{
|
||||
attname = atts.getName(i);
|
||||
if (attname == string("begin"))
|
||||
taxiSegment.setStartNodeRef(std::atoi(atts.getValue(i)));
|
||||
if (attname == string("end"))
|
||||
taxiSegment.setEndNodeRef(std::atoi(atts.getValue(i)));
|
||||
if (attname == string("isPushBackRoute"))
|
||||
taxiSegment.setPushBackType((bool) std::atoi(atts.getValue(i)));
|
||||
}
|
||||
_dynamics->getGroundNetwork()->addSegment(taxiSegment);
|
||||
}
|
||||
// sort by radius, in asending order, so that smaller gates are first in the list
|
||||
string attname = atts.getName(i);
|
||||
if (attname == "begin")
|
||||
begin = std::atoi(atts.getValue(i));
|
||||
else if (attname == "end")
|
||||
end = std::atoi(atts.getValue(i));
|
||||
else if (attname == "isPushBackRoute")
|
||||
isPushBackRoute = (bool) std::atoi(atts.getValue(i));
|
||||
}
|
||||
|
||||
void FGAirportDynamicsXMLLoader::endElement (const char * name) {
|
||||
//cout << "End element " << name << endl;
|
||||
if (name == string("version")) {
|
||||
_dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
|
||||
//std::cerr << "version" << value<< std::endl;
|
||||
}
|
||||
if (name == string("AWOS")) {
|
||||
_dynamics->addAwosFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding AWOS" << value<< endl;
|
||||
}
|
||||
if (name == string("UNICOM")) {
|
||||
_dynamics->addUnicomFreq(atoi(value.c_str()));
|
||||
//cerr << "UNICOM" << value<< endl;
|
||||
}
|
||||
if (name == string("CLEARANCE")) {
|
||||
_dynamics->addClearanceFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding CLEARANCE" << value<< endl;
|
||||
}
|
||||
if (name == string("GROUND")) {
|
||||
_dynamics->addGroundFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding GROUND" << value<< endl;
|
||||
_dynamics->getGroundNetwork()->addSegment(new FGTaxiSegment(begin, end, isPushBackRoute));
|
||||
}
|
||||
|
||||
if (name == string("TOWER")) {
|
||||
_dynamics->addTowerFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding TOWER" << value<< endl;
|
||||
void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttributes &atts)
|
||||
{
|
||||
if (!strcmp("Parking", name)) {
|
||||
startParking(atts);
|
||||
} else if (!strcmp("node", name)) {
|
||||
startNode(atts);
|
||||
} else if (!strcmp("arc", name)) {
|
||||
startArc(atts);
|
||||
}
|
||||
if (name == string("APPROACH")) {
|
||||
_dynamics->addApproachFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding approach" << value<< endl;
|
||||
}
|
||||
|
||||
void FGAirportDynamicsXMLLoader::endElement (const char * name)
|
||||
{
|
||||
int valueAsInt = atoi(value.c_str());
|
||||
if (!strcmp("version", name)) {
|
||||
_dynamics->getGroundNetwork()->addVersion(valueAsInt);
|
||||
} else if (!strcmp("AWOS", name)) {
|
||||
_dynamics->addAwosFreq(valueAsInt);
|
||||
} else if (!strcmp("UNICOM", name)) {
|
||||
_dynamics->addUnicomFreq(valueAsInt);
|
||||
} else if (!strcmp("CLEARANCE", name)) {
|
||||
_dynamics->addClearanceFreq(valueAsInt);
|
||||
} else if (!strcmp("GROUND", name)) {
|
||||
_dynamics->addGroundFreq(valueAsInt);
|
||||
} else if (!strcmp("TOWER", name)) {
|
||||
_dynamics->addTowerFreq(valueAsInt);
|
||||
} else if (!strcmp("APPROACH", name)) {
|
||||
_dynamics->addApproachFreq(valueAsInt);
|
||||
}
|
||||
}
|
||||
|
||||
void FGAirportDynamicsXMLLoader::data (const char * s, int len) {
|
||||
|
|
|
@ -35,6 +35,10 @@ protected:
|
|||
virtual void error (const char * message, int line, int column);
|
||||
|
||||
private:
|
||||
void startParking(const XMLAttributes &atts);
|
||||
void startNode(const XMLAttributes &atts);
|
||||
void startArc(const XMLAttributes &atts);
|
||||
|
||||
FGAirportDynamics* _dynamics;
|
||||
string value;
|
||||
};
|
||||
|
|
|
@ -91,8 +91,7 @@ int FGAirportDynamics::innerGetAvailableParking(double radius, const string & fl
|
|||
const string & airline,
|
||||
bool skipEmptyAirlineCode)
|
||||
{
|
||||
FGParkingVecIterator i;
|
||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
||||
BOOST_FOREACH(FGParking* i, parkings) {
|
||||
// Taken by another aircraft, or no airline codes
|
||||
if (!i->isAvailable()) {
|
||||
continue;
|
||||
|
@ -151,32 +150,29 @@ int FGAirportDynamics::getAvailableParking(double radius, const string & flType,
|
|||
|
||||
FGParking *FGAirportDynamics::getParking(int id)
|
||||
{
|
||||
FGParkingVecIterator i = parkings.begin();
|
||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
||||
BOOST_FOREACH(FGParking* i, parkings) {
|
||||
if (id == i->getIndex()) {
|
||||
return &(*i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string FGAirportDynamics::getParkingName(int id)
|
||||
{
|
||||
FGParkingVecIterator i = parkings.begin();
|
||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
||||
if (id == i->getIndex()) {
|
||||
return i->getName();
|
||||
}
|
||||
FGParking* p = getParking(id);
|
||||
if (p) {
|
||||
return p->getName();
|
||||
}
|
||||
|
||||
return string("overflow");
|
||||
return string();
|
||||
}
|
||||
|
||||
int FGAirportDynamics::findParkingByName(const std::string& name) const
|
||||
{
|
||||
FGParkingVec::const_iterator i = parkings.begin();
|
||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
||||
if (i->getName() == name) {
|
||||
BOOST_FOREACH(FGParking* i, parkings) {
|
||||
if (name == i->getName()) {
|
||||
return i->getIndex();
|
||||
}
|
||||
}
|
||||
|
@ -187,12 +183,9 @@ int FGAirportDynamics::findParkingByName(const std::string& name) const
|
|||
void FGAirportDynamics::releaseParking(int id)
|
||||
{
|
||||
if (id >= 0) {
|
||||
|
||||
FGParkingVecIterator i = parkings.begin();
|
||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
||||
if (id == i->getIndex()) {
|
||||
i->setAvailable(true);
|
||||
}
|
||||
FGParking* parking = getParking(id);
|
||||
if (parking) {
|
||||
parking->setAvailable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +373,7 @@ string FGAirportDynamics::chooseRunwayFallback()
|
|||
return rwy->ident();
|
||||
}
|
||||
|
||||
void FGAirportDynamics::addParking(FGParking & park)
|
||||
void FGAirportDynamics::addParking(FGParking* park)
|
||||
{
|
||||
parkings.push_back(park);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
|
||||
void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
|
||||
|
||||
void addParking(FGParking& park);
|
||||
void addParking(FGParking* park);
|
||||
|
||||
/**
|
||||
* retrieve an available parking by GateID, or -1 if no suitable
|
||||
|
|
|
@ -1,99 +1,63 @@
|
|||
#include "gnnode.hxx"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "groundnetwork.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
using std::sort;
|
||||
using std::string;
|
||||
|
||||
/*****************************************************************************
|
||||
* Helper function for parsing position string
|
||||
****************************************************************************/
|
||||
double processPosition(const string &pos)
|
||||
{
|
||||
string prefix;
|
||||
string subs;
|
||||
string degree;
|
||||
string decimal;
|
||||
int sign = 1;
|
||||
double value;
|
||||
subs = pos;
|
||||
prefix= subs.substr(0,1);
|
||||
if (prefix == string("S") || (prefix == string("W")))
|
||||
sign = -1;
|
||||
subs = subs.substr(1, subs.length());
|
||||
degree = subs.substr(0, subs.find(" ",0));
|
||||
decimal = subs.substr(subs.find(" ",0), subs.length());
|
||||
|
||||
|
||||
//cerr << sign << " "<< degree << " " << decimal << endl;
|
||||
value = sign * (atof(degree.c_str()) + atof(decimal.c_str())/60.0);
|
||||
//cerr << value <<endl;
|
||||
//exit(1);
|
||||
return value;
|
||||
}
|
||||
|
||||
//bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
|
||||
// return a->hasSmallerHeadingDiff(*b);
|
||||
//}
|
||||
|
||||
bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
|
||||
return a->getLength() > b->getLength();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* FGTaxiNode
|
||||
*************************************************************************/
|
||||
|
||||
FGTaxiNode::FGTaxiNode(PositionedID aGuid, int index, const SGGeod& pos, bool aOnRunway, int aHoldType) :
|
||||
FGPositioned(aGuid, FGPositioned::PARKING, "", pos),
|
||||
index(index),
|
||||
isOnRunway(aOnRunway),
|
||||
holdType(aHoldType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FGTaxiNode::~FGTaxiNode()
|
||||
{
|
||||
}
|
||||
|
||||
void FGTaxiNode::setElevation(double val)
|
||||
{
|
||||
geod.setElevationM(val);
|
||||
}
|
||||
|
||||
void FGTaxiNode::setLatitude (double val)
|
||||
{
|
||||
geod.setLatitudeDeg(val);
|
||||
}
|
||||
|
||||
void FGTaxiNode::setLongitude(double val)
|
||||
{
|
||||
geod.setLongitudeDeg(val);
|
||||
}
|
||||
|
||||
void FGTaxiNode::setLatitude (const string& val)
|
||||
{
|
||||
geod.setLatitudeDeg(processPosition(val));
|
||||
}
|
||||
|
||||
void FGTaxiNode::setLongitude(const string& val)
|
||||
{
|
||||
geod.setLongitudeDeg(processPosition(val));
|
||||
// ignored for the moment
|
||||
}
|
||||
|
||||
double FGTaxiNode::getElevationFt(double refelev)
|
||||
{
|
||||
double elevF = geod.getElevationFt();
|
||||
double elevF = elevation();
|
||||
#if 0
|
||||
double elevationEnd = 0;
|
||||
if ((elevF == 0) || (elevF == refelev)) {
|
||||
SGGeod center2 = geod;
|
||||
SGGeod center2 = mPosition;
|
||||
FGScenery * local_scenery = globals->get_scenery();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
|
||||
geod.setElevationM(elevationEnd);
|
||||
}
|
||||
}
|
||||
//cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (feet) = " << refelev << endl;
|
||||
return geod.getElevationFt();
|
||||
#endif
|
||||
return mPosition.getElevationFt();
|
||||
}
|
||||
|
||||
double FGTaxiNode::getElevationM(double refelev)
|
||||
{
|
||||
//double refelevFt = refelev * SG_METER_TO_FEET;
|
||||
//double retval = getElevationFt(refelevFt);
|
||||
//cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (meters) = " << refelev << endl;
|
||||
return geod.getElevationM();
|
||||
return geod().getElevationM();
|
||||
}
|
||||
|
||||
FGTaxiSegment* FGTaxiNode::getArcTo(FGTaxiNode* aEnd) const
|
||||
{
|
||||
BOOST_FOREACH(FGTaxiSegment* arc, next) {
|
||||
if (arc->getEnd() == aEnd) {
|
||||
return arc;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -20,76 +20,39 @@
|
|||
#include <string>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
#include <Navaids/positioned.hxx>
|
||||
|
||||
class FGTaxiSegment;
|
||||
|
||||
typedef std::vector<FGTaxiSegment*> FGTaxiSegmentVector;
|
||||
typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator;
|
||||
|
||||
bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b);
|
||||
bool sortByLength (FGTaxiSegment *a, FGTaxiSegment *b);
|
||||
|
||||
class FGTaxiNode
|
||||
class FGTaxiNode : public FGPositioned
|
||||
{
|
||||
protected:
|
||||
SGGeod geod;
|
||||
int index;
|
||||
|
||||
bool isOnRunway;
|
||||
int holdType;
|
||||
FGTaxiSegmentVector next; // a vector of pointers to all the segments leaving from this node
|
||||
|
||||
// used in way finding
|
||||
// used in way finding - should really move to a dynamic struct
|
||||
double pathScore;
|
||||
FGTaxiNode* previousNode;
|
||||
FGTaxiSegment* previousSeg;
|
||||
|
||||
|
||||
public:
|
||||
FGTaxiNode() :
|
||||
index(0),
|
||||
isOnRunway(false),
|
||||
holdType(0),
|
||||
pathScore(0),
|
||||
previousNode(0),
|
||||
previousSeg(0)
|
||||
{
|
||||
};
|
||||
FGTaxiNode(PositionedID aGuid, int index, const SGGeod& pos, bool aOnRunway, int aHoldType);
|
||||
virtual ~FGTaxiNode();
|
||||
|
||||
FGTaxiNode(const FGTaxiNode &other) :
|
||||
geod(other.geod),
|
||||
index(other.index),
|
||||
isOnRunway(other.isOnRunway),
|
||||
holdType(other.holdType),
|
||||
next(other.next),
|
||||
pathScore(other.pathScore),
|
||||
previousNode(other.previousNode),
|
||||
previousSeg(other.previousSeg)
|
||||
{
|
||||
};
|
||||
|
||||
FGTaxiNode &operator =(const FGTaxiNode &other)
|
||||
{
|
||||
geod = other.geod;
|
||||
index = other.index;
|
||||
isOnRunway = other.isOnRunway;
|
||||
holdType = other.holdType;
|
||||
next = other.next;
|
||||
pathScore = other.pathScore;
|
||||
previousNode = other.previousNode;
|
||||
previousSeg = other.previousSeg;
|
||||
return *this;
|
||||
};
|
||||
|
||||
void setIndex(int idx) { index = idx; };
|
||||
void setLatitude (double val);
|
||||
void setLongitude(double val);
|
||||
void setElevation(double val);
|
||||
void setLatitude (const std::string& val);
|
||||
void setLongitude(const std::string& val);
|
||||
void addSegment(FGTaxiSegment *segment) { next.push_back(segment); };
|
||||
void setHoldPointType(int val) { holdType = val; };
|
||||
void setOnRunway(bool val) { isOnRunway = val; };
|
||||
|
||||
void setPathScore (double val) { pathScore = val; };
|
||||
void setPreviousNode(FGTaxiNode *val) { previousNode = val; };
|
||||
|
@ -99,26 +62,28 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
|
|||
FGTaxiSegment *getPreviousSegment() { return previousSeg; };
|
||||
|
||||
double getPathScore() { return pathScore; };
|
||||
double getLatitude() { return geod.getLatitudeDeg();};
|
||||
double getLongitude(){ return geod.getLongitudeDeg();};
|
||||
double getElevationM (double refelev=0);
|
||||
double getElevationFt(double refelev=0);
|
||||
|
||||
const SGGeod& getGeod() const { return geod; }
|
||||
double getElevationM (double refelev);
|
||||
double getElevationFt(double refelev);
|
||||
|
||||
int getIndex() const { return index; };
|
||||
int getHoldPointType() const { return holdType; };
|
||||
bool getIsOnRunway() const { return isOnRunway; };
|
||||
|
||||
FGTaxiNode *getAddress() { return this;};
|
||||
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
|
||||
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
|
||||
const FGTaxiSegmentVector& arcs() const
|
||||
{ return next; }
|
||||
|
||||
/// find the arg which leads from this node to another.
|
||||
/// returns NULL if no such arc exists.
|
||||
FGTaxiSegment* getArcTo(FGTaxiNode* aEnd) const;
|
||||
|
||||
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<FGTaxiNode*> FGTaxiNodeVector;
|
||||
typedef SGSharedPtr<FGTaxiNode> FGTaxiNode_ptr;
|
||||
typedef std::vector<FGTaxiNode_ptr> FGTaxiNodeVector;
|
||||
typedef FGTaxiNodeVector::iterator FGTaxiNodeVectorIterator;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/scene/util/OsgMath.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Airports/simple.hxx>
|
||||
#include <Airports/dynamics.hxx>
|
||||
|
@ -59,64 +60,47 @@ using std::string;
|
|||
* FGTaxiSegment
|
||||
**************************************************************************/
|
||||
|
||||
void FGTaxiSegment::setStart(FGTaxiNodeVector * nodes)
|
||||
FGTaxiSegment::FGTaxiSegment(int aStart, int aEnd, bool isPushBack) :
|
||||
startNode(aStart),
|
||||
endNode(aEnd),
|
||||
length(0),
|
||||
heading(0),
|
||||
isActive(0),
|
||||
isPushBackRoute(isPushBack),
|
||||
start(0),
|
||||
end(0),
|
||||
index(0),
|
||||
oppositeDirection(0)
|
||||
{
|
||||
FGTaxiNodeVectorIterator i = nodes->begin();
|
||||
while (i != nodes->end()) {
|
||||
//cerr << "Scanning start node index" << (*i)->getIndex() << endl;
|
||||
if ((*i)->getIndex() == startNode) {
|
||||
start = (*i)->getAddress();
|
||||
(*i)->addSegment(this);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Could not find start node " << startNode << endl);
|
||||
}
|
||||
};
|
||||
|
||||
void FGTaxiSegment::setEnd(FGTaxiNodeVector * nodes)
|
||||
bool FGTaxiSegment::bindToNodes(const IndexTaxiNodeMap& nodes)
|
||||
{
|
||||
FGTaxiNodeVectorIterator i = nodes->begin();
|
||||
while (i != nodes->end()) {
|
||||
//cerr << "Scanning end node index" << (*i)->getIndex() << endl;
|
||||
if ((*i)->getIndex() == endNode) {
|
||||
end = (*i)->getAddress();
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Could not find end node " << endNode << endl);
|
||||
IndexTaxiNodeMap::const_iterator it = nodes.find(startNode);
|
||||
if (it == nodes.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
start = it->second;
|
||||
|
||||
it = nodes.find(endNode);
|
||||
if (it == nodes.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// There is probably a computationally cheaper way of
|
||||
// doing this.
|
||||
void FGTaxiSegment::setDimensions(double elevation)
|
||||
end = it->second;
|
||||
|
||||
start->addSegment(this);
|
||||
double az2;
|
||||
SGGeodesy::inverse(start->geod(), end->geod(), heading, az2, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
SGGeod FGTaxiSegment::getCenter() const
|
||||
{
|
||||
length = SGGeodesy::distanceM(start->getGeod(), end->getGeod());
|
||||
//heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
|
||||
|
||||
double az2; //, distanceM;
|
||||
SGGeodesy::inverse(start->getGeod(), end->getGeod(), heading, az2, length);
|
||||
double coveredDistance = length * 0.5;
|
||||
SGGeodesy::direct(start->getGeod(), heading, coveredDistance, center, az2);
|
||||
//start->setElevation(elevation);
|
||||
//end->setElevation(elevation);
|
||||
//cerr << "Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
|
||||
return SGGeodesy::direct(start->geod(), heading, length * 0.5);
|
||||
}
|
||||
|
||||
|
||||
//void FGTaxiSegment::setCourseDiff(double crse)
|
||||
//{
|
||||
// headingDiff = fabs(course - crse);
|
||||
|
||||
// if (headingDiff > 180)
|
||||
// headingDiff = fabs(headingDiff - 360);
|
||||
//}
|
||||
|
||||
void FGTaxiSegment::block(int id, time_t blockTime, time_t now)
|
||||
{
|
||||
BlockListIterator i = blockTimes.begin();
|
||||
|
@ -193,7 +177,7 @@ bool FGTaxiRoute::next(int *nde, int *rte)
|
|||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"ALERT: Misconfigured TaxiRoute : " << nodes.
|
||||
size() << " " << routes.size());
|
||||
exit(1);
|
||||
throw sg_range_exception("misconfigured taxi route");
|
||||
}
|
||||
if (currNode == nodes.end())
|
||||
return false;
|
||||
|
@ -237,15 +221,6 @@ void FGTaxiRoute::rewind(int route)
|
|||
/***************************************************************************
|
||||
* FGGroundNetwork()
|
||||
**************************************************************************/
|
||||
bool compare_nodes(FGTaxiNode * a, FGTaxiNode * b)
|
||||
{
|
||||
return (*a) < (*b);
|
||||
}
|
||||
|
||||
bool compare_segments(FGTaxiSegment * a, FGTaxiSegment * b)
|
||||
{
|
||||
return (*a) < (*b);
|
||||
}
|
||||
|
||||
bool compare_trafficrecords(FGTrafficRecord a, FGTrafficRecord b)
|
||||
{
|
||||
|
@ -344,11 +319,11 @@ void FGGroundNetwork::saveElevationCache() {
|
|||
}
|
||||
}
|
||||
cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
|
||||
for (FGTaxiNodeVectorIterator node = nodes.begin();
|
||||
for (IndexTaxiNodeMap::iterator node = nodes.begin();
|
||||
node != nodes.end(); node++) {
|
||||
if (saveData) {
|
||||
cachefile << (*node)->getIndex () << " "
|
||||
<< (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
|
||||
cachefile << node->second->getIndex () << " "
|
||||
<< node->second->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
@ -357,33 +332,29 @@ void FGGroundNetwork::saveElevationCache() {
|
|||
}
|
||||
}
|
||||
|
||||
void FGGroundNetwork::addSegment(const FGTaxiSegment & seg)
|
||||
void FGGroundNetwork::addSegment(FGTaxiSegment* seg)
|
||||
{
|
||||
segments.push_back(new FGTaxiSegment(seg));
|
||||
segments.push_back(seg);
|
||||
}
|
||||
|
||||
void FGGroundNetwork::addNode(const FGTaxiNode & node)
|
||||
void FGGroundNetwork::addNode(FGTaxiNode* node)
|
||||
{
|
||||
nodes.push_back(new FGTaxiNode(node));
|
||||
assert(node);
|
||||
IndexTaxiNodeMap::iterator it = nodes.find(node->getIndex());
|
||||
if (it != nodes.end()) {
|
||||
throw sg_range_exception();
|
||||
}
|
||||
|
||||
nodes.insert(it, std::make_pair(node->getIndex(), node));
|
||||
}
|
||||
|
||||
void FGGroundNetwork::addNodes(FGParkingVec * parkings)
|
||||
{
|
||||
FGTaxiNode n;
|
||||
FGParkingVecIterator i = parkings->begin();
|
||||
while (i != parkings->end()) {
|
||||
n.setIndex(i->getIndex());
|
||||
n.setLatitude(i->getLatitude());
|
||||
n.setLongitude(i->getLongitude());
|
||||
n.setElevation(parent->getElevation()*SG_FEET_TO_METER);
|
||||
nodes.push_back(new FGTaxiNode(n));
|
||||
|
||||
i++;
|
||||
BOOST_FOREACH(FGParking* parking, *parkings) {
|
||||
addNode(parking);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGGroundNetwork::init()
|
||||
{
|
||||
if (networkInitialized) {
|
||||
|
@ -394,59 +365,44 @@ void FGGroundNetwork::init()
|
|||
hasNetwork = true;
|
||||
nextSave = 0;
|
||||
int index = 1;
|
||||
sort(nodes.begin(), nodes.end(), compare_nodes);
|
||||
//sort(segments.begin(), segments.end(), compare_segments());
|
||||
FGTaxiSegmentVectorIterator i = segments.begin();
|
||||
while (i != segments.end()) {
|
||||
(*i)->setStart(&nodes);
|
||||
(*i)->setEnd(&nodes);
|
||||
(*i)->setDimensions(parent->getElevation() * SG_FEET_TO_METER);
|
||||
(*i)->setIndex(index);
|
||||
if ((*i)->isPushBack()) {
|
||||
pushBackNodes.push_back((*i)->getEnd());
|
||||
}
|
||||
//SG_LOG(SG_GENERAL, SG_BULK, "initializing segment " << (*i)->getIndex() << endl);
|
||||
//SG_LOG(SG_GENERAL, SG_BULK, "Track distance = " << (*i)->getLength() << endl);
|
||||
//SG_LOG(SG_GENERAL, SG_BULK, "Track runs from " << (*i)->getStart()->getIndex() << " to "
|
||||
// << (*i)->getEnd()->getIndex() << endl);
|
||||
i++;
|
||||
index++;
|
||||
|
||||
// bind segments to nodes
|
||||
BOOST_FOREACH(FGTaxiSegment* segment, segments) {
|
||||
if (!segment->bindToNodes(nodes)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "unable to bind taxiway segment");
|
||||
}
|
||||
|
||||
i = segments.begin();
|
||||
while (i != segments.end()) {
|
||||
FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute();
|
||||
while (j != (*i)->getEnd()->getEndRoute()) {
|
||||
if ((*j)->getEnd()->getIndex() == (*i)->getStart()->getIndex()) {
|
||||
// int start1 = (*i)->getStart()->getIndex();
|
||||
// int end1 = (*i)->getEnd() ->getIndex();
|
||||
// int start2 = (*j)->getStart()->getIndex();
|
||||
// int end2 = (*j)->getEnd()->getIndex();
|
||||
// int oppIndex = (*j)->getIndex();
|
||||
//cerr << "Opposite of " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
|
||||
// << "happens to be " << oppIndex << " (" << start2 << "," << end2 << ") " << endl;
|
||||
(*i)->setOpposite(*j);
|
||||
break;
|
||||
segment->setIndex(index++);
|
||||
if (segment->isPushBack()) {
|
||||
pushBackNodes.push_back(segment->getEnd());
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
|
||||
// establish pairing of segments
|
||||
BOOST_FOREACH(FGTaxiSegment* segment, segments) {
|
||||
FGTaxiSegment* opp = segment->getEnd()->getArcTo(segment->getStart());
|
||||
if (opp) {
|
||||
segment->setOpposite(opp);
|
||||
}
|
||||
//FGTaxiNodeVectorIterator j = nodes.begin();
|
||||
//while (j != nodes.end()) {
|
||||
// if ((*j)->getHoldPointType() == 3) {
|
||||
// pushBackNodes.push_back((*j));
|
||||
// }
|
||||
// j++;
|
||||
//}
|
||||
//cerr << "Done initializing ground network" << endl;
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
if (fgGetBool("/sim/ai/groundnet-cache")) {
|
||||
parseCache();
|
||||
}
|
||||
|
||||
networkInitialized = true;
|
||||
}
|
||||
|
||||
void FGGroundNetwork::parseCache()
|
||||
{
|
||||
SGPath cacheData(globals->get_fg_home());
|
||||
cacheData.append("ai");
|
||||
string airport = parent->getId();
|
||||
|
||||
if ((airport) != "") {
|
||||
if (airport.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
::snprintf(buffer, 128, "%c/%c/%c/",
|
||||
airport[0], airport[1], airport[2]);
|
||||
|
@ -465,39 +421,34 @@ void FGGroundNetwork::init()
|
|||
SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
|
||||
cacheData.c_str() << " for Airport " << airport);
|
||||
} else {
|
||||
for (FGTaxiNodeVectorIterator i = nodes.begin();
|
||||
for (IndexTaxiNodeMap::iterator i = nodes.begin();
|
||||
i != nodes.end();
|
||||
i++) {
|
||||
(*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
|
||||
i->second->setElevation(parent->elevation() * SG_FEET_TO_METER);
|
||||
data >> index >> elev;
|
||||
if (data.eof())
|
||||
break;
|
||||
if (index != (*i)->getIndex()) {
|
||||
if (index != i->second->getIndex()) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
|
||||
} else {
|
||||
(*i)->setElevation(elev);
|
||||
i->second->setElevation(elev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//cerr << "Finished initializing " << parent->getId() << " groundnetwork " << endl;
|
||||
networkInitialized = true;
|
||||
}
|
||||
|
||||
int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
|
||||
{
|
||||
double minDist = HUGE_VAL;
|
||||
int index = -1;
|
||||
|
||||
for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
|
||||
itr++) {
|
||||
double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
|
||||
IndexTaxiNodeMap::iterator i;
|
||||
for (i = nodes.begin(); i != nodes.end(); i++) {
|
||||
double d = SGGeodesy::distanceM(aGeod, i->second->geod());
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
index = (*itr)->getIndex();
|
||||
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
||||
index = i->first;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,42 +460,30 @@ int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
|
|||
double minDist = HUGE_VAL;
|
||||
int index = -1;
|
||||
|
||||
for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
|
||||
itr++) {
|
||||
if (!((*itr)->getIsOnRunway())) {
|
||||
IndexTaxiNodeMap::iterator i;
|
||||
for (i = nodes.begin(); i != nodes.end(); i++) {
|
||||
if (!i->second->getIsOnRunway()) {
|
||||
continue;
|
||||
}
|
||||
double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
|
||||
|
||||
double d = SGGeodesy::distanceM(aGeod, i->second->geod());
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
index = (*itr)->getIndex();
|
||||
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
||||
index = i->first;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
||||
FGTaxiNode* FGGroundNetwork::findNode(unsigned int idx)
|
||||
{
|
||||
return findNearestNode(SGGeod::fromDeg(lon, lat));
|
||||
IndexTaxiNodeMap::iterator i = nodes.find(idx);
|
||||
if (i == nodes.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FGTaxiNode *FGGroundNetwork::findNode(unsigned idx)
|
||||
{ /*
|
||||
for (FGTaxiNodeVectorIterator
|
||||
itr = nodes.begin();
|
||||
itr != nodes.end(); itr++)
|
||||
{
|
||||
if (itr->getIndex() == idx)
|
||||
return itr->getAddress();
|
||||
} */
|
||||
|
||||
if (idx < nodes.size())
|
||||
return nodes[idx]->getAddress();
|
||||
else
|
||||
return 0;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
|
||||
|
@ -558,7 +497,7 @@ FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
|
|||
}
|
||||
*/
|
||||
if ((idx > 0) && (idx <= segments.size()))
|
||||
return segments[idx - 1]->getAddress();
|
||||
return segments[idx - 1];
|
||||
else {
|
||||
//cerr << "Alert: trying to find invalid segment " << idx << endl;
|
||||
return 0;
|
||||
|
@ -575,18 +514,22 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
|
|||
//double INFINITE = 100000000000.0;
|
||||
// initialize scoring values
|
||||
int nParkings = parent->getDynamics()->getNrOfParkings();
|
||||
FGTaxiNodeVector *currNodesSet;
|
||||
FGTaxiNodeVector unvisited;
|
||||
|
||||
if (fullSearch) {
|
||||
currNodesSet = &nodes;
|
||||
// create vector from map values
|
||||
IndexTaxiNodeMap::iterator i;
|
||||
for (i = nodes.begin(); i != nodes.end(); i++) {
|
||||
unvisited.push_back(i->second);
|
||||
}
|
||||
} else {
|
||||
currNodesSet = &pushBackNodes;
|
||||
unvisited = pushBackNodes;
|
||||
}
|
||||
|
||||
for (FGTaxiNodeVectorIterator
|
||||
itr = currNodesSet->begin(); itr != currNodesSet->end(); itr++) {
|
||||
(*itr)->setPathScore(HUGE_VAL); //infinity by all practical means
|
||||
(*itr)->setPreviousNode(0); //
|
||||
(*itr)->setPreviousSeg(0); //
|
||||
BOOST_FOREACH(FGTaxiNode* node, unvisited) {
|
||||
node->setPathScore(HUGE_VAL); //infinity by all practical means
|
||||
node->setPreviousNode(0); //
|
||||
node->setPreviousSeg(0); //
|
||||
}
|
||||
|
||||
FGTaxiNode *firstNode = findNode(start);
|
||||
|
@ -608,49 +551,38 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
|
|||
return FGTaxiRoute();
|
||||
}
|
||||
|
||||
FGTaxiNodeVector unvisited(*currNodesSet); // working copy
|
||||
|
||||
while (!unvisited.empty()) {
|
||||
FGTaxiNode *best = *(unvisited.begin());
|
||||
for (FGTaxiNodeVectorIterator
|
||||
itr = unvisited.begin(); itr != unvisited.end(); itr++) {
|
||||
if ((*itr)->getPathScore() < best->getPathScore())
|
||||
best = (*itr);
|
||||
FGTaxiNode *best = unvisited.front();
|
||||
BOOST_FOREACH(FGTaxiNode* i, unvisited) {
|
||||
if (i->getPathScore() < best->getPathScore()) {
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
|
||||
// remove 'best' from the unvisited set
|
||||
FGTaxiNodeVectorIterator newend =
|
||||
remove(unvisited.begin(), unvisited.end(), best);
|
||||
unvisited.erase(newend, unvisited.end());
|
||||
|
||||
if (best == lastNode) { // found route or best not connected
|
||||
break;
|
||||
} else {
|
||||
for (FGTaxiSegmentVectorIterator
|
||||
seg = best->getBeginRoute();
|
||||
seg != best->getEndRoute(); seg++) {
|
||||
if (fullSearch || (*seg)->isPushBack()) {
|
||||
FGTaxiNode *tgt = (*seg)->getEnd();
|
||||
if (!tgt)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Error in ground network. Found empty segment "
|
||||
<< " at " << ((parent) ? parent->getId() : "<unknown>"));
|
||||
return FGTaxiRoute();
|
||||
}
|
||||
double alt =
|
||||
best->getPathScore() + (*seg)->getLength() +
|
||||
(*seg)->getPenalty(nParkings);
|
||||
|
||||
BOOST_FOREACH(FGTaxiSegment* seg, best->arcs()) {
|
||||
if (!fullSearch && !seg->isPushBack()) {
|
||||
continue; // inelligible!
|
||||
}
|
||||
|
||||
FGTaxiNode *tgt = seg->getEnd();
|
||||
double alt = best->getPathScore() + seg->getLength() +
|
||||
seg->getPenalty(nParkings);
|
||||
if (alt < tgt->getPathScore()) { // Relax (u,v)
|
||||
tgt->setPathScore(alt);
|
||||
tgt->setPreviousNode(best);
|
||||
tgt->setPreviousSeg(*seg); //
|
||||
}
|
||||
} else {
|
||||
// // cerr << "Skipping TaxiSegment " << (*seg)->getIndex() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
tgt->setPreviousSeg(seg);
|
||||
}
|
||||
} // of outgoing arcs/segments from current best node iteration
|
||||
} // of unvisited nodes remaining
|
||||
|
||||
if (lastNode->getPathScore() == HUGE_VAL) {
|
||||
// no valid route found
|
||||
|
@ -1080,7 +1012,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
}
|
||||
bool origStatus = current->hasHoldPosition();
|
||||
current->setHoldPosition(false);
|
||||
SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
|
||||
//SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
|
||||
int currentRoute = i->getCurrentPosition();
|
||||
int nextRoute;
|
||||
if (i->getIntentions().size()) {
|
||||
|
@ -1100,7 +1032,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
// current->setHoldPosition(true);
|
||||
//}
|
||||
SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
|
||||
SGGeod end (SGGeod::fromDeg(nx->getStart()->getLongitude(), nx->getStart()->getLatitude()));
|
||||
SGGeod end (nx->getStart()->geod());
|
||||
|
||||
double distance = SGGeodesy::distanceM(start, end);
|
||||
if (nx->hasBlock(now) && (distance < i->getRadius() * 4)) {
|
||||
|
@ -1379,10 +1311,10 @@ void FGGroundNetwork::render(bool visible)
|
|||
if (pos >= 0) {
|
||||
|
||||
SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
|
||||
SGGeod end (SGGeod::fromDeg(segments[pos]->getEnd()->getLongitude(), segments[pos]->getEnd()->getLatitude()));
|
||||
SGGeod end (segments[pos]->getEnd()->geod());
|
||||
|
||||
double length = SGGeodesy::distanceM(start, end);
|
||||
//heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
|
||||
//heading = SGGeodesy::headingDeg(start->geod(), end->geod());
|
||||
|
||||
double az2, heading; //, distanceM;
|
||||
SGGeodesy::inverse(start, end, heading, az2, length);
|
||||
|
@ -1466,7 +1398,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
double elevationStart = segments[k]->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
double elevationEnd = segments[k]->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
|
||||
SGGeod center2 = segments[k]->getStart()->getGeod();
|
||||
SGGeod center2 = segments[k]->getStart()->geod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
|
||||
// elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
|
||||
|
@ -1478,7 +1410,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
segments[k]->getStart()->setElevation(elevationStart);
|
||||
}
|
||||
if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
|
||||
SGGeod center2 = segments[k]->getEnd()->getGeod();
|
||||
SGGeod center2 = segments[k]->getEnd()->geod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
|
||||
// elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
|
||||
|
@ -1497,8 +1429,8 @@ void FGGroundNetwork::render(bool visible)
|
|||
|
||||
// cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
|
||||
|
||||
|
||||
WorldCoordinate( obj_pos, segments[k]->getLatitude(), segments[k]->getLongitude(), elevationMean+ 0.5, -(segments[k]->getHeading()), slope );
|
||||
SGGeod segCenter = segments[k]->getCenter();
|
||||
WorldCoordinate( obj_pos, segCenter.getLatitudeDeg(), segCenter.getLongitudeDeg(), elevationMean+ 0.5, -(segments[k]->getHeading()), slope );
|
||||
|
||||
obj_trans->setMatrix( obj_pos );
|
||||
//osg::Vec3 center(0, 0, 0)
|
||||
|
|
|
@ -24,17 +24,12 @@
|
|||
#ifndef _GROUNDNETWORK_HXX_
|
||||
#define _GROUNDNETWORK_HXX_
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Shape>
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class Block;
|
||||
|
||||
|
@ -48,10 +43,9 @@ class FGAIFlightPlan; // forward reference
|
|||
class FGAirport; // forward reference
|
||||
|
||||
typedef std::vector<FGTaxiSegment*> FGTaxiSegmentVector;
|
||||
typedef std::vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
||||
typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator;
|
||||
|
||||
//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
||||
//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
||||
typedef std::map<int, FGTaxiNode_ptr> IndexTaxiNodeMap;
|
||||
|
||||
class Block
|
||||
{
|
||||
|
@ -82,7 +76,6 @@ private:
|
|||
int endNode;
|
||||
double length;
|
||||
double heading;
|
||||
SGGeod center;
|
||||
bool isActive;
|
||||
bool isPushBackRoute;
|
||||
BlockList blockTimes;
|
||||
|
@ -91,75 +84,19 @@ private:
|
|||
int index;
|
||||
FGTaxiSegment *oppositeDirection;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
FGTaxiSegment() :
|
||||
startNode(0),
|
||||
endNode(0),
|
||||
length(0),
|
||||
heading(0),
|
||||
isActive(0),
|
||||
isPushBackRoute(0),
|
||||
start(0),
|
||||
end(0),
|
||||
index(0),
|
||||
oppositeDirection(0)
|
||||
{
|
||||
};
|
||||
|
||||
FGTaxiSegment (const FGTaxiSegment &other) :
|
||||
startNode (other.startNode),
|
||||
endNode (other.endNode),
|
||||
length (other.length),
|
||||
heading (other.heading),
|
||||
center (other.center),
|
||||
isActive (other.isActive),
|
||||
isPushBackRoute (other.isPushBackRoute),
|
||||
blockTimes (other.blockTimes),
|
||||
start (other.start),
|
||||
end (other.end),
|
||||
index (other.index),
|
||||
oppositeDirection (other.oppositeDirection)
|
||||
{
|
||||
};
|
||||
|
||||
FGTaxiSegment& operator=(const FGTaxiSegment &other)
|
||||
{
|
||||
startNode = other.startNode;
|
||||
endNode = other.endNode;
|
||||
length = other.length;
|
||||
heading = other.heading;
|
||||
center = other.center;
|
||||
isActive = other.isActive;
|
||||
isPushBackRoute = other.isPushBackRoute;
|
||||
blockTimes = other.blockTimes;
|
||||
start = other.start;
|
||||
end = other.end;
|
||||
index = other.index;
|
||||
oppositeDirection = other.oppositeDirection;
|
||||
return *this;
|
||||
};
|
||||
FGTaxiSegment(int start, int end, bool isPushBack);
|
||||
|
||||
void setIndex (int val) {
|
||||
index = val;
|
||||
};
|
||||
void setStartNodeRef (int val) {
|
||||
startNode = val;
|
||||
};
|
||||
void setEndNodeRef (int val) {
|
||||
endNode = val;
|
||||
};
|
||||
|
||||
void setOpposite(FGTaxiSegment *opp) {
|
||||
oppositeDirection = opp;
|
||||
};
|
||||
|
||||
void setStart(FGTaxiNodeVector *nodes);
|
||||
void setEnd (FGTaxiNodeVector *nodes);
|
||||
void setPushBackType(bool val) {
|
||||
isPushBackRoute = val;
|
||||
};
|
||||
bool bindToNodes(const IndexTaxiNodeMap& nodes);
|
||||
|
||||
void setDimensions(double elevation);
|
||||
void block(int id, time_t blockTime, time_t now);
|
||||
void unblock(time_t now);
|
||||
|
@ -177,12 +114,10 @@ public:
|
|||
int getIndex() {
|
||||
return index;
|
||||
};
|
||||
double getLatitude() {
|
||||
return center.getLatitudeDeg();
|
||||
};
|
||||
double getLongitude() {
|
||||
return center.getLongitudeDeg();
|
||||
};
|
||||
|
||||
// compute the center of the arc
|
||||
SGGeod getCenter() const;
|
||||
|
||||
double getHeading() {
|
||||
return heading;
|
||||
};
|
||||
|
@ -192,10 +127,6 @@ public:
|
|||
|
||||
int getPenalty(int nGates);
|
||||
|
||||
FGTaxiSegment *getAddress() {
|
||||
return this;
|
||||
};
|
||||
|
||||
bool operator<(const FGTaxiSegment &other) const {
|
||||
return index < other.index;
|
||||
};
|
||||
|
@ -203,11 +134,6 @@ public:
|
|||
FGTaxiSegment *opposite() {
|
||||
return oppositeDirection;
|
||||
};
|
||||
void setCourseDiff(double crse);
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -304,12 +230,12 @@ private:
|
|||
//int maxDepth;
|
||||
int count;
|
||||
int version;
|
||||
FGTaxiNodeVector nodes;
|
||||
|
||||
IndexTaxiNodeMap nodes;
|
||||
FGTaxiNodeVector pushBackNodes;
|
||||
|
||||
FGTaxiSegmentVector segments;
|
||||
//intVec route;
|
||||
//intVec nodesStack;
|
||||
//intVec routesStack;
|
||||
|
||||
TaxiRouteVector routes;
|
||||
TrafficVector activeTraffic;
|
||||
TrafficVectorIterator currTraffic;
|
||||
|
@ -328,14 +254,14 @@ private:
|
|||
double heading, double speed, double alt);
|
||||
|
||||
|
||||
|
||||
void parseCache();
|
||||
public:
|
||||
FGGroundNetwork();
|
||||
~FGGroundNetwork();
|
||||
|
||||
void addNode (const FGTaxiNode& node);
|
||||
void addNode (FGTaxiNode* node);
|
||||
void addNodes (FGParkingVec *parkings);
|
||||
void addSegment(const FGTaxiSegment& seg);
|
||||
void addSegment(FGTaxiSegment* seg);
|
||||
void setVersion (int v) { version = v;};
|
||||
|
||||
int getVersion() { return version; };
|
||||
|
@ -348,7 +274,6 @@ public:
|
|||
towerController = twrCtrlr;
|
||||
};
|
||||
|
||||
int findNearestNode(double lat, double lon);
|
||||
int findNearestNode(const SGGeod& aGeod);
|
||||
int findNearestNodeOnRunway(const SGGeod& aGeod);
|
||||
|
||||
|
|
|
@ -36,21 +36,22 @@
|
|||
/*********************************************************************************
|
||||
* FGParking
|
||||
********************************************************************************/
|
||||
// FGParking::FGParking(double lat,
|
||||
// double lon,
|
||||
// double hdg,
|
||||
// double rad,
|
||||
// int idx,
|
||||
// const string &name,
|
||||
// const string &tpe,
|
||||
// const string &codes)
|
||||
// : FGTaxiNode(lat,lon,idx)
|
||||
// {
|
||||
// heading = hdg;
|
||||
// parkingName = name;
|
||||
// type = tpe;
|
||||
// airlineCodes = codes;
|
||||
// }
|
||||
FGParking::~FGParking() {
|
||||
delete pushBackRoute;
|
||||
|
||||
FGParking::FGParking(PositionedID aGuid, int index, const SGGeod& pos,
|
||||
double aHeading, double aRadius,
|
||||
const std::string& name, const std::string& aType,
|
||||
const std::string& codes) :
|
||||
FGTaxiNode(aGuid, index, pos, false, 0),
|
||||
heading(aHeading),
|
||||
radius(aRadius),
|
||||
parkingName(name),
|
||||
type(aType),
|
||||
airlineCodes(codes),
|
||||
available(true),
|
||||
pushBackPoint(0)
|
||||
{
|
||||
}
|
||||
|
||||
FGParking::~FGParking()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -30,16 +30,19 @@
|
|||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/sg_inlines.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory> // for std::auto_ptr
|
||||
|
||||
#include "gnnode.hxx"
|
||||
|
||||
class FGTaxiRoute;
|
||||
|
||||
|
||||
class FGParking : public FGTaxiNode {
|
||||
class FGParking : public FGTaxiNode
|
||||
{
|
||||
private:
|
||||
double heading;
|
||||
double radius;
|
||||
|
@ -49,46 +52,15 @@ private:
|
|||
|
||||
bool available;
|
||||
int pushBackPoint;
|
||||
FGTaxiRoute *pushBackRoute;
|
||||
std::auto_ptr<FGTaxiRoute> pushBackRoute;
|
||||
|
||||
SG_DISABLE_COPY(FGParking);
|
||||
public:
|
||||
FGParking() :
|
||||
heading(0),
|
||||
radius(0),
|
||||
available(true),
|
||||
pushBackPoint(0),
|
||||
pushBackRoute(0)
|
||||
{
|
||||
};
|
||||
|
||||
FGParking(const FGParking &other) :
|
||||
FGTaxiNode (other),
|
||||
heading (other.heading),
|
||||
radius (other.radius),
|
||||
parkingName (other.parkingName),
|
||||
type (other.type),
|
||||
airlineCodes (other.airlineCodes),
|
||||
available (other.available),
|
||||
pushBackPoint(other.pushBackPoint),
|
||||
pushBackRoute(other.pushBackRoute)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
FGParking& operator =(const FGParking &other)
|
||||
{
|
||||
FGTaxiNode::operator=(other);
|
||||
heading = other.heading;
|
||||
radius = other.radius;
|
||||
parkingName = other.parkingName;
|
||||
type = other.type;
|
||||
airlineCodes = other.airlineCodes;
|
||||
available = other.available;
|
||||
pushBackPoint= other.pushBackPoint;
|
||||
pushBackRoute= other.pushBackRoute;
|
||||
return *this;
|
||||
};
|
||||
~FGParking();
|
||||
FGParking(PositionedID aGuid, int index, const SGGeod& pos,
|
||||
double heading, double radius,
|
||||
const std::string& name, const std::string& type,
|
||||
const std::string& codes);
|
||||
virtual ~FGParking();
|
||||
|
||||
void setHeading (double hdg) { heading = hdg; };
|
||||
void setRadius (double rad) { radius = rad; };
|
||||
|
@ -97,7 +69,7 @@ public:
|
|||
void setType (const std::string& tpe) { type = tpe; };
|
||||
void setCodes (const std::string& codes){ airlineCodes= codes;};
|
||||
|
||||
void setPushBackRoute(FGTaxiRoute *val) { pushBackRoute = val; };
|
||||
void setPushBackRoute(std::auto_ptr<FGTaxiRoute> val) { pushBackRoute = val; };
|
||||
void setPushBackPoint(int val) { pushBackPoint = val; };
|
||||
|
||||
bool isAvailable () const { return available;};
|
||||
|
@ -110,7 +82,7 @@ public:
|
|||
std::string getCodes () const { return airlineCodes;};
|
||||
std::string getName () const { return parkingName; };
|
||||
|
||||
FGTaxiRoute * getPushBackRoute () { return pushBackRoute; };
|
||||
FGTaxiRoute * getPushBackRoute () { return pushBackRoute.get(); };
|
||||
|
||||
int getPushBackPoint () { return pushBackPoint; };
|
||||
|
||||
|
@ -118,8 +90,8 @@ public:
|
|||
return radius < other.radius; };
|
||||
};
|
||||
|
||||
typedef std::vector<FGParking> FGParkingVec;
|
||||
typedef std::vector<FGParking>::iterator FGParkingVecIterator;
|
||||
typedef std::vector<FGParking>::const_iterator FGParkingVecConstIterator;
|
||||
typedef std::vector<FGParking*> FGParkingVec;
|
||||
typedef FGParkingVec::iterator FGParkingVecIterator;
|
||||
typedef FGParkingVec::const_iterator FGParkingVecConstIterator;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -223,7 +223,7 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
|
|||
|
||||
FGParking* parking = dcs->getParking(gateID);
|
||||
parking->setAvailable(false);
|
||||
fgApplyStartOffset(parking->getGeod(), parking->getHeading());
|
||||
fgApplyStartOffset(parking->geod(), parking->getHeading());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ const char* FGPositioned::nameForType(Type aTy)
|
|||
case RUNWAY: return "runway";
|
||||
case TAXIWAY: return "taxiway";
|
||||
case PAVEMENT: return "pavement";
|
||||
case PARK_STAND: return "parking stand";
|
||||
case PARKING: return "parking stand";
|
||||
case FIX: return "fix";
|
||||
case VOR: return "VOR";
|
||||
case NDB: return "NDB";
|
||||
|
@ -166,6 +166,7 @@ const char* FGPositioned::nameForType(Type aTy)
|
|||
case FREQ_CLEARANCE: return "clearance";
|
||||
case FREQ_UNICOM: return "unicom";
|
||||
case FREQ_APP_DEP: return "approach-departure";
|
||||
case TAXI_NODE: return "taxi-node";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
|
@ -48,7 +49,6 @@ public:
|
|||
RUNWAY,
|
||||
TAXIWAY,
|
||||
PAVEMENT,
|
||||
PARK_STAND,
|
||||
WAYPOINT,
|
||||
FIX,
|
||||
NDB,
|
||||
|
@ -77,6 +77,9 @@ public:
|
|||
FREQ_ENROUTE,
|
||||
FREQ_CLEARANCE,
|
||||
FREQ_UNICOM,
|
||||
// groundnet items
|
||||
PARKING, ///< parking position - might be a gate, or stand
|
||||
TAXI_NODE,
|
||||
LAST_TYPE
|
||||
} Type;
|
||||
|
||||
|
@ -230,6 +233,9 @@ protected:
|
|||
const SGVec3d mCart;
|
||||
const Type mType;
|
||||
const std::string mIdent;
|
||||
|
||||
private:
|
||||
SG_DISABLE_COPY(FGPositioned);
|
||||
};
|
||||
|
||||
#endif // of FG_POSITIONED_HXX
|
||||
|
|
|
@ -1350,7 +1350,7 @@ static naRef f_airport_parking(naContext c, naRef me, int argc, naRef* args)
|
|||
continue;
|
||||
}
|
||||
|
||||
const SGGeod& parkLoc = park->getGeod();
|
||||
const SGGeod& parkLoc = park->geod();
|
||||
naRef ph = naNewHash(c);
|
||||
hashset(c, ph, "name", stringToNasal(c, park->getName()));
|
||||
hashset(c, ph, "lat", naNum(parkLoc.getLatitudeDeg()));
|
||||
|
|
Loading…
Reference in a new issue