Jump to content

You're browsing the 2004-2023 VATSIM Forums archive. All content is preserved in a read-only fashion.
For the latest forum posts, please visit https://forum.vatsim.net.

Need to find something? Use the Google search below.

Parsing of PBDs and LatLongs


David Zhong
 Share

Recommended Posts

David Zhong
Posted
Posted

Hi,

 

Would it be possible to add Place-Bearing-Distance (e.g., ML270100, ML bearing 270 at 100NM) and Lat Long (e.g., 3739S14244E) fixes to the route p[Mod - Happy Thoughts]r? While these aren't common, they do pop-up every now and then, and of course the route monitor trips once the aircraft is tracking towards one of these points.

 

Regards,

David Zhong

Link to comment
Share on other sites

David Zhong
Posted
Posted

Indeed the Lat Longs do work. Thanks Stephan!

David Zhong

Link to comment
Share on other sites

  • 2 weeks later...
Jonas Eberle
Posted
Posted

If somebody else needs it: I have written a "strange Lat/Lons" - function in QuteScoop:

 

The ARINC 424-format functions:

https://qutescoop.svn.sourceforge.net/svnroot/qutescoop/trunk/QuteScoop/src/NavData.cpp

const QPair<double, double> *NavData::fromArinc(const QString &str) { // returning 0 on error
QRegExp arinc("(\\d{2})([NSEW]?)(\\d{2})([NSEW]?)"); // ARINC424 waypoints (strict)
if (arinc.exactMatch(str)) {
	if (!arinc.capturedTexts()[2].isEmpty() ||
		!arinc.capturedTexts()[4].isEmpty()) {
		double wLat = arinc.capturedTexts()[1].toDouble();
		double wLon = arinc.capturedTexts()[3].toDouble();
		if (QRegExp("[SW]").exactMatch(arinc.capturedTexts()[2]) ||
			QRegExp("[SW]").exactMatch(arinc.capturedTexts()[4]))
			wLat = -wLat;
		if (!arinc.capturedTexts()[2].isEmpty())
			wLon = wLon + 100.;
		if (QRegExp("[NW]").exactMatch(arinc.capturedTexts()[2]) ||
			QRegExp("[NW]").exactMatch(arinc.capturedTexts()[4]))
			wLon = -wLon;
		return new QPair<double, double>(wLat, wLon);
	}
}
return 0;
}

const QString NavData::toArinc(const short lat, const short lon) { // returning QString() on error
if (qAbs(lat) > 90 || qAbs(lon) > 180)
	return QString();
QString q; // ARINC 424 quadrant
if (lat > 0) {
	if (lon > 0)
		q = "E";
	else
		q = "N";
} else {
	if (lon > 0)
		q = "S";
	else
		q = "W";
}
return QString("%1%2%3%4").
		arg(qAbs(lat), 2, 10, QChar('0')).
		arg(qAbs(lon) >= 100? q: "").
		arg(qAbs(lon) >= 100? qAbs(lon) - 100: qAbs(lon), 2, 10, QChar('0')).
		arg(qAbs(lon) >= 100? "": q);
}

 

And here it comes together with some idiot hacks:

(https://qutescoop.svn.sourceforge.net/svnroot/qutescoop/trunk/QuteScoop/src/Airac.cpp)

        QRegExp slash("([\\-]?\\d{2})/([\\-]?\\d{2,3})"); // some pilots
                                               // ..like to use non-standard: -53/170
       QRegExp wildGuess("([NS]?)(\\d{2})([NSEW])(\\d{2,3})([EW]?)"); // or even
                                                                       // .. N53W170
       QRegExp idiotFormat("(\\d{2,4})([NS])(\\d{2,5})([EW])"); // complete ignorants
                                                            // ..write: 3000N 02000W
       const QPair<double, double> *arincP = NavData::fromArinc(id);
       if (arincP != 0) { // ARINC424
           double d = NavData::distance(lat, lon, arincP->first, arincP->second);
           if ((d < minDist) && (d < maxDist)) {
               result = new Waypoint(id, arincP->first, arincP->second);
               minDist = d;
           }
       } else if (slash.exactMatch(id)) { // slash-style: 35/30
           double wLat = slash.capturedTexts()[1].toDouble();
           double wLon = slash.capturedTexts()[2].toDouble();
           double d = NavData::distance(lat, lon, wLat, wLon);
           if ((d < minDist) && (d < maxDist)) {
               result = new Waypoint(NavData::toArinc(wLat, wLon), wLat, wLon);
               minDist = d;
           }
       } else if (wildGuess.exactMatch(id)) { // N53W170
           double wLat = wildGuess.capturedTexts()[2].toDouble();
           double wLon = wildGuess.capturedTexts()[4].toDouble();
           if ((wildGuess.capturedTexts()[1] == "S") ||
               (wildGuess.capturedTexts()[3] == "S"))
               wLat = -wLat;
           if ((wildGuess.capturedTexts()[3] == "W") ||
               (wildGuess.capturedTexts()[5] == "W"))
               wLon = -wLon;
           double d = NavData::distance(lat, lon, wLat, wLon);
           if ((d < minDist) && (d < maxDist)) {
               result = new Waypoint(NavData::toArinc(wLat, wLon), wLat, wLon);
               minDist = d;
           }
       } else if (idiotFormat.exactMatch(id)) { // 3000N 02000W (space removed by resolveFlightplan)
           double wLat = idiotFormat.capturedTexts()[1].toDouble();
           double wLon = idiotFormat.capturedTexts()[3].toDouble();
           while (wLat > 90)
               wLat /= 10.;
           while (wLon > 180)
               wLon /= 10.;
           if (idiotFormat.capturedTexts()[2] == "S")
               wLat = -wLat;
           if (idiotFormat.capturedTexts()[4] == "W")
               wLon = -wLon;
           double d = NavData::distance(lat, lon, wLat, wLon);
           if ((d < minDist) && (d < maxDist)) {
               result = new Waypoint(NavData::toArinc(wLat, wLon), wLat, wLon);
               minDist = d;
           }
       }

Link to comment
Share on other sites

 Share