-1

I am attempting to convert the first code snippet at:

Calculate distance between 2 GPS coordinates

//      var R = 6371; // km
//      var dLat = (lat2-lat1).toRad();
//      var dLon = (lon2-lon1).toRad();
//      var lat1 = lat1.toRad();
//      var lat2 = lat2.toRad();

//      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
//              Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
//      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
//      var d = R * c;

(also shown below) for use in qt c++. It is used in a program that simulates gps flight inside of a radio control simulator. The GpsCalcLoop grabs gps latitude and longitude (in decimal format) once per second. These are fed into my converted code in hopes of getting a distance traveled during that one second of time. Speed would then be calculated.

I used the information at this page:

http://doc.qt.io/qt-4.8/qtcore-qmath-h.html

to convert the math functions. The output, however, is not what I expected. No matter what is input into lat2, lat1, lon2, and lon1 the results are always the same, '16777200.00'.

I am hoping that someone more familiar with qt c++ will be able to show me where I have gone wrong with the conversion. or point me to where I can find qt c++ code that is working.

I will add that I have attempted to use "#include "<"QGeoPositionInfo">" but get a 'No such file or directory' error when running the program.

void TelemetrySimulator::onGpsCalcLoop()
 {

 if(rungps)
    {
    ui -> valuetest1 -> setValue(flat);
    ui -> valuetest2 -> setValue(flat2);
    ui -> valuetest3 -> setValue(flon);
    ui -> valuetest4 -> setValue(flon2);

    ui -> valuetest5 -> setValue(flat-flat2);
    ui -> valuetest6 -> setValue(flon-flon2);

    flat2 = flat;
    flon2 = flon;
    //--https://stackoverflow.com/questions/365826   //calculate-distance-between-2-gps-coordinates--
    //      var R = 6371; // km
    //      var dLat = (lat2-lat1).toRad();
    //      var dLon = (lon2-lon1).toRad();
    //      var lat1 = lat1.toRad();
    //      var lat2 = lat2.toRad();

    //      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    //              Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
    //      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    //      var d = R * c;
    //--------------my conversio  to qt  c++---------
    //---converted to qt using this web page -> http://doc.qt.io/qt-4.8/qtcore-qmath-h.html----
    double R, dLat, dLon, lat1, lat2, lon2, lon1, a, c, d;

    lat2 = flat2;
    lat1 = flat;
    lon2 = flon2;
    lon1 = flon;

     R = 6371; // km
     dLat = qAcos(lat2-lat1); //dLat = (lat2-lat1).toRad(); instead of qAcos could be qAsin, qAtan, qCos, qSin,
                                                       // qTan. All refer to Radials.
     dLon = qAcos(lon2-lon1); //dLon = (lon2-lon1).toRad();
     lat1 = qAcos(lat1);  //lat1 = lat1.toRad();
     lat2 = qAcos(lat2);  //lat2 = lat2.toRad();

     a = qSin(dLat/2) * qSin(dLat/2) +  //Math.sin(dLat/2) * Math.sin(dLat/2) +
       qSin(dLon/2) * qSin(dLon/2) * qCos(lat1) * qCos(lat2);//Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) *  Math.cos(lat2);
     c = 2 * qAtan2(qSqrt(a), qSqrt(1-a)); //Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
     d = R * c;
     ui -> valuetest7 -> setValue(d);
     }

 }

Here is the final code:

void MainWindow::onGpsCalcLoop()
{
    //Get initial values from gps run loop-------
     double lat2 = flat2;
     double lat1 = flat;
     double lon2 = flon2;
     double lon1 = flon;
     //GPS distance and speed calculation -------
     double dLat = .01745329 * (lat2 - lat1);
     double dLon = .01745329 * (lon2 - lon1);
     lat1 = .01745329 * lat1;
     lat2 = .01745329 * lat2;
     double a = qSin(dLat/2) * qSin(dLat/2) +
         qSin(dLon/2) * qSin(dLon/2) * qCos(lat1) * qCos(lat2);
     double c = 2 * qAtan2(qSqrt(a), qSqrt(1-a));
     double d = 3975 * c;
     //Distance calculation done. Next is total distance and speed------
     td = td + d;
     if (d > .1)
     {
         d = 0;
         td = 0;
     }
     if (ui -> metric -> isChecked())
     {
         ui -> valuetest1 -> setValue(td * 1.6);
         ui -> valuetest2 -> setValue((d * 3600) * 1.6);
     }
     else
     {
     ui -> valuetest1 -> setValue(td);
     ui -> valuetest2 -> setValue(d * 3600);
     }
     flat2 = flat;
     flon2 = flon;
}

I used .01745329*(whatever) instead of qDegreesToRadians(whatever) just to keep things as simple as possible.

6
  • You're doing setValue() to ui in the beginning of the snippet. And where is the getValue()? Uninitialized variables, I think. Commented Jan 3, 2016 at 20:01
  • And: no-no, toRad() cannot be exchanged with acos, asin or other trigonomethric function. Use qDegreesToRadians doc.qt.io/qt-5/qtmath.html#qDegreesToRadians Commented Jan 3, 2016 at 20:03
  • 2
    Log the values at each calculation step to narrow down the problem. As it is one can't see if the initial values are correct. Commented Jan 3, 2016 at 20:05
  • John West, the setValue() variables were set as global. Just to keep things constant I changed everything to global. Commented Jan 4, 2016 at 1:53
  • I changed acos to qdegreestoradians as you suggested, and, with other bug fixes, it seems to be working now. I compared the output to google earth, and my initial testing seems to be right on! Thank you very much!!! Commented Jan 4, 2016 at 2:00

1 Answer 1

0

Just as reference for posterity, the same can now be done using the class QGeoCoordinate:

double latitude1 = ...;
double longitude1 = ...;
double latitude2 = ...;
double longitude2 = ...;
QGeoCoordinate coordinate1(latitude1, longitude1);
QGeoCoordinate coordinate2(latitude2, longitude2);
double distance_in_meters = coordinate1.distanceTo(coordinate2);

or, in a one-liner:

QGeoCoordinate(latitude1, longitude1).distanceTo(QGeoCoordinate(latitude2, longitude2))

To use QGeoCoordinate you need to #include <QGeoCoordinate> in the source/header file and, in the CMake file, make sure to add the Positioning component - something like:

find_package(Qt6 REQUIRED COMPONENTS Widgets Positioning)
...
target_link_libraries(my_executable PRIVATE Qt6::Widgets Qt6::Positioning)

(I added the Widgets component next to Positioning since, if you are using Qt, you are very likely using it already, so this should help you locate the proper place where you are to add the statements!)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.