Skip to content

Instantly share code, notes, and snippets.

@gryzzly
Created July 17, 2017 17:22
Show Gist options
  • Save gryzzly/f084754cf2b32f2c3ff7d2a70ab6fc1b to your computer and use it in GitHub Desktop.
Save gryzzly/f084754cf2b32f2c3ff7d2a70ab6fc1b to your computer and use it in GitHub Desktop.
Get bbox from coordinates and distance
/**
* Get bounding box from set of coordinates [lat,lng] and distance in (deg) adopted to JS
*
* @param {number} distance - distance (deg) from the point represented by centerPoint
* @param {array} centerPoint - two-dimensional array containing center coords [latitude, longitude]
* @description
* Computes the bounding coordinates of all points on the surface of a sphere
* that has a great circle distance to the point represented by the centerPoint
* argument that is less or equal to the distance argument.
* Technique from: Jan Matuschek <http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates>
* @author Alex Salisbury
*/
export const getBoundingBox = function getBoundingBox(centerPoint, distance) {
if (distance < 0) {
return 'Illegal arguments';
}
// coordinate limits
const MIN_LAT = degToRad(-90);
const MAX_LAT = degToRad(90);
const MIN_LON = degToRad(-180);
const MAX_LON = degToRad(180);
// Earth's radius (km)
const R = 6378.1;
// angular distance in radians on a great circle
// (degrees * PI * diameter / 360) * cos (latitude)
const radDist = (distance * 111) / R;
// center point coordinates (deg)
const degLat = centerPoint[0];
const degLon = centerPoint[1];
// center point coordinates (rad)
const radLat = degToRad(degLat);
const radLon = degToRad(degLon);
// minimum and maximum latitudes for given distance
let minLat = radLat - radDist;
let maxLat = radLat + radDist;
// minimum and maximum longitudes for given distance
let minLon;
let maxLon;
// define deltaLon to help determine min and max longitudes
const deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));
if (minLat > MIN_LAT && maxLat < MAX_LAT) {
minLon = radLon - deltaLon;
maxLon = radLon + deltaLon;
if (minLon < MIN_LON) {
minLon = minLon + 2 * Math.PI;
}
if (maxLon > MAX_LON) {
maxLon = maxLon - 2 * Math.PI;
}
// a pole is within the given distance
} else {
minLat = Math.max(minLat, MIN_LAT);
maxLat = Math.min(maxLat, MAX_LAT);
minLon = MIN_LON;
maxLon = MAX_LON;
}
return latLngBounds(
// SW
latLng(radToDeg(minLat), radToDeg(minLon)),
// NE
latLng(radToDeg(maxLat), radToDeg(maxLon))
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment