7

I've looked around and still couldn't find anything to help me really! I've written a program to calculate the distance between 2 cities using their Latitudes and Longitudes, the cities details are saved in a file then loaded in my program into a BST! So far everything works fine except when i run the codes that is suppose to calculate the distance i get the same answer for every cities! Am not quite sure as to why i keep getting the same answer for every cities! Please help point me into the right direction?

here are the codes to calculate the distance

#include <cmath> 
#define pi 3.14159265358979323846

string userResponse;
float globalLat1, globalLon1, globalLat2, globalLon2;

for(int j= 0; j < 2; j++){
        string whatever;
        if (j==0){
          bool hasbeenfound = false;
           do{
                //ask the user to enter their first city of their choice
                 whatever = "first ";
                  cout << "Enter your " + whatever + "City" << endl;
                  cout << "-------------------" << endl;
                  cin >> userResponse;
                  cout << endl;
                  if (Cities->search(userResponse)) //check if the entered city already exist
                  {
                  hasbeenfound = true;
                  }
                  else{
                       cout << "City not Found" << endl;
                       cout << endl;
                       }
                  //globalCity1 = Cities->sRootName;
                  globalLat1 = Cities->sLatitude;
                  globalLon1 = Cities->sLongitude;
                  }
                  while(hasbeenfound == false); //while the entered city hasn't been found, repeat the process

               }else
               {
                   bool hasbeenfound = false;
                    do{
                        //ask the user to enter their second city of their choice
                              whatever = "second ";
                              cout << endl;
                              cout << "Enter your " + whatever + "City" << endl;
                              cout << "-------------------" << endl;
                              cin >> userResponse;
                              cout << endl;
                              if (Cities->search(userResponse)) //check if the entered city already exist
                              {
                              hasbeenfound = true;
                              }
                              else{
                                   cout << "City not Found" << endl;
                                   }
                              //globalCity2 = Cities->sRootName;
                              globalLat2 = Cities->sLatitude;
                              globalLon2 = Cities->sLongitude;
                              }
                    while(hasbeenfound == false); //while the entered city hasn't been found, repeat the process

                       }
                    }

// This function converts decimal degrees to radians
double deg2rad(double deg) {
return (deg * pi / 180);
};

//  This function converts radians to decimal degrees
double rad2deg(double rad) {
return (rad * 180 / pi);
};

//distance calculations
cout << endl;
distan = sin(globalLat1)) * sin(deg2rad(globalLat2)) + cos(deg2rad(globalLat1)) * cos(deg2rad(globalLat2)) * cos(globalLon2 - globalLon1);
distan = rad2deg(distan);
distan = distan * 60 * 1.1515;
distan = (6371 * pi * distan)/180;
cout << "The Distance between the to cities is: " << distan << " kilometers" << endl;
Ange
  • 309
  • 2
  • 5
  • 14
  • 2
    The most important part is missing... How you populate `globalLat/Lon/1/2`. – Joe Apr 17 '12 at 20:55
  • may i ask what you mean by "populate"? – Ange Apr 17 '12 at 20:57
  • "Populate" means to put values in them. In other words, why *shouldn't* it return the same value all the time? What ensures that the values are different for different city selections? – Rob Kennedy Apr 17 '12 at 21:01
  • @Kap - how do you set those values? If they aren't being set correctly and never change, then you're always going to get the same results using them. – Michael Burr Apr 17 '12 at 21:02
  • You are missing 2 calls to `deg2rad()` in the first calculation for `distan`. – pmg Apr 17 '12 at 21:06
  • @MichaelBurr - Every city already has its Longitude and Latitude saved together as a node in the BST and once i've entered a city it returns the city name + Lat+ Long, i then save the Long and Lat within the globalLat/Long – Ange Apr 17 '12 at 21:07
  • @RobKennedy - please see above comment...thats how i populate them – Ange Apr 17 '12 at 21:08
  • 1
    @Kap The code with which you populate them is the important thing, since that's almost certainly where the error is. (Apart from minor glitches in the formula.) – Daniel Fischer Apr 17 '12 at 21:09
  • @DanielFischer - here are the codes [hope you can read it] `do{ whatever = "first "; cout << "Enter your " + whatever + "City" << endl; cin >> userResponse; if (Cities->search(userResponse)){ hasbeenfound = true; }else{ cout << "City not Found" << endl; } globalLat1 = Cities->sLatitude; globalLon1 = Cities->sLongitude; } while(hasbeenfound == false); }` – Ange Apr 17 '12 at 21:17
  • 2
    @Kap: try using some `printf()` debugging: Add `printf("distan(%f, %f, %f, %f) == %f\n", globalLat1, globalLat2, globalLon1, globalLon2, distan);` just after your calculation of `distan` and see if the output shows anything interesting. – Michael Burr Apr 17 '12 at 21:17
  • If you want to know why you get the same result for all cities, then you need to post enough code so that the rest of us can run your program and see for ourselves that it really does behave the way you claim. But if you just want to know how to get the spherical distance between two points given latitude and longitude, then you should remove the code and any description of the problem in your code and just ask for the formula instead. – Rob Kennedy Apr 17 '12 at 21:22
  • @RobKennedy - I want to know why! As for posting the rest of the codes, I've got 500+ lines i don't think it will fit! Is there another way i could use to post the rest of the codes? – Ange Apr 17 '12 at 21:25
  • That's OK. You shouldn't have to post 500 lines of code. Nobody wants to read that much code anyway. But how did you decide that the code you *did* post was the *right* code to post here? How do you know that's where the problem is? What debugging have you done to verify that the rest of your program up to that point works correctly? How do you know that `Cities->search` finds the right city and stores the right values in `sLatitude` and `sLongitude`? – Rob Kennedy Apr 17 '12 at 21:34
  • 1
    @RobKennedy - these are the only codes that is supposed to get the cities Lonand Lat then do the calculations. `Cities->search` does find the city when i run the program! I just checked and as you mentioned it seems that the latitudes and longitudes aren't being stored as i was hoping. Thanks for pointing that out for me! – Ange Apr 17 '12 at 21:50
  • Voted to close as **not a real question**. The problem has nothing to do with anything shown in the question. It's especially not a problem regarding finding distances or dealing with text files. Also, the posted code has syntax errors that show it's not even the real code. – Rob Kennedy Apr 17 '12 at 21:53

