Skip to content

Commit 2390de5

Browse files
committed
Fixed a rounding error for bounding boxes
1 parent d2f02c6 commit 2390de5

File tree

1 file changed

+26
-20
lines changed

1 file changed

+26
-20
lines changed

src/overpass_api/core/geometry.cc

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,15 @@ double Bbox_Double::center_lon() const
4747

4848
bool Bbox_Double::contains(const Point_Double& point) const
4949
{
50-
if (point.lat < south || point.lat > north)
50+
if (point.lat + 5e-8 < south || point.lat - 5e-8 > north)
5151
return false;
5252

5353
if (east >= west)
54-
return point.lon >= west && point.lon <= east;
54+
return point.lon + 5e-8 >= west && point.lon - 5e-8 <= east;
5555

56-
return point.lon >= west || point.lon <= east;
56+
return point.lon + 5e-8 >= west || point.lon - 5e-8 <= east;
5757
}
5858

59-
6059
bool Bbox_Double::intersects(const Point_Double& from, const Point_Double& to) const
6160
{
6261
double from_lon = from.lon;
@@ -67,48 +66,55 @@ bool Bbox_Double::intersects(const Point_Double& from, const Point_Double& to) c
6766
to_lon += 360.;
6867

6968
double delta_from = 0;
70-
if (from.lat < south)
69+
if (from.lat + 5e-8 < south)
7170
{
72-
if (to.lat < south)
71+
if (to.lat + 5e-8 < south)
7372
return false;
74-
// Otherwise just adjust from.lat and from.lon
75-
delta_from = (to_lon - from_lon)*(south - from.lat)/(to.lat - from.lat);
73+
if (to.lat - 5e-8 > from.lat)
74+
delta_from = (to_lon - from_lon)*(south - from.lat)/(to.lat - from.lat);
75+
// Asserted: (south, from_lon + delta_from) is a point on the segment
7676
}
77-
else if (from.lat > north)
77+
else if (from.lat - 5e-8 > north)
7878
{
79-
if (to.lat > north)
79+
if (to.lat - 5e-8 > north)
8080
return false;
81-
// Otherwise just adjust from.lat and from.lon
82-
delta_from = (to_lon - from_lon)*(north - from.lat)/(to.lat - from.lat);
81+
if (to.lat + 5e-8 < from.lat)
82+
delta_from = (to_lon - from_lon)*(north - from.lat)/(to.lat - from.lat);
83+
// Asserted: (north, from_lon + delta_from) is a point on the segment
8384
}
8485

85-
if (to.lat < south)
86+
if (to.lat + 5e-8 < south && from.lat - 5e-8 > to.lat)
8687
// Adjust to.lat and to.lon
8788
to_lon += (from_lon - to_lon)*(south - to.lat)/(from.lat - to.lat);
88-
else if (to.lat > north)
89+
// Asserted: (south, to_lon) is a point on the segment
90+
else if (to.lat - 5e-8 > north && from.lat + 5e-8 < to.lat)
8991
// Adjust to.lat and to.lon
9092
to_lon += (from_lon - to_lon)*(north - to.lat)/(from.lat - to.lat);
93+
// Asserted: (north, to_lon) is a point on the segment
9194
from_lon += delta_from;
95+
96+
// Asserted: (std::min(north, std::max(south, from.lat)), from_lon) is on the segment
97+
// Asserted: (std::min(north, std::max(south, to.lat)), to_lon) is on the segment
9298

9399
// Now we know that both latitudes are between south and north.
94-
// Thus we only need to check whether the segment touches the bbox in its east-west-extension.
100+
// Thus we only need to check whether the segment touches the bbox in its east-west-extent.
95101
// Note that the lons have now values between -180.0 and 360.0.
96102
double min_lon = std::min(from_lon, to_lon);
97103
double max_lon = std::max(from_lon, to_lon);
98104
if (west <= east)
99105
{
100106
if (max_lon < 180.)
101-
return min_lon <= east && max_lon >= west;
107+
return min_lon - 5e-8 <= east && max_lon + 5e-8 >= west;
102108
else if (min_lon > 180.)
103-
return min_lon - 360. <= east && max_lon - 360. >= west;
109+
return min_lon - 5e-8 - 360. <= east && max_lon + 5e-8 - 360. >= west;
104110

105-
return min_lon <= east && max_lon - 360. >= west;
111+
return min_lon - 5e-8 <= east && max_lon + 5e-8 - 360. >= west;
106112
}
107113

108114
if (max_lon < 180.)
109-
return min_lon <= east || max_lon >= west;
115+
return min_lon - 5e-8 <= east || max_lon + 5e-8 >= west;
110116
else if (min_lon > 180.)
111-
return min_lon - 360. <= east || max_lon - 360. >= west;
117+
return min_lon - 5e-8 - 360. <= east || max_lon + 5e-8 - 360. >= west;
112118

113119
return true;
114120
}

0 commit comments

Comments
 (0)