Tuesday, March 21, 2017

Lat / Lon and Bounding Areas

To add to the post made yesterday, I thought I'd add some notes and code for some latitude / longitude bounding area logic.

Deciding if a point is within a bounding box on a globe

You need two cases to account for the special case where the bounding box crosses over the 180 degree meridian.  Here's some sample code:

  1. if( upperLeftLong > lowerRightLong &&  
  2.     latitude <= upperLeftLat &&  
  3.     latitude >= lowerRightLat &&  
  4.     longitude >= upperLeftLong &&  
  5.     longitude <= lowerRightLong )  
  6. {  
  7.   //Special case when the 180 degree meridian crossed  
  8.   //The point is within the bounding area  
  9. }  
  10. else if ( latitude <= upperLeftLat &&  
  11.           latitude >= lowerRightLat &&  
  12.           longitude >= upperLeftLong &&  
  13.           longitude <= lowerRightLong )  
  14. {  
  15.   //Normal case  
  16.   //The point is within the bounding area  
  17. }  
  18. else  
  19. {  
  20.   //The point is not within the bounding area  
  21. }  
Deciding if a point is within a bounding circle on a globe:

In the project I was working on, someone else had written a function that determines whether or not a coordinate is within a bounding circle on Earth.  The bounding circle was defined by a center coordinate and a radius.  The function was not always working and the original author was long gone, so I looked at it myself.  It turns out the problem was that the equation being used was for a 2 dimensional plane, which the Earth is not.  So I just needed to replace it with an equation for determining if a point is within a circle on a sphere. This is what I found:

acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon2-lon1))*EarthRadius <= Radius

The latitudes and longitudes must be in radians. This is the spherical law of cosines and should work well for our purposes. The Haversine Formula seems to be more precise, but more computationally expensive, and we're not using small values anyway. For further optimization, see: http://www.movable-type.co.uk/scripts/latlong-db.html

No comments: