I need to create a function that, given a
, b
and c
returns a boolean indicating if c
is within a
and b
.
All variables have the following type:
type Coordinate = {
lat: number;
lon: number;
};
I've came up with a solution that initially I though was correctly, but after testing with Google Maps, I find out it's wrong.
The function:
function inBoundingBox(
bottomLeft: Coordinate,
topRight: Coordinate,
point: Coordinate
) {
let isLongInRange: boolean;
if (topRight.lon < bottomLeft.lon) {
isLongInRange = point.lon >= bottomLeft.lon || point.lon <= topRight.lon;
} else {
isLongInRange = point.lon >= bottomLeft.lon && point.lon <= topRight.lon;
}
return (
point.lat >= bottomLeft.lat && point.lat <= topRight.lat && isLongInRange
);
}
One example that should work:
const topRight: Coordinate = {
lat: -23.5273,
lon: -46.833881
};
const bottomLeft: Coordinate = {
lat: -23.537519,
lon: -46.840019
};
const point = {
lat: -23.52785,
lon: -46.840545
};
const result = inBoundingBox(bottomLeft, topRight, point);
console.log(result) // false, where should be true.
And a visual representation is here.
I need help to find out where exactly the code is wrong, and how to fix it.
I also tried to use Leaflet to see if it works, but the result is the same:
function leafletContains(bottomLeft, topRight, pos) {
var bounds = new L.LatLngBounds(
new L.LatLng(bottomLeft.lat, bottomLeft.lon),
new L.LatLng(topRight.lat, topRight.lon)
);
return bounds.contains(new L.LatLng(pos.lat, pos.lon));
}
leafLetContains({ lat: -23.537519, lon: -46.840019 }, { lat: -23.5273, lon: -46.833881 }, { lat: -23.527811, lon: -46.840201 }) // false, where should be true.
A bounding box test must check the four sides of the box.
A box in the surface of a sphere is not a rectangle, so it's hard to work with x,y coordinates. But with "polar" coordinates (lat, lon) it's a lot easy:
I'm not a javascript coder, so forgive my mistakes in this code:
function inBoundingBox(
bottomLeft: Coordinate,
topRight: Coordinate,
point: Coordinate
) {
let isLongInRange: boolean;
let isLatiInRange: boolean;
isLongInRange = point.lon >= bottomLeft.lon && point.lon <= topRight.lon;
isLatiInRange = point.lat >= bottomLeft.lat && point.lat <= topRight.lat;
return ( isLongInRange && isLatiInRange );
}
assuming bottomLeft.lon < topRight.lon
and bottomLeft.lat < topRight.lat