Refactor airway code to use SGGeod in external APIs. First of various changes to make airways more useful in GPS/FMS modules.
This commit is contained in:
parent
cb6647ff13
commit
bc7ac3493e
3 changed files with 33 additions and 43 deletions
|
@ -76,18 +76,14 @@ void FGAIFlightPlan::evaluateRoutePart(double deplat,
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "1"<< endl;
|
//cerr << "1"<< endl;
|
||||||
SGGeoc geoc = SGGeoc::fromCart(SGVec3d(newPos[0], newPos[1], newPos[2]));
|
SGGeod geod = SGGeod::fromCart(SGVec3d(newPos[0], newPos[1], newPos[2]));
|
||||||
|
|
||||||
double midlat = geoc.getLatitudeDeg();
|
|
||||||
double midlon = geoc.getLongitudeDeg();
|
|
||||||
|
|
||||||
prevNode = tmpNode;
|
prevNode = tmpNode;
|
||||||
tmpNode = globals->get_airwaynet()->findNearestNode(midlat, midlon);
|
tmpNode = globals->get_airwaynet()->findNearestNode(geod);
|
||||||
|
|
||||||
FGNode* node = globals->get_airwaynet()->findNode(tmpNode);
|
FGNode* node = globals->get_airwaynet()->findNode(tmpNode);
|
||||||
SGGeoc nodePos(SGGeoc::fromGeod(node->getPosition()));
|
|
||||||
|
|
||||||
if ((tmpNode != prevNode) && (SGGeodesy::distanceM(geoc, nodePos) < 25000)) {
|
if ((tmpNode != prevNode) && (SGGeodesy::distanceM(geod, node->getPosition()) < 25000)) {
|
||||||
nodes.push_back(tmpNode);
|
nodes.push_back(tmpNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/misc/sgstream.hxx>
|
#include <simgear/misc/sgstream.hxx>
|
||||||
#include <simgear/route/waypoint.hxx>
|
#include <simgear/route/waypoint.hxx>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
#include "awynet.hxx"
|
#include "awynet.hxx"
|
||||||
|
|
||||||
|
@ -47,18 +48,19 @@ FGNode::FGNode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FGNode::FGNode(double lt, double ln, int idx, std::string id) :
|
FGNode::FGNode(const SGGeod& aPos, int idx, std::string id) :
|
||||||
ident(id),
|
ident(id),
|
||||||
geod(SGGeod::fromDeg(ln, lt)),
|
geod(aPos),
|
||||||
index(idx)
|
index(idx)
|
||||||
{
|
{
|
||||||
|
cart = SGVec3d::fromGeod(geod);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGNode::matches(string id, double lt, double ln)
|
bool FGNode::matches(std::string id, const SGGeod& aPos)
|
||||||
{
|
{
|
||||||
if ((ident == id) &&
|
if ((ident == id) &&
|
||||||
(fabs(lt - geod.getLatitudeDeg()) < 1.0) &&
|
(fabs(aPos.getLatitudeDeg() - geod.getLatitudeDeg()) < 1.0) &&
|
||||||
(fabs(ln - geod.getLongitudeDeg()) < 1.0))
|
(fabs(aPos.getLongitudeDeg() - geod.getLongitudeDeg()) < 1.0))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -195,9 +197,9 @@ void FGAirwayNetwork::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGAirwayNetwork::load(SGPath path)
|
void FGAirwayNetwork::load(const SGPath& path)
|
||||||
{
|
{
|
||||||
string identStart, identEnd, token, name;
|
std::string identStart, identEnd, token, name;
|
||||||
double latStart, lonStart, latEnd, lonEnd;
|
double latStart, lonStart, latEnd, lonEnd;
|
||||||
int type, base, top;
|
int type, base, top;
|
||||||
int airwayIndex = 0;
|
int airwayIndex = 0;
|
||||||
|
@ -272,7 +274,8 @@ void FGAirwayNetwork::load(SGPath path)
|
||||||
node_map_iterator itr = nodesMap.find(string(buffer));
|
node_map_iterator itr = nodesMap.find(string(buffer));
|
||||||
if (itr == nodesMap.end()) {
|
if (itr == nodesMap.end()) {
|
||||||
startIndex = nodes.size();
|
startIndex = nodes.size();
|
||||||
n = new FGNode(latStart, lonStart, startIndex, identStart);
|
SGGeod startPos(SGGeod::fromDeg(lonStart, latStart));
|
||||||
|
n = new FGNode(startPos, startIndex, identStart);
|
||||||
nodesMap[string(buffer)] = n;
|
nodesMap[string(buffer)] = n;
|
||||||
nodes.push_back(n);
|
nodes.push_back(n);
|
||||||
//cout << "Adding node: " << identStart << endl;
|
//cout << "Adding node: " << identStart << endl;
|
||||||
|
@ -287,7 +290,8 @@ void FGAirwayNetwork::load(SGPath path)
|
||||||
itr = nodesMap.find(string(buffer));
|
itr = nodesMap.find(string(buffer));
|
||||||
if (itr == nodesMap.end()) {
|
if (itr == nodesMap.end()) {
|
||||||
endIndex = nodes.size();
|
endIndex = nodes.size();
|
||||||
n = new FGNode(latEnd, lonEnd, endIndex, identEnd);
|
SGGeod endPos(SGGeod::fromDeg(lonEnd, latEnd));
|
||||||
|
n = new FGNode(endPos, endIndex, identEnd);
|
||||||
nodesMap[string(buffer)] = n;
|
nodesMap[string(buffer)] = n;
|
||||||
nodes.push_back(n);
|
nodes.push_back(n);
|
||||||
//cout << "Adding node: " << identEnd << endl;
|
//cout << "Adding node: " << identEnd << endl;
|
||||||
|
@ -310,32 +314,23 @@ void FGAirwayNetwork::load(SGPath path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FGAirwayNetwork::findNearestNode(double lat, double lon)
|
int FGAirwayNetwork::findNearestNode(const SGGeod& aPos)
|
||||||
{
|
{
|
||||||
double minDist = HUGE_VAL;
|
double minDist = HUGE_VAL;
|
||||||
double distsqrt, lat2, lon2;
|
|
||||||
int index;
|
int index;
|
||||||
|
SGVec3d cart = SGVec3d::fromGeod(aPos);
|
||||||
|
|
||||||
//cerr << "Lat " << lat << " lon " << lon << endl;
|
//cerr << "Lat " << lat << " lon " << lon << endl;
|
||||||
for (FGNodeVectorIterator
|
for (FGNodeVectorIterator
|
||||||
itr = nodes.begin();
|
itr = nodes.begin();
|
||||||
itr != nodes.end(); itr++)
|
itr != nodes.end(); itr++)
|
||||||
{
|
{
|
||||||
lat2 = (*itr)->getLatitude();
|
double d2 = distSqr(cart, (*itr)->getCart());
|
||||||
lon2 = (*itr)->getLongitude();
|
if (d2 < minDist)
|
||||||
// Note: This equation should adjust for decreasing distance per longitude
|
{
|
||||||
// with increasing lat.
|
minDist = d2;
|
||||||
distsqrt =
|
index = (*itr)->getIndex();
|
||||||
(lat-lat2)*(lat-lat2) +
|
}
|
||||||
(lon-lon2)*(lon-lon2);
|
|
||||||
|
|
||||||
if (distsqrt < minDist)
|
|
||||||
{
|
|
||||||
minDist = distsqrt;
|
|
||||||
//cerr << "Test" << endl;
|
|
||||||
index = (*itr)->getIndex();
|
|
||||||
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
|
||||||
//cerr << (*itr)->getLatitude() << " " << (*itr)->getLongitude() << endl;
|
|
||||||
}
|
|
||||||
//cerr << (*itr)->getIndex() << endl;
|
//cerr << (*itr)->getIndex() << endl;
|
||||||
}
|
}
|
||||||
//cerr << " returning " << index << endl;
|
//cerr << " returning " << index << endl;
|
||||||
|
|
|
@ -30,13 +30,14 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
|
||||||
#include <simgear/misc/sgstream.hxx>
|
#include <simgear/misc/sgstream.hxx>
|
||||||
|
|
||||||
|
|
||||||
//#include "parking.hxx"
|
//#include "parking.hxx"
|
||||||
|
|
||||||
class FGAirway; // forward reference
|
class FGAirway; // forward reference
|
||||||
|
class SGPath;
|
||||||
|
class SGGeod;
|
||||||
|
|
||||||
typedef std::vector<FGAirway> FGAirwayVector;
|
typedef std::vector<FGAirway> FGAirwayVector;
|
||||||
typedef std::vector<FGAirway *> FGAirwayPointerVector;
|
typedef std::vector<FGAirway *> FGAirwayPointerVector;
|
||||||
|
@ -51,28 +52,26 @@ class FGNode
|
||||||
private:
|
private:
|
||||||
std::string ident;
|
std::string ident;
|
||||||
SGGeod geod;
|
SGGeod geod;
|
||||||
|
SGVec3d cart; // cached cartesian position
|
||||||
int index;
|
int index;
|
||||||
FGAirwayPointerVector next; // a vector to all the segments leaving from this node
|
FGAirwayPointerVector next; // a vector to all the segments leaving from this node
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGNode();
|
FGNode();
|
||||||
FGNode(double lt, double ln, int idx, std::string id);
|
FGNode(const SGGeod& aPos, int idx, std::string id);
|
||||||
|
|
||||||
void setIndex(int idx) { index = idx;};
|
void setIndex(int idx) { index = idx;};
|
||||||
void addAirway(FGAirway *segment) { next.push_back(segment); };
|
void addAirway(FGAirway *segment) { next.push_back(segment); };
|
||||||
|
|
||||||
double getLatitude() { return geod.getLatitudeDeg();};
|
|
||||||
double getLongitude(){ return geod.getLongitudeDeg();};
|
|
||||||
|
|
||||||
const SGGeod& getPosition() {return geod;}
|
const SGGeod& getPosition() {return geod;}
|
||||||
|
const SGVec3d& getCart() { return cart; }
|
||||||
int getIndex() { return index; };
|
int getIndex() { return index; };
|
||||||
std::string getIdent() { return ident; };
|
std::string getIdent() { return ident; };
|
||||||
FGNode *getAddress() { return this;};
|
FGNode *getAddress() { return this;};
|
||||||
FGAirwayPointerVectorIterator getBeginRoute() { return next.begin(); };
|
FGAirwayPointerVectorIterator getBeginRoute() { return next.begin(); };
|
||||||
FGAirwayPointerVectorIterator getEndRoute() { return next.end(); };
|
FGAirwayPointerVectorIterator getEndRoute() { return next.end(); };
|
||||||
|
|
||||||
bool matches(std::string ident, double lat, double lon);
|
bool matches(std::string ident, const SGGeod& aPos);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<FGNode *> FGNodeVector;
|
typedef std::vector<FGNode *> FGNodeVector;
|
||||||
|
@ -191,12 +190,12 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
bool exists() { return hasNetwork; };
|
bool exists() { return hasNetwork; };
|
||||||
int findNearestNode(double lat, double lon);
|
int findNearestNode(const SGGeod& aPos);
|
||||||
FGNode *findNode(int idx);
|
FGNode *findNode(int idx);
|
||||||
FGAirRoute findShortestRoute(int start, int end);
|
FGAirRoute findShortestRoute(int start, int end);
|
||||||
void trace(FGNode *, int, int, double dist);
|
void trace(FGNode *, int, int, double dist);
|
||||||
|
|
||||||
void load(SGPath path);
|
void load(const SGPath& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue