From c393e590802da535c96f61049693024992679ccd Mon Sep 17 00:00:00 2001 From: mmd-osm Date: Fri, 26 Dec 2014 20:14:44 +0100 Subject: [PATCH 1/4] perf: around with bbox --- src/overpass_api/statements/around.cc | 199 +++++++++++++++++++++++--- src/overpass_api/statements/around.h | 20 +++ 2 files changed, 203 insertions(+), 16 deletions(-) diff --git a/src/overpass_api/statements/around.cc b/src/overpass_api/statements/around.cc index d3a874614..994e47bc8 100644 --- a/src/overpass_api/statements/around.cc +++ b/src/overpass_api/statements/around.cc @@ -265,6 +265,138 @@ set< pair< Uint32_Index, Uint32_Index > > children //----------------------------------------------------------------------------- +BBox::BBox() +{ + min_lat = 100.0; + max_lat = -100.0; + min_lon = 200.0; + max_lon = -200.0; +} + +inline void BBox::merge(BBox & bbox_) +{ + min_lat = min(min_lat, bbox_.min_lat); + max_lat = max(max_lat, bbox_.max_lat); + min_lon = min(min_lon, bbox_.min_lon); + max_lon = max(max_lon, bbox_.max_lon); +} + +inline bool BBox::intersects(const BBox & bbox_) const +{ + bool intersects_; + + intersects_ = !( bbox_.max_lat + 1e-8 < min_lat || + bbox_.min_lat - 1e-8 > max_lat || + bbox_.max_lon + 1e-8 < min_lon || + bbox_.min_lon - 1e-8 > max_lon ); + + return intersects_; +/* + * return ((lat >= south - 1e-8) && (lat <= north + 1e-8) && + (((lon >= west - 1e-8) && (lon <= east + 1e-8)) || + ((east < west) && ((lon >= west - 1e-8) || (lon <= east + 1e-8))))); + * + */ +} + +inline bool BBox::intersects(const vector < BBox > & bboxes) const +{ + + for (vector< BBox >::const_iterator it = bboxes.begin(); it != bboxes.end(); ++it) + { + if (intersects(*it)) + return true; + } + return false; + +} + +std::ostream& operator << (std::ostream &o, const BBox &b) +{ + o << fixed << setprecision(7) + << " min_lat: " << b.min_lat + << " min_lon: " << b.min_lon + << " max_lat: " << b.max_lat + << " max_lon: " << b.max_lon + << std::endl; + return o; +} + +inline BBox lat_lon_bbox(double lat, double lon) +{ + BBox bbox; + bbox.min_lat = bbox.max_lat = lat; + bbox.min_lon = bbox.max_lon = lon; + return bbox; +} + +inline BBox way_geometry_bbox(const vector< Quad_Coord >& way_geometry) +{ + BBox bbox_; + vector< Quad_Coord >::const_iterator nit = way_geometry.begin(); + if (nit == way_geometry.end()) + return bbox_; + + for (vector< Quad_Coord >::const_iterator it = way_geometry.begin(); it != way_geometry.end(); ++it) + { + double lat(::lat(it->ll_upper, it->ll_lower)); + double lon(::lon(it->ll_upper, it->ll_lower)); + BBox bbox_node = lat_lon_bbox(lat, lon); + bbox_.merge(bbox_node); + } + return bbox_; +} + +inline BBox calc_distance_bbox(double lat, double lon, double dist) +{ +// see: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates + + BBox bbox; + + if (dist == 0) + { + bbox.min_lat = bbox.max_lat = lat; + bbox.min_lon = bbox.max_lon = lon; + return bbox; + } + + double min_lon_rad, max_lon_rad; + + double dist_rad = dist / (10.0 * 1000.0 * 1000.0 / acos(0)); // TODO: accurate enough? should be 6371009m + + double lat_rad = lat * acos(0) / 90.0; + double lon_rad = lon * acos(0) / 90.0; + double min_lat_rad = lat_rad - dist_rad; + double max_lat_rad = lat_rad + dist_rad; + + if (min_lat_rad > (-90.0 * acos(0) / 90.0) + && max_lat_rad < (90.0 * acos(0) / 90.0)) + { + double lon_delta_rad = asin(sin(dist_rad) / cos(lat_rad)); + min_lon_rad = lon_rad - lon_delta_rad; + if (min_lon_rad < (-180.0 * acos(0) / 90.0)) + min_lon_rad += 2.0 * 2.0 * acos(0); + max_lon_rad = lon_rad + lon_delta_rad; + if (max_lon_rad > (180.0 * acos(0) / 90.0)) + max_lon_rad -= 2.0 * 2.0 * acos(0); + } + else + { // pole within dist + min_lat_rad = max(min_lat_rad, -90.0 * acos(0) / 90.0); + max_lat_rad = min(max_lat_rad, 90.0 * acos(0) / 90.0); + min_lon_rad = -180.0 * acos(0) / 90.0; + max_lon_rad = 180.0 * acos(0) / 90.0; + } + + bbox.min_lat = min_lat_rad * 90.0 / acos(0); + bbox.max_lat = max_lat_rad * 90.0 / acos(0); + bbox.min_lon = min_lon_rad * 90.0 / acos(0); + bbox.max_lon = max_lon_rad * 90.0 / acos(0); + return bbox; +} + +//----------------------------------------------------------------------------- + class Around_Constraint : public Query_Constraint { public: @@ -378,7 +510,7 @@ void filter_nodes_expensive(const Around_Statement& around, { double lat(::lat(it->first.val(), iit->ll_lower)); double lon(::lon(it->first.val(), iit->ll_lower)); - if (around.is_inside(lat, lon)) + if (around.matches_bboxes(lat, lon) && around.is_inside(lat, lon)) local_into.push_back(*iit); } it->second.swap(local_into); @@ -398,7 +530,9 @@ void filter_ways_expensive(const Around_Statement& around, for (typename vector< Way_Skeleton >::const_iterator iit = it->second.begin(); iit != it->second.end(); ++iit) { - if (around.is_inside(way_geometries.get_geometry(*iit))) + const vector< Quad_Coord >& way_geometry = way_geometries.get_geometry(*iit); + if (around.matches_bboxes(::way_geometry_bbox(way_geometry)) && + around.is_inside(way_geometry)) local_into.push_back(*iit); } it->second.swap(local_into); @@ -432,7 +566,8 @@ void filter_relations_expensive(const Around_Statement& around, double lat(::lat(second_nd->first.val(), second_nd->second->ll_lower)); double lon(::lon(second_nd->first.val(), second_nd->second->ll_lower)); - if (around.is_inside(lat, lon)) + if (around.matches_bboxes(lat, lon) && + around.is_inside(lat, lon)) { local_into.push_back(*iit); break; @@ -444,7 +579,9 @@ void filter_relations_expensive(const Around_Statement& around, binary_search_for_pair_id(way_members_by_id, nit->ref32()); if (!second_nd) continue; - if (around.is_inside(way_geometries.get_geometry(*second_nd->second))) + const vector< Quad_Coord >& way_geometry = way_geometries.get_geometry(*second_nd->second); + if (around.matches_bboxes(::way_geometry_bbox(way_geometry)) && + around.is_inside(way_geometry)) { local_into.push_back(*iit); break; @@ -460,7 +597,7 @@ void filter_relations_expensive(const Around_Statement& around, void Around_Constraint::filter(const Statement& query, Resource_Manager& rman, Set& into, uint64 timestamp) { around->calc_lat_lons(rman.sets()[around->get_source_name()], *around, rman); - + filter_nodes_expensive(*around, into.nodes); filter_ways_expensive(*around, Way_Geometry_Store(into.ways, query, rman), into.ways); @@ -771,25 +908,35 @@ void add_coord(double lat, double lon, double radius, void add_node(Uint32_Index idx, const Node_Skeleton& node, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< Prepared_Point >& simple_lat_lons) + vector< Prepared_Point >& simple_lat_lons, + vector< BBox >& node_bboxes) { - add_coord(::lat(idx.val(), node.ll_lower), ::lon(idx.val(), node.ll_lower), - radius, radius_lat_lons, simple_lat_lons); + double lat = ::lat(idx.val(), node.ll_lower); + double lon = ::lon(idx.val(), node.ll_lower); + add_coord(lat, lon, radius, radius_lat_lons, simple_lat_lons); + node_bboxes.push_back(::calc_distance_bbox(lat, lon, radius)); } void add_way(const vector< Quad_Coord >& way_geometry, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, vector< Prepared_Point >& simple_lat_lons, - vector< Prepared_Segment >& simple_segments) + vector< Prepared_Segment >& simple_segments, + vector< BBox >& way_bboxes) { // add nodes + BBox way_bbox; for (vector< Quad_Coord >::const_iterator nit = way_geometry.begin(); nit != way_geometry.end(); ++nit) - add_coord(::lat(nit->ll_upper, nit->ll_lower), - ::lon(nit->ll_upper, nit->ll_lower), - radius, radius_lat_lons, simple_lat_lons); - + { + double lat = ::lat(nit->ll_upper, nit->ll_lower); + double lon = ::lon(nit->ll_upper, nit->ll_lower); + add_coord(lat, lon, radius, radius_lat_lons, simple_lat_lons); + BBox node_bbox = ::calc_distance_bbox(lat, lon, radius); + way_bbox.merge(node_bbox); + } + way_bboxes.push_back(way_bbox); + // add segments vector< Quad_Coord >::const_iterator nit = way_geometry.begin(); @@ -881,7 +1028,7 @@ void Around_Statement::add_nodes(const map< Uint32_Index, vector< Node_Skeleton { for (typename vector< Node_Skeleton >::const_iterator nit(iit->second.begin()); nit != iit->second.end(); ++nit) - add_node(iit->first, *nit, radius, radius_lat_lons, simple_lat_lons); + add_node(iit->first, *nit, radius, radius_lat_lons, simple_lat_lons, node_bboxes); } } @@ -896,7 +1043,7 @@ void Around_Statement::add_ways(const map< Uint31_Index, vector< Way_Skeleton > for (typename vector< Way_Skeleton >::const_iterator iit = it->second.begin(); iit != it->second.end(); ++iit) add_way(way_geometries.get_geometry(*iit), radius, - radius_lat_lons, simple_lat_lons, simple_segments); + radius_lat_lons, simple_lat_lons, simple_segments, way_bboxes); } } @@ -908,9 +1055,14 @@ void Around_Statement::calc_lat_lons(const Set& input, Statement& query, Resourc simple_segments.clear(); + node_bboxes.clear(); + way_bboxes.clear(); + rel_bboxes.clear(); + if (lat < 100.0) { add_coord(lat, lon, radius, radius_lat_lons, simple_lat_lons); + node_bboxes.push_back(::calc_distance_bbox(lat, lon, radius)); return; } @@ -941,6 +1093,22 @@ void Around_Statement::calc_lat_lons(const Set& input, Statement& query, Resourc } } +bool Around_Statement::matches_bboxes(double lat, double lon) const +{ + BBox bbox_ = ::lat_lon_bbox(lat, lon); + return bbox_.intersects(node_bboxes) || + bbox_.intersects(way_bboxes) || + bbox_.intersects(rel_bboxes); + +} + +bool Around_Statement::matches_bboxes(const BBox & bbox_) const +{ + return bbox_.intersects(node_bboxes) || + bbox_.intersects(way_bboxes) || + bbox_.intersects(rel_bboxes); +} + bool Around_Statement::is_inside(double lat, double lon) const { @@ -1037,7 +1205,6 @@ bool Around_Statement::is_inside(const vector< Quad_Coord >& way_geometry) const return false; } - void Around_Statement::execute(Resource_Manager& rman) { Set into; diff --git a/src/overpass_api/statements/around.h b/src/overpass_api/statements/around.h index 6c1e3b94c..45b6edb94 100644 --- a/src/overpass_api/statements/around.h +++ b/src/overpass_api/statements/around.h @@ -19,6 +19,7 @@ #ifndef DE__OSM3S___OVERPASS_API__STATEMENTS__AROUND_H #define DE__OSM3S___OVERPASS_API__STATEMENTS__AROUND_H +#include #include #include #include @@ -28,6 +29,20 @@ #include "../data/way_geometry_store.h" #include "statement.h" +using namespace std; + +struct BBox +{ + double min_lat; + double min_lon; + double max_lat; + double max_lon; + + BBox(); + void merge(BBox&); + bool intersects(const BBox &) const; + bool intersects(const vector < BBox > &) const; +}; struct Prepared_Segment { @@ -84,6 +99,8 @@ class Around_Statement : public Output_Statement template< typename Way_Skeleton > void add_ways(const map< Uint31_Index, vector< Way_Skeleton > >& ways, const Way_Geometry_Store& way_geometries); + bool matches_bboxes(double lat, double lon) const; + bool matches_bboxes(const BBox &) const; virtual std::string dump_xml(const std::string& indent) const { @@ -119,6 +136,9 @@ class Around_Statement : public Output_Statement vector< Prepared_Point > simple_lat_lons; vector< Prepared_Segment > simple_segments; vector< Query_Constraint* > constraints; + vector< BBox > node_bboxes; + vector< BBox > way_bboxes; + vector< BBox > rel_bboxes; }; #endif From b4cea155cae09c4e3ef0fe31987315b2ef7f725b Mon Sep 17 00:00:00 2001 From: mmd-osm Date: Sat, 27 Dec 2014 10:25:05 +0100 Subject: [PATCH 2/4] perf: bbox support for prepared_points and prepared_segments --- src/overpass_api/statements/around.cc | 80 ++++++++++++++------------- src/overpass_api/statements/around.h | 5 +- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/overpass_api/statements/around.cc b/src/overpass_api/statements/around.cc index 994e47bc8..de214ba2d 100644 --- a/src/overpass_api/statements/around.cc +++ b/src/overpass_api/statements/around.cc @@ -283,20 +283,13 @@ inline void BBox::merge(BBox & bbox_) inline bool BBox::intersects(const BBox & bbox_) const { - bool intersects_; - - intersects_ = !( bbox_.max_lat + 1e-8 < min_lat || - bbox_.min_lat - 1e-8 > max_lat || - bbox_.max_lon + 1e-8 < min_lon || - bbox_.min_lon - 1e-8 > max_lon ); - - return intersects_; -/* - * return ((lat >= south - 1e-8) && (lat <= north + 1e-8) && - (((lon >= west - 1e-8) && (lon <= east + 1e-8)) || - ((east < west) && ((lon >= west - 1e-8) || (lon <= east + 1e-8))))); - * - */ + //TODO: east/west + bool intersects; + intersects = !( bbox_.max_lat + 1e-8 < min_lat || + bbox_.min_lat - 1e-8 > max_lat || + bbox_.max_lon + 1e-8 < min_lon || + bbox_.min_lon - 1e-8 > max_lon ); + return intersects; } inline bool BBox::intersects(const vector < BBox > & bboxes) const @@ -330,6 +323,14 @@ inline BBox lat_lon_bbox(double lat, double lon) return bbox; } +inline BBox lat_lon_bbox(double lat1, double lon1, double lat2, double lon2) +{ + BBox bbox_result = ::lat_lon_bbox(lat1, lon1); + BBox bbox_second = ::lat_lon_bbox(lat2, lon2); + bbox_result.merge(bbox_second); + return bbox_result; +} + inline BBox way_geometry_bbox(const vector< Quad_Coord >& way_geometry) { BBox bbox_; @@ -882,7 +883,7 @@ set< pair< Uint32_Index, Uint32_Index > > Around_Statement::calc_ranges void add_coord(double lat, double lon, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< Prepared_Point >& simple_lat_lons) + vector< pair< BBox, Prepared_Point> >& simple_lat_lons) { double south = lat - radius*(360.0/(40000.0*1000.0)); double north = lat + radius*(360.0/(40000.0*1000.0)); @@ -892,7 +893,9 @@ void add_coord(double lat, double lon, double radius, double west = lon - radius*(360.0/(40000.0*1000.0))/cos(scale_lat/90.0*acos(0)); double east = lon + radius*(360.0/(40000.0*1000.0))/cos(scale_lat/90.0*acos(0)); - simple_lat_lons.push_back(Prepared_Point(lat, lon)); + BBox bbox_point = ::lat_lon_bbox(south, west, north, east); + + simple_lat_lons.push_back(make_pair(bbox_point, Prepared_Point(lat, lon))); vector< pair< uint32, uint32 > > uint_ranges (calc_ranges(south, north, west, east)); @@ -908,7 +911,7 @@ void add_coord(double lat, double lon, double radius, void add_node(Uint32_Index idx, const Node_Skeleton& node, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< Prepared_Point >& simple_lat_lons, + vector< pair< BBox, Prepared_Point> >& simple_lat_lons, vector< BBox >& node_bboxes) { double lat = ::lat(idx.val(), node.ll_lower); @@ -920,8 +923,8 @@ void add_node(Uint32_Index idx, const Node_Skeleton& node, double radius, void add_way(const vector< Quad_Coord >& way_geometry, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< Prepared_Point >& simple_lat_lons, - vector< Prepared_Segment >& simple_segments, + vector< pair< BBox, Prepared_Point> >& simple_lat_lons, + vector< pair< BBox, Prepared_Segment> >& simple_segments, vector< BBox >& way_bboxes) { // add nodes @@ -951,7 +954,7 @@ void add_way(const vector< Quad_Coord >& way_geometry, double radius, double second_lat(::lat(nit->ll_upper, nit->ll_lower)); double second_lon(::lon(nit->ll_upper, nit->ll_lower)); - simple_segments.push_back(Prepared_Segment(first_lat, first_lon, second_lat, second_lon)); + simple_segments.push_back(make_pair(way_bbox, Prepared_Segment(first_lat, first_lon, second_lat, second_lon))); first_lat = second_lat; first_lon = second_lon; @@ -1057,7 +1060,6 @@ void Around_Statement::calc_lat_lons(const Set& input, Statement& query, Resourc node_bboxes.clear(); way_bboxes.clear(); - rel_bboxes.clear(); if (lat < 100.0) { @@ -1097,16 +1099,14 @@ bool Around_Statement::matches_bboxes(double lat, double lon) const { BBox bbox_ = ::lat_lon_bbox(lat, lon); return bbox_.intersects(node_bboxes) || - bbox_.intersects(way_bboxes) || - bbox_.intersects(rel_bboxes); + bbox_.intersects(way_bboxes); } bool Around_Statement::matches_bboxes(const BBox & bbox_) const { return bbox_.intersects(node_bboxes) || - bbox_.intersects(way_bboxes) || - bbox_.intersects(rel_bboxes); + bbox_.intersects(way_bboxes); } @@ -1126,16 +1126,19 @@ bool Around_Statement::is_inside(double lat, double lon) const } vector< double > coord_cartesian = cartesian(lat, lon); - for (vector< Prepared_Segment >::const_iterator + BBox bbox_lat_lon = ::lat_lon_bbox(lat, lon); + + for (vector< pair< BBox, Prepared_Segment> >::const_iterator it = simple_segments.begin(); it != simple_segments.end(); ++it) { - if (great_circle_line_dist(*it, coord_cartesian) <= radius) + if (bbox_lat_lon.intersects(it->first) && + great_circle_line_dist(it->second, coord_cartesian) <= radius) { double gcdist = great_circle_dist - (it->first_lat, it->first_lon, it->second_lat, it->second_lon); + (it->second.first_lat, it->second.first_lon, it->second.second_lat, it->second.second_lon); double limit = sqrt(gcdist*gcdist + radius*radius); - if (great_circle_dist(lat, lon, it->first_lat, it->first_lon) <= limit && - great_circle_dist(lat, lon, it->second_lat, it->second_lon) <= limit) + if (great_circle_dist(lat, lon, it->second.first_lat, it->second.first_lon) <= limit && + great_circle_dist(lat, lon, it->second.second_lat, it->second.second_lon) <= limit) return true; } } @@ -1147,24 +1150,27 @@ bool Around_Statement::is_inside (double first_lat, double first_lon, double second_lat, double second_lon) const { Prepared_Segment segment(first_lat, first_lon, second_lat, second_lon); + BBox bbox_segment = ::lat_lon_bbox(first_lat, first_lon, second_lat, second_lon); - for (vector< Prepared_Point >::const_iterator cit = simple_lat_lons.begin(); + for (vector< pair< BBox, Prepared_Point> >::const_iterator cit = simple_lat_lons.begin(); cit != simple_lat_lons.end(); ++cit) { - if (great_circle_line_dist(segment, cit->cartesian) <= radius) + if (bbox_segment.intersects(cit->first) && + great_circle_line_dist(segment, cit->second.cartesian) <= radius) { double gcdist = great_circle_dist(first_lat, first_lon, second_lat, second_lon); double limit = sqrt(gcdist*gcdist + radius*radius); - if (great_circle_dist(cit->lat, cit->lon, first_lat, first_lon) <= limit && - great_circle_dist(cit->lat, cit->lon, second_lat, second_lon) <= limit) + if (great_circle_dist(cit->second.lat, cit->second.lon, first_lat, first_lon) <= limit && + great_circle_dist(cit->second.lat, cit->second.lon, second_lat, second_lon) <= limit) return true; } } - - for (vector< Prepared_Segment >::const_iterator + + for (vector< pair< BBox, Prepared_Segment> >::const_iterator cit = simple_segments.begin(); cit != simple_segments.end(); ++cit) { - if (intersect(*cit, segment)) + if (bbox_segment.intersects(cit->first) && + intersect(cit->second, segment)) return true; } diff --git a/src/overpass_api/statements/around.h b/src/overpass_api/statements/around.h index 45b6edb94..9c0dbd517 100644 --- a/src/overpass_api/statements/around.h +++ b/src/overpass_api/statements/around.h @@ -133,12 +133,11 @@ class Around_Statement : public Output_Statement double lat; double lon; map< Uint32_Index, vector< pair< double, double > > > radius_lat_lons; - vector< Prepared_Point > simple_lat_lons; - vector< Prepared_Segment > simple_segments; + vector< pair< BBox, Prepared_Point> > simple_lat_lons; + vector< pair< BBox, Prepared_Segment> > simple_segments; vector< Query_Constraint* > constraints; vector< BBox > node_bboxes; vector< BBox > way_bboxes; - vector< BBox > rel_bboxes; }; #endif From 3e3d92687ae4fbeee85dbb17679b2d97e85377a2 Mon Sep 17 00:00:00 2001 From: mmd-osm Date: Sat, 14 Mar 2015 12:13:01 +0100 Subject: [PATCH 3/4] perf: around, date line check added --- src/overpass_api/statements/around.cc | 106 +++++++++++++------------- src/overpass_api/statements/around.h | 18 ++--- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/overpass_api/statements/around.cc b/src/overpass_api/statements/around.cc index de214ba2d..14b8546b6 100644 --- a/src/overpass_api/statements/around.cc +++ b/src/overpass_api/statements/around.cc @@ -265,7 +265,7 @@ set< pair< Uint32_Index, Uint32_Index > > children //----------------------------------------------------------------------------- -BBox::BBox() +Prepared_BBox::Prepared_BBox() { min_lat = 100.0; max_lat = -100.0; @@ -273,38 +273,38 @@ BBox::BBox() max_lon = -200.0; } -inline void BBox::merge(BBox & bbox_) +inline void Prepared_BBox::merge(Prepared_BBox & bbox) { - min_lat = min(min_lat, bbox_.min_lat); - max_lat = max(max_lat, bbox_.max_lat); - min_lon = min(min_lon, bbox_.min_lon); - max_lon = max(max_lon, bbox_.max_lon); + min_lat = min(min_lat, bbox.min_lat); + max_lat = max(max_lat, bbox.max_lat); + min_lon = min(min_lon, bbox.min_lon); + max_lon = max(max_lon, bbox.max_lon); } -inline bool BBox::intersects(const BBox & bbox_) const +inline bool Prepared_BBox::intersects(const Prepared_BBox & bbox) const { - //TODO: east/west bool intersects; - intersects = !( bbox_.max_lat + 1e-8 < min_lat || - bbox_.min_lat - 1e-8 > max_lat || - bbox_.max_lon + 1e-8 < min_lon || - bbox_.min_lon - 1e-8 > max_lon ); + // skip bbox based test when crossing date line + if (!(min_lat <= max_lat && + min_lon <= max_lon)) + return true; + + intersects = !( bbox.max_lat + 1e-8 < min_lat || + bbox.min_lat - 1e-8 > max_lat || + bbox.max_lon + 1e-8 < min_lon || + bbox.min_lon - 1e-8 > max_lon ); return intersects; } -inline bool BBox::intersects(const vector < BBox > & bboxes) const +inline bool Prepared_BBox::intersects(const vector < Prepared_BBox > & bboxes) const { - - for (vector< BBox >::const_iterator it = bboxes.begin(); it != bboxes.end(); ++it) - { + for (vector< Prepared_BBox >::const_iterator it = bboxes.begin(); it != bboxes.end(); ++it) if (intersects(*it)) return true; - } return false; - } -std::ostream& operator << (std::ostream &o, const BBox &b) +std::ostream& operator << (std::ostream &o, const Prepared_BBox &b) { o << fixed << setprecision(7) << " min_lat: " << b.min_lat @@ -315,44 +315,44 @@ std::ostream& operator << (std::ostream &o, const BBox &b) return o; } -inline BBox lat_lon_bbox(double lat, double lon) +inline Prepared_BBox lat_lon_bbox(double lat, double lon) { - BBox bbox; + Prepared_BBox bbox; bbox.min_lat = bbox.max_lat = lat; bbox.min_lon = bbox.max_lon = lon; return bbox; } -inline BBox lat_lon_bbox(double lat1, double lon1, double lat2, double lon2) +inline Prepared_BBox lat_lon_bbox(double lat1, double lon1, double lat2, double lon2) { - BBox bbox_result = ::lat_lon_bbox(lat1, lon1); - BBox bbox_second = ::lat_lon_bbox(lat2, lon2); + Prepared_BBox bbox_result = ::lat_lon_bbox(lat1, lon1); + Prepared_BBox bbox_second = ::lat_lon_bbox(lat2, lon2); bbox_result.merge(bbox_second); return bbox_result; } -inline BBox way_geometry_bbox(const vector< Quad_Coord >& way_geometry) +inline Prepared_BBox way_geometry_bbox(const vector< Quad_Coord >& way_geometry) { - BBox bbox_; + Prepared_BBox bbox; vector< Quad_Coord >::const_iterator nit = way_geometry.begin(); if (nit == way_geometry.end()) - return bbox_; + return bbox; for (vector< Quad_Coord >::const_iterator it = way_geometry.begin(); it != way_geometry.end(); ++it) { double lat(::lat(it->ll_upper, it->ll_lower)); double lon(::lon(it->ll_upper, it->ll_lower)); - BBox bbox_node = lat_lon_bbox(lat, lon); - bbox_.merge(bbox_node); + Prepared_BBox bbox_node = lat_lon_bbox(lat, lon); + bbox.merge(bbox_node); } - return bbox_; + return bbox; } -inline BBox calc_distance_bbox(double lat, double lon, double dist) +inline Prepared_BBox calc_distance_bbox(double lat, double lon, double dist) { // see: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates - BBox bbox; + Prepared_BBox bbox; if (dist == 0) { @@ -363,7 +363,7 @@ inline BBox calc_distance_bbox(double lat, double lon, double dist) double min_lon_rad, max_lon_rad; - double dist_rad = dist / (10.0 * 1000.0 * 1000.0 / acos(0)); // TODO: accurate enough? should be 6371009m + double dist_rad = dist / (10.0 * 1000.0 * 1000.0 / acos(0)); double lat_rad = lat * acos(0) / 90.0; double lon_rad = lon * acos(0) / 90.0; @@ -883,7 +883,7 @@ set< pair< Uint32_Index, Uint32_Index > > Around_Statement::calc_ranges void add_coord(double lat, double lon, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< pair< BBox, Prepared_Point> >& simple_lat_lons) + vector< pair< Prepared_BBox, Prepared_Point> >& simple_lat_lons) { double south = lat - radius*(360.0/(40000.0*1000.0)); double north = lat + radius*(360.0/(40000.0*1000.0)); @@ -893,7 +893,7 @@ void add_coord(double lat, double lon, double radius, double west = lon - radius*(360.0/(40000.0*1000.0))/cos(scale_lat/90.0*acos(0)); double east = lon + radius*(360.0/(40000.0*1000.0))/cos(scale_lat/90.0*acos(0)); - BBox bbox_point = ::lat_lon_bbox(south, west, north, east); + Prepared_BBox bbox_point = ::lat_lon_bbox(south, west, north, east); simple_lat_lons.push_back(make_pair(bbox_point, Prepared_Point(lat, lon))); @@ -911,8 +911,8 @@ void add_coord(double lat, double lon, double radius, void add_node(Uint32_Index idx, const Node_Skeleton& node, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< pair< BBox, Prepared_Point> >& simple_lat_lons, - vector< BBox >& node_bboxes) + vector< pair< Prepared_BBox, Prepared_Point> >& simple_lat_lons, + vector< Prepared_BBox >& node_bboxes) { double lat = ::lat(idx.val(), node.ll_lower); double lon = ::lon(idx.val(), node.ll_lower); @@ -923,19 +923,19 @@ void add_node(Uint32_Index idx, const Node_Skeleton& node, double radius, void add_way(const vector< Quad_Coord >& way_geometry, double radius, map< Uint32_Index, vector< pair< double, double > > >& radius_lat_lons, - vector< pair< BBox, Prepared_Point> >& simple_lat_lons, - vector< pair< BBox, Prepared_Segment> >& simple_segments, - vector< BBox >& way_bboxes) + vector< pair< Prepared_BBox, Prepared_Point> >& simple_lat_lons, + vector< pair< Prepared_BBox, Prepared_Segment> >& simple_segments, + vector< Prepared_BBox >& way_bboxes) { // add nodes - BBox way_bbox; + Prepared_BBox way_bbox; for (vector< Quad_Coord >::const_iterator nit = way_geometry.begin(); nit != way_geometry.end(); ++nit) { double lat = ::lat(nit->ll_upper, nit->ll_lower); double lon = ::lon(nit->ll_upper, nit->ll_lower); add_coord(lat, lon, radius, radius_lat_lons, simple_lat_lons); - BBox node_bbox = ::calc_distance_bbox(lat, lon, radius); + Prepared_BBox node_bbox = ::calc_distance_bbox(lat, lon, radius); way_bbox.merge(node_bbox); } way_bboxes.push_back(way_bbox); @@ -1097,16 +1097,16 @@ void Around_Statement::calc_lat_lons(const Set& input, Statement& query, Resourc bool Around_Statement::matches_bboxes(double lat, double lon) const { - BBox bbox_ = ::lat_lon_bbox(lat, lon); - return bbox_.intersects(node_bboxes) || - bbox_.intersects(way_bboxes); + Prepared_BBox bbox = ::lat_lon_bbox(lat, lon); + return bbox.intersects(node_bboxes) || + bbox.intersects(way_bboxes); } -bool Around_Statement::matches_bboxes(const BBox & bbox_) const +bool Around_Statement::matches_bboxes(const Prepared_BBox & bbox) const { - return bbox_.intersects(node_bboxes) || - bbox_.intersects(way_bboxes); + return bbox.intersects(node_bboxes) || + bbox.intersects(way_bboxes); } @@ -1126,9 +1126,9 @@ bool Around_Statement::is_inside(double lat, double lon) const } vector< double > coord_cartesian = cartesian(lat, lon); - BBox bbox_lat_lon = ::lat_lon_bbox(lat, lon); + Prepared_BBox bbox_lat_lon = ::lat_lon_bbox(lat, lon); - for (vector< pair< BBox, Prepared_Segment> >::const_iterator + for (vector< pair< Prepared_BBox, Prepared_Segment> >::const_iterator it = simple_segments.begin(); it != simple_segments.end(); ++it) { if (bbox_lat_lon.intersects(it->first) && @@ -1150,9 +1150,9 @@ bool Around_Statement::is_inside (double first_lat, double first_lon, double second_lat, double second_lon) const { Prepared_Segment segment(first_lat, first_lon, second_lat, second_lon); - BBox bbox_segment = ::lat_lon_bbox(first_lat, first_lon, second_lat, second_lon); + Prepared_BBox bbox_segment = ::lat_lon_bbox(first_lat, first_lon, second_lat, second_lon); - for (vector< pair< BBox, Prepared_Point> >::const_iterator cit = simple_lat_lons.begin(); + for (vector< pair< Prepared_BBox, Prepared_Point> >::const_iterator cit = simple_lat_lons.begin(); cit != simple_lat_lons.end(); ++cit) { if (bbox_segment.intersects(cit->first) && @@ -1166,7 +1166,7 @@ bool Around_Statement::is_inside } } - for (vector< pair< BBox, Prepared_Segment> >::const_iterator + for (vector< pair< Prepared_BBox, Prepared_Segment> >::const_iterator cit = simple_segments.begin(); cit != simple_segments.end(); ++cit) { if (bbox_segment.intersects(cit->first) && diff --git a/src/overpass_api/statements/around.h b/src/overpass_api/statements/around.h index 9c0dbd517..8cbf27312 100644 --- a/src/overpass_api/statements/around.h +++ b/src/overpass_api/statements/around.h @@ -31,17 +31,17 @@ using namespace std; -struct BBox +struct Prepared_BBox { double min_lat; double min_lon; double max_lat; double max_lon; - BBox(); - void merge(BBox&); - bool intersects(const BBox &) const; - bool intersects(const vector < BBox > &) const; + Prepared_BBox(); + void merge(Prepared_BBox&); + bool intersects(const Prepared_BBox &) const; + bool intersects(const vector < Prepared_BBox > &) const; }; struct Prepared_Segment @@ -133,11 +133,11 @@ class Around_Statement : public Output_Statement double lat; double lon; map< Uint32_Index, vector< pair< double, double > > > radius_lat_lons; - vector< pair< BBox, Prepared_Point> > simple_lat_lons; - vector< pair< BBox, Prepared_Segment> > simple_segments; + vector< pair< Prepared_BBox, Prepared_Point> > simple_lat_lons; + vector< pair< Prepared_BBox, Prepared_Segment> > simple_segments; vector< Query_Constraint* > constraints; - vector< BBox > node_bboxes; - vector< BBox > way_bboxes; + vector< Prepared_BBox > node_bboxes; + vector< Prepared_BBox > way_bboxes; }; #endif From d4e542cfcae200adc2de7f753072827cd9f335c8 Mon Sep 17 00:00:00 2001 From: mmd-osm Date: Sat, 4 Mar 2017 12:05:47 +0100 Subject: [PATCH 4/4] Fix syntax error --- src/overpass_api/statements/around.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overpass_api/statements/around.h b/src/overpass_api/statements/around.h index 8cbf27312..0b88c6460 100644 --- a/src/overpass_api/statements/around.h +++ b/src/overpass_api/statements/around.h @@ -100,7 +100,7 @@ class Around_Statement : public Output_Statement void add_ways(const map< Uint31_Index, vector< Way_Skeleton > >& ways, const Way_Geometry_Store& way_geometries); bool matches_bboxes(double lat, double lon) const; - bool matches_bboxes(const BBox &) const; + bool matches_bboxes(const Prepared_BBox&) const; virtual std::string dump_xml(const std::string& indent) const {