Changed haversine formula to be less sensitive to floating-point
inexactness.
This commit is contained in:
		
							parent
							
								
									c6dc476704
								
							
						
					
					
						commit
						0b2df9892d
					
				| @ -57,18 +57,45 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat | |||||||
|     assert(lon1 != INT_MIN); |     assert(lon1 != INT_MIN); | ||||||
|     assert(lat2 != INT_MIN); |     assert(lat2 != INT_MIN); | ||||||
|     assert(lon2 != INT_MIN); |     assert(lon2 != INT_MIN); | ||||||
|     static const double DEG_TO_RAD = 0.017453292519943295769236907684886; | //    static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
 | ||||||
|     //Earth's quatratic mean radius for WGS-84
 | //    //Earth's quatratic mean radius for WGS-84
 | ||||||
|     static const double EARTH_RADIUS_IN_METERS = 6372797.560856; | //    static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
 | ||||||
|     double latitudeArc  = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD; | //    double latitudeArc  = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD;
 | ||||||
|     double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD; | //    double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD;
 | ||||||
|     double latitudeH = sin( latitudeArc * 0.5 ); | //    double latitudeH = sin( latitudeArc * 0.5 );
 | ||||||
|     latitudeH *= latitudeH; | //    latitudeH *= latitudeH;
 | ||||||
|     double lontitudeH = sin( longitudeArc * 0.5 ); | //    double lontitudeH = sin( longitudeArc * 0.5 );
 | ||||||
|     lontitudeH *= lontitudeH; | //    lontitudeH *= lontitudeH;
 | ||||||
|     double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD ); | //    double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD );
 | ||||||
|     double distanceArc =  2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) ); | //    double distanceArc =  2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) );
 | ||||||
|     return EARTH_RADIUS_IN_METERS * distanceArc; | //    return EARTH_RADIUS_IN_METERS * distanceArc;
 | ||||||
|  | 
 | ||||||
|  |     //double PI = 3.14159265358979323846;//4.0*atan(1.0);
 | ||||||
|  |     double RAD = 0.017453292519943295769236907684886; | ||||||
|  |     //std::cout << "RAD: " << RAD << std::endl;
 | ||||||
|  |     //main code inside the class
 | ||||||
|  |     double lt1 = lat1/100000.; | ||||||
|  |     double ln1 = lon1/100000.; | ||||||
|  |     double lt2 = lat2/100000.; | ||||||
|  |     double ln2 = lon2/100000.; | ||||||
|  |     double dlat1=lt1*(RAD); | ||||||
|  | 
 | ||||||
|  |     double dlong1=ln1*(RAD); | ||||||
|  |     double dlat2=lt2*(RAD); | ||||||
|  |     double dlong2=ln2*(RAD); | ||||||
|  | 
 | ||||||
|  |     double dLong=dlong1-dlong2; | ||||||
|  |     double dLat=dlat1-dlat2; | ||||||
|  | 
 | ||||||
|  |     double aHarv= pow(sin(dLat/2.0),2.0)+cos(dlat1)*cos(dlat2)*pow(sin(dLong/2.),2); | ||||||
|  |     double cHarv=2.*atan2(sqrt(aHarv),sqrt(1.0-aHarv)); | ||||||
|  |     //earth's radius from wikipedia varies between 6,356.750 km — 6,378.135 km (˜3,949.901 — 3,963.189 miles)
 | ||||||
|  |     //The IUGG value for the equatorial radius of the Earth is 6378.137 km (3963.19 mile)
 | ||||||
|  |     const double earth=6372797.560856;//I am doing miles, just change this to radius in kilometers to get distances in km
 | ||||||
|  |     double distance=earth*cHarv; | ||||||
|  |     return distance; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) { | inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) { | ||||||
|  | |||||||
| @ -51,7 +51,7 @@ public: | |||||||
|         unsigned startName; |         unsigned startName; | ||||||
|         unsigned destName; |         unsigned destName; | ||||||
|         _RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {} |         _RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {} | ||||||
|         void BuildDurationAndLengthStrings(double distance, unsigned time) { |         void BuildDurationAndLengthStrings(const double distance, const unsigned time) { | ||||||
|             //compute distance/duration for route summary
 |             //compute distance/duration for route summary
 | ||||||
|             std::ostringstream s; |             std::ostringstream s; | ||||||
|             s << round(distance); |             s << round(distance); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user