4 Answers4

32

As it is said, Haversine formula is your answer:

#include <math.h>
#include <cmath> 
#define earthRadiusKm 6371.0

// This function converts decimal degrees to radians
double deg2rad(double deg) {
  return (deg * M_PI / 180);
}

//  This function converts radians to decimal degrees
double rad2deg(double rad) {
  return (rad * 180 / M_PI);
}

/**
 * Returns the distance between two points on the Earth.
 * Direct translation from http://en.wikipedia.org/wiki/Haversine_formula
 * @param lat1d Latitude of the first point in degrees
 * @param lon1d Longitude of the first point in degrees
 * @param lat2d Latitude of the second point in degrees
 * @param lon2d Longitude of the second point in degrees
 * @return The distance between the two points in kilometers
 */
double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) {
  double lat1r, lon1r, lat2r, lon2r, u, v;
  lat1r = deg2rad(lat1d);
  lon1r = deg2rad(lon1d);
  lat2r = deg2rad(lat2d);
  lon2r = deg2rad(lon2d);
  u = sin((lat2r - lat1r)/2);
  v = sin((lon2r - lon1r)/2);
  return 2.0 * earthRadiusKm * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}
Nik
  • 9,063
  • 7
  • 66
  • 81
MrTJ
  • 13,064
  • 4
  • 41
  • 63
2

Using boost.geometry

typedef boost::geometry::model::point<
    double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
> spherical_point;

spherical_point p(lon1_degree, lat1_degree);
spherical_point q(lon2_degree, lat2_degree);
double dist = boost::geometry::distance(p, q);
double const earth_radius = 6371.0; // Km
double dist_km = dist*earth_radius;
Neel Basu
  • 12,638
  • 12
  • 82
  • 146
1

for people who need in swift:

  // Haversine formula:

    func deg2rad(_ deg: Double) ->Double {
        return deg * Double.pi  / 180.0
    }

    func distanceEarth(lat1d: Double, lon1d: Double, lat2d: Double, lon2d: Double) ->Double {
    let  earthRadiusKm = 6371.0

    let lat1r = deg2rad(lat1d);
    let lon1r = deg2rad(lon1d);
    let lat2r = deg2rad(lat2d);
    let lon2r = deg2rad(lon2d);
    let u = sin((lat2r - lat1r)/2);
    let v = sin((lon2r - lon1r)/2);
    return 2.0 * earthRadiusKm * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}

//test here.... https://andrew.hedges.name/experiments/haversine/


func doTestHaversine(){

    let km = distanceEarth(lat1d: 38.898556, lon1d: -77.037852, lat2d: 38.897147, lon2d: -77.043934)
     print(km)  // should show : 0.549 or similar..
}
ingconti
  • 10,876
  • 3
  • 61
  • 48
-8

This is the method that I would use for finding the distance This is probably easier

Or this, not concidering the "bend" of the Earthenter image description here

  • It's subtraction, multiplication, addition, and square root, Kap. Which part of "that" do you need to know how to do? – Rob Kennedy Apr 17 '12 at 21:01
  • 4
    This is the formula for the Euclidian distance, it doesn't apply to the Earth since it's not a linear. The lat/long space is not a plane. – Spidey Apr 17 '12 at 21:02
  • 11
    @Spidey: you'll never convince those flat-earthers. – Michael Burr Apr 17 '12 at 21:05
  • You don't have x,y,z. You have latitude and longitude, a coordinate system where one of the coordinates is not parallel, on a spherical surphace to boot. Neither of your formulas works. – juanchopanza Apr 17 '12 at 21:08
  • @RobKennedy - I know how to do all of them (didn't quite understand it being in that form) – Ange Apr 17 '12 at 21:09
  • @juanchopanza - really? I don't quite understand what you mean by neither of the formulas works – Ange Apr 17 '12 at 21:12
  • 1
    @Kap First, the earth is kind of spherical, second, the parallels are curved on the spherical surface because they are not the shortest line between two points (the definition of straight). The meridians are. A useful formula has to take this into account. The first formula above can be a useful approximation when the distance isn't too big. – juanchopanza Apr 17 '12 at 21:18
  • Google for 'Great circle route' – Martin James Apr 17 '12 at 23:31