Search code examples
mysqllaravelreact-nativelatitude-longitudereact-native-maps

Getting radius in meters/km from latitudeDelta and longitudeDelta


I am requesting data from backend (laravel) based on a set distance between 2 points latitude and longitude eg. Lat= 78.3232 and Long = 65.3234 and distance = 30 miles/kilometers , get the rows within the 30 miles.

The problem I'm having is with distance.

I am using react-native-maps and the zoom in/out is based on the latitudeDelta and longitudeDelta and I don't know how to calculate the radius/distance of them when the user zooms in/out to be sent to the backend and get data based on the points and radius/distance

at the moment, I have this function on the client-side. to determine when to fetch new data when user changes the region. but it has a problem of hard-coded distance (5.0 KM)

const _onRegionChangeComplete = (onCompletedregion: Region) => {
    if (initialRegion) {
      const KMDistance = helper.distance(         
        initialRegion?.latitude,
        initialRegion?.longitude,
        onCompletedregion.latitude,
        onCompletedregion.longitude,
        "K"
      );

      if (KMDistance > 5.0) {
        props.getNearByReports({   // request backend if distance difference more than 5 kilometers
          latitude: onCompletedregion.latitude,
          longitude: onCompletedregion.longitude
        });
      }
    }
  };

helper.distance // get the difference in distance between the initial points and after the user done changing the region

function distance(
  lat1: number,
  lon1: number,
  lat2: number,
  lon2: number,
  unit: string
) {
  var radlat1 = (Math.PI * lat1) / 180;
  var radlat2 = (Math.PI * lat2) / 180;
  var theta = lon1 - lon2;
  var radtheta = (Math.PI * theta) / 180;
  var dist =
    Math.sin(radlat1) * Math.sin(radlat2) +
    Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
  dist = Math.acos(dist);
  dist = (dist * 180) / Math.PI;
  dist = dist * 60 * 1.1515;
  if (unit == "K") {
    dist = dist * 1.609344;
  }
  if (unit == "M") {
    dist = dist * 0.8684;
  }
  return dist;
}

The distance value is hard coded in the backend and frontend (which shouldn't be) cuz when the user zooms in/out , the radius/distance should change too. I am unable to calculate the distance from latitudeDelta and longitudeDelta

// Backend query code (simplified)

SELECT
  id, (
    6371 * acos (   
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
  ) AS distance
FROM markers
HAVING distance < 5 // hard-coded distance
ORDER BY distance
LIMIT 0 , 20;

Solution

  • latitudeDelta is the amount of degrees that are visible on the screen. 1 degree is always equal to approx. 69 miles, so you can calculate the diameter of the currently visible area in miles with this diameter = latitudeDelta * 69. This is assuming the screen is in portrait mode and, therefore, latitudeDelta is the larger value. If not, use longitudeDelta instead. I hope I understood your question correctly and this is helpful.