Open mmd-osm opened 7 years ago
diff --git a/src/overpass_api/core/type_area.h b/src/overpass_api/core/type_area.h
index a57f29a..453e0a9 100644
--- a/src/overpass_api/core/type_area.h
+++ b/src/overpass_api/core/type_area.h
@@ -313,6 +313,8 @@ struct Area_Block
Id_Type id;
std::vector< uint64 > coors;
+ std::vector< std::pair< uint32, int32 > > ilat_ilon_pairs;
+
Area_Block() : id(0u) {}
Area_Block(void* data) : id(*(Id_Type*)data)
diff --git a/src/overpass_api/data/collect_members.cc b/src/overpass_api/data/collect_members.cc
index 99def70..26eff46 100644
--- a/src/overpass_api/data/collect_members.cc
+++ b/src/overpass_api/data/collect_members.cc
@@ -1085,6 +1085,8 @@ std::vector< Quad_Coord > make_geometry(const Way_Skeleton& way, const std::vect
{
std::vector< Quad_Coord > result;
+ result.reserve(way.nds.size());
+
for (std::vector< Node::Id_Type >::const_iterator it3(way.nds.begin());
it3 != way.nds.end(); ++it3)
{
diff --git a/src/overpass_api/statements/area_query.cc b/src/overpass_api/statements/area_query.cc
index cd10022..73f0716 100644
--- a/src/overpass_api/statements/area_query.cc
+++ b/src/overpass_api/statements/area_query.cc
@@ -16,6 +16,7 @@
* along with Overpass_API. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <cctype>
#include <fstream>
#include <iostream>
@@ -35,6 +36,109 @@
#include "recurse.h"
+
+namespace area_query {
+
+namespace detail {
+
+const static int HIT = 1;
+const static int TOGGLE_EAST = 2;
+const static int TOGGLE_WEST = 4;
+
+int check_area_block2
+(uint32 ll_index_ilat, int32 ll_index_ilon, const Area_Block& area_block,
+ uint32 coord_lat, int32 coord_lon)
+{
+ int state = 0;
+
+ auto it(area_block.ilat_ilon_pairs.begin());
+ uint32 lat = ll_index_ilat | it->first;
+ int32 lon = ll_index_ilon | it->second;
+
+ while (++it != area_block.ilat_ilon_pairs.end())
+ {
+ uint32 last_lat = lat;
+ int32 last_lon = lon;
+
+ lat = ll_index_ilat | it->first;
+ lon = ll_index_ilon | it->second;
+
+ if (last_lon < lon)
+ {
+ if (lon < coord_lon)
+ continue; // case (1)
+ else if (last_lon > coord_lon)
+ continue; // case (1)
+ else if (lon == coord_lon)
+ {
+ if (lat < coord_lat)
+ state ^= TOGGLE_WEST; // case (4)
+ else if (lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ else if (last_lon == coord_lon)
+ {
+ if (last_lat < coord_lat)
+ state ^= TOGGLE_EAST; // case (4)
+ else if (last_lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ }
+ else if (last_lon > lon)
+ {
+ if (lon > coord_lon)
+ continue; // case (1)
+ else if (last_lon < coord_lon)
+ continue; // case (1)
+ else if (lon == coord_lon)
+ {
+ if (lat < coord_lat)
+ state ^= TOGGLE_EAST; // case (4)
+ else if (lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ else if (last_lon == coord_lon)
+ {
+ if (last_lat < coord_lat)
+ state ^= TOGGLE_WEST; // case (4)
+ else if (last_lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ }
+ else // last_lon == lon
+ {
+ if (lon == coord_lon &&
+ ((last_lat <= coord_lat && coord_lat <= lat) || (lat <= coord_lat && coord_lat <= last_lat)))
+ return HIT; // case (2)
+ continue; // else: case (1)
+ }
+
+ uint32 intersect_lat = lat +
+ ((int64)coord_lon - lon)*((int64)last_lat - lat)/((int64)last_lon - lon);
+ if (coord_lat > intersect_lat)
+ state ^= (TOGGLE_EAST | TOGGLE_WEST); // case (3)
+ else if (coord_lat == intersect_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ }
+ return state;
+}
+
+
+}
+
+}
+
+
+
class Area_Constraint : public Query_Constraint
{
public:
@@ -351,79 +455,80 @@ bool Area_Constraint::delivers_data(Resource_Manager& rman)
return (counter <= 12);
}
-
-void Area_Query_Statement::collect_nodes
- (const std::set< std::pair< Uint32_Index, Uint32_Index > >& nodes_req,
- const std::set< Uint31_Index >& req,
- std::vector< Node::Id_Type >* ids,
- std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
- Resource_Manager& rman)
-{
- Block_Backend< Uint31_Index, Area_Block > area_blocks_db
- (rman.get_area_transaction()->data_index(area_settings().AREA_BLOCKS));
- Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
- (rman.get_transaction()->data_index(osm_base_settings().NODES));
- Block_Backend< Uint31_Index, Area_Block >::Discrete_Iterator
- area_it(area_blocks_db.discrete_begin(req.begin(), req.end()));
- Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
- nodes_it(nodes_db.range_begin(nodes_req.begin(), nodes_req.end()));
- uint32 current_idx(0);
- if (!(area_it == area_blocks_db.discrete_end()))
- current_idx = area_it.index().val();
- while (!(area_it == area_blocks_db.discrete_end()))
- {
- rman.health_check(*this);
-
- std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > > areas;
- while ((!(area_it == area_blocks_db.discrete_end())) &&
- (area_it.index().val() == current_idx))
- {
- if (binary_search(area_id.begin(), area_id.end(), area_it.object().id))
- areas[area_it.object().id].push_back(area_it.object());
- ++area_it;
- }
- while ((!(nodes_it == nodes_db.range_end())) &&
- ((nodes_it.index().val() & 0xffffff00) == current_idx))
- {
- if ((ids != 0) &&
- (!binary_search(ids->begin(), ids->end(), nodes_it.object().id)))
- {
- ++nodes_it;
- continue;
- }
-
- uint32 ilat((::lat(nodes_it.index().val(), nodes_it.object().ll_lower)
- + 91.0)*10000000+0.5);
- int32 ilon(::lon(nodes_it.index().val(), nodes_it.object().ll_lower)*10000000
- + (::lon(nodes_it.index().val(), nodes_it.object().ll_lower) > 0
- ? 0.5 : -0.5));
- for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
- it != areas.end(); ++it)
- {
- int inside = 0;
- for (std::vector< Area_Block >::const_iterator it2 = it->second.begin(); it2 != it->second.end();
- ++it2)
- {
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
- if (check == Coord_Query_Statement::HIT)
- {
- inside = 1;
- break;
- }
- else if (check != 0)
- inside ^= check;
- }
- if (inside)
- {
- nodes[nodes_it.index()].push_back(nodes_it.object());
- break;
- }
- }
- ++nodes_it;
- }
- current_idx = area_it.index().val();
- }
-}
+// NO LONGER USED & OBSOLETE CODE?
+//
+//void Area_Query_Statement::collect_nodes
+// (const std::set< std::pair< Uint32_Index, Uint32_Index > >& nodes_req,
+// const std::set< Uint31_Index >& req,
+// std::vector< Node::Id_Type >* ids,
+// std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
+// Resource_Manager& rman)
+//{
+// Block_Backend< Uint31_Index, Area_Block > area_blocks_db
+// (rman.get_area_transaction()->data_index(area_settings().AREA_BLOCKS));
+// Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
+// (rman.get_transaction()->data_index(osm_base_settings().NODES));
+// Block_Backend< Uint31_Index, Area_Block >::Discrete_Iterator
+// area_it(area_blocks_db.discrete_begin(req.begin(), req.end()));
+// Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
+// nodes_it(nodes_db.range_begin(nodes_req.begin(), nodes_req.end()));
+// uint32 current_idx(0);
+// if (!(area_it == area_blocks_db.discrete_end()))
+// current_idx = area_it.index().val();
+// while (!(area_it == area_blocks_db.discrete_end()))
+// {
+// rman.health_check(*this);
+//
+// std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > > areas;
+// while ((!(area_it == area_blocks_db.discrete_end())) &&
+// (area_it.index().val() == current_idx))
+// {
+// if (binary_search(area_id.begin(), area_id.end(), area_it.object().id))
+// areas[area_it.object().id].push_back(area_it.object());
+// ++area_it;
+// }
+// while ((!(nodes_it == nodes_db.range_end())) &&
+// ((nodes_it.index().val() & 0xffffff00) == current_idx))
+// {
+// if ((ids != 0) &&
+// (!binary_search(ids->begin(), ids->end(), nodes_it.object().id)))
+// {
+// ++nodes_it;
+// continue;
+// }
+//
+// uint32 ilat((::lat(nodes_it.index().val(), nodes_it.object().ll_lower)
+// + 91.0)*10000000+0.5);
+// int32 ilon(::lon(nodes_it.index().val(), nodes_it.object().ll_lower)*10000000
+// + (::lon(nodes_it.index().val(), nodes_it.object().ll_lower) > 0
+// ? 0.5 : -0.5));
+// for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
+// it != areas.end(); ++it)
+// {
+// int inside = 0;
+// for (std::vector< Area_Block >::const_iterator it2 = it->second.begin(); it2 != it->second.end();
+// ++it2)
+// {
+// int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+// if (check == Coord_Query_Statement::HIT)
+// {
+// inside = 1;
+// break;
+// }
+// else if (check != 0)
+// inside ^= check;
+// }
+// if (inside)
+// {
+// nodes[nodes_it.index()].push_back(nodes_it.object());
+// break;
+// }
+// }
+// ++nodes_it;
+// }
+// current_idx = area_it.index().val();
+// }
+//}
template< typename Node_Skeleton >
@@ -441,6 +546,10 @@ void Area_Query_Statement::collect_nodes
uint32 loop_count = 0;
uint32 current_idx(0);
+
+ uint32 current_idx_ilat(0);
+ int32 current_idx_ilon(0);
+
while (!(area_it == area_blocks_db.discrete_end()))
{
current_idx = area_it.index().val();
@@ -459,6 +568,23 @@ void Area_Query_Statement::collect_nodes
++area_it;
}
+ /* Test: Populate ilat/ilon pairs */
+ {
+ for (auto &it : areas)
+ for (auto& it2 : it.second)
+ for (auto coor : it2.coors)
+ {
+ uint32 _lat = ::ilat((coor>>32)&0xff, coor & 0xffffffff);
+ int32 _lon = ::ilon(((coor>>32)&0xff) ^ 0x40000000, coor & 0xffffffff);
+ it2.ilat_ilon_pairs.push_back(std::make_pair(_lat, _lon));
+ }
+ current_idx_ilat = ::ilat(current_idx, 0);
+ current_idx_ilon = ::ilon(current_idx, 0);
+ }
+
+ /* ------------------------------ */
+
+
while (nodes_it != nodes.end() && nodes_it->first.val() < current_idx)
{
nodes_it->second.clear();
@@ -475,6 +601,7 @@ void Area_Query_Statement::collect_nodes
+ 91.0)*10000000+0.5);
int32 ilon(::lon(nodes_it->first.val(), iit->ll_lower)*10000000
+ (::lon(nodes_it->first.val(), iit->ll_lower) > 0 ? 0.5 : -0.5));
+
for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
it != areas.end(); ++it)
{
@@ -484,7 +611,8 @@ void Area_Query_Statement::collect_nodes
{
++loop_count;
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ int check(area_query::detail::check_area_block2(current_idx_ilat, current_idx_ilon, *it2, ilat, ilon));
+ //int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
if (check == Coord_Query_Statement::HIT && add_border)
{
inside = 1;
@@ -494,10 +622,10 @@ void Area_Query_Statement::collect_nodes
inside ^= check;
}
if (inside)
- {
- into.push_back(*iit);
- break;
- }
+ {
+ into.push_back(*iit);
+ break;
+ }
}
}
nodes_it->second.swap(into);
@@ -616,6 +744,7 @@ inline int longitude_a_intersects_inner
int intersects_inner(const Area_Block& string_a, const Area_Block& string_b)
{
+
std::vector< std::pair< uint32, uint32 > > coords_a;
for (std::vector< uint64 >::const_iterator it = string_a.coors.begin(); it != string_a.coors.end(); ++it)
coords_a.push_back(std::make_pair(::ilat(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull)),
@@ -626,6 +755,15 @@ int intersects_inner(const Area_Block& string_a, const Area_Block& string_b)
coords_b.push_back(std::make_pair(::ilat(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull)),
::ilon(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull))));
+
+/*
+ std::vector< std::pair< uint32, int32 > > coords_a = string_a.ilat_ilon_pairs;
+ std::vector< std::pair< uint32, int32 > > coords_b = string_b.ilat_ilon_pairs;
+
+ for (auto & v : coords_a) v.second ^= 0x80000000;
+ for (auto & v : coords_b) v.second ^= 0x80000000;
+ */
+
for (std::vector< std::pair< uint32, uint32 > >::size_type i = 0; i < coords_a.size()-1; ++i)
{
if (coords_a[i].second < coords_a[i+1].second)
@@ -678,7 +816,10 @@ void has_inner_points(const Area_Block& string_a, const Area_Block& string_b, in
{
uint32 ilat = (coords_a[i].first + coords_a[i+1].first)/2;
uint32 ilon = (coords_a[i].second + coords_a[i+1].second)/2 + 0x80000000u;
- int check = Coord_Query_Statement::check_area_block(0, string_b, ilat, ilon);
+
+ //int check = Coord_Query_Statement::check_area_block(0, string_b, ilat, ilon);
+ int check(area_query::detail::check_area_block2(0, 0, string_b, ilat, ilon));
+
if (check & Coord_Query_Statement::HIT)
inside = check;
else if (check)
@@ -708,6 +849,18 @@ void Area_Query_Statement::collect_ways
add_way_to_area_blocks(way_geometries.get_geometry(*it2), it2->id.val(), way_segments);
}
+ /* Test: Populate ilat/ilon pairs */
+ {
+ for (auto &it : way_segments)
+ for (auto& it2 : it.second)
+ for (auto coor : it2.coors)
+ {
+ uint32 _lat = ::ilat((coor>>32)&0xff, coor & 0xffffffff);
+ int32 _lon = ::ilon(((coor>>32)&0xff) ^ 0x40000000, coor & 0xffffffff);
+ it2.ilat_ilon_pairs.push_back(std::make_pair(_lat, _lon));
+ }
+ }
+
std::map< uint32, std::vector< std::pair< uint32, Way::Id_Type > > > way_coords_to_id;
for (typename std::map< Uint31_Index, std::vector< Way_Skeleton > >::iterator it = ways.begin(); it != ways.end(); ++it)
{
@@ -724,6 +877,9 @@ void Area_Query_Statement::collect_ways
// Fill node_status with the area related status of each node and segment
uint32 loop_count = 0;
uint32 current_idx(0);
+ uint32 current_idx_ilat(0);
+ int32 current_idx_ilon(0);
+
while (!(area_it == area_blocks_db.discrete_end()))
{
current_idx = area_it.index().val();
@@ -742,6 +898,20 @@ void Area_Query_Statement::collect_ways
++area_it;
}
+ /* Test: Populate ilat/ilon pairs */
+ {
+ for (auto &it : areas)
+ for (auto& it2 : it.second)
+ for (auto coor : it2.coors)
+ {
+ uint32 _lat = ::ilat((coor>>32)&0xff, coor & 0xffffffff);
+ int32 _lon = ::ilon(((coor>>32)&0xff) ^ 0x40000000, coor & 0xffffffff);
+ it2.ilat_ilon_pairs.push_back(std::make_pair(_lat, _lon));
+ }
+ current_idx_ilat = ::ilat(current_idx, 0);
+ current_idx_ilon = ::ilon(current_idx, 0);
+ }
+
// check nodes
while (nodes_it != way_coords_to_id.end() && nodes_it->first < current_idx)
++nodes_it;
@@ -763,7 +933,8 @@ void Area_Query_Statement::collect_ways
{
++loop_count;
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ // int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ int check(area_query::detail::check_area_block2(current_idx_ilat, current_idx_ilon, *it2, ilat, ilon));
if (check == Coord_Query_Statement::HIT)
{
inside = Coord_Query_Statement::HIT;
@@ -845,20 +1016,21 @@ void Area_Query_Statement::collect_ways
}
-void collect_nodes_from_req
- (const std::set< std::pair< Uint32_Index, Uint32_Index > >& req,
- std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
- Resource_Manager& rman)
-{
- Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
- (rman.get_transaction()->data_index(osm_base_settings().NODES));
- for (Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
- it(nodes_db.range_begin
- (Default_Range_Iterator< Uint32_Index >(req.begin()),
- Default_Range_Iterator< Uint32_Index >(req.end())));
- !(it == nodes_db.range_end()); ++it)
- nodes[it.index()].push_back(it.object());
-}
+//
+//void collect_nodes_from_req
+// (const std::set< std::pair< Uint32_Index, Uint32_Index > >& req,
+// std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
+// Resource_Manager& rman)
+//{
+// Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
+// (rman.get_transaction()->data_index(osm_base_settings().NODES));
+// for (Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
+// it(nodes_db.range_begin
+// (Default_Range_Iterator< Uint32_Index >(req.begin()),
+// Default_Range_Iterator< Uint32_Index >(req.end())));
+// !(it == nodes_db.range_end()); ++it)
+// nodes[it.index()].push_back(it.object());
+//}
void Area_Query_Statement::execute(Resource_Manager& rman)
diff --git a/src/overpass_api/core/type_area.h b/src/overpass_api/core/type_area.h
index a57f29a..c13b45e 100644
--- a/src/overpass_api/core/type_area.h
+++ b/src/overpass_api/core/type_area.h
@@ -29,6 +29,7 @@
#include "type_node.h"
#include "basic_types.h"
+#include "index_computations.h"
struct Aligned_Segment
@@ -313,9 +314,9 @@ struct Area_Block
Id_Type id;
std::vector< uint64 > coors;
- Area_Block() : id(0u) {}
+ Area_Block() : id(0u), ilat_ilon_initialized(false) {}
- Area_Block(void* data) : id(*(Id_Type*)data)
+ Area_Block(void* data) : id(*(Id_Type*)data), ilat_ilon_initialized(false)
{
id = *(Id_Type*)data;
coors.resize(*((uint16*)data + 2));
@@ -324,7 +325,7 @@ struct Area_Block
}
Area_Block(Id_Type id_, const std::vector< uint64 >& coors_)
- : id(id_), coors(coors_) {}
+ : id(id_), coors(coors_), ilat_ilon_initialized(false) {}
uint32 size_of() const
{
@@ -360,6 +361,25 @@ struct Area_Block
{
return ((this->id == a.id) && (this->coors == a.coors));
}
+
+ const std::vector< std::pair< uint32, int32 > > & get_ilat_ilon_pairs() const
+ {
+ if (!ilat_ilon_initialized)
+ {
+ for (auto coor : coors)
+ {
+ uint32 _lat = ::ilat((coor>>32)&0xff, coor & 0xffffffff);
+ int32 _lon = ::ilon((coor>>32)&0xff, coor & 0xffffffff);
+ ilat_ilon_pairs.push_back(std::make_pair(_lat, _lon));
+ }
+ ilat_ilon_initialized = true;
+ }
+ return ilat_ilon_pairs;
+ }
+
+private:
+ mutable std::vector< std::pair< uint32, int32 > > ilat_ilon_pairs;
+ mutable bool ilat_ilon_initialized;
};
#endif
diff --git a/src/overpass_api/data/collect_members.cc b/src/overpass_api/data/collect_members.cc
index 99def70..26eff46 100644
--- a/src/overpass_api/data/collect_members.cc
+++ b/src/overpass_api/data/collect_members.cc
@@ -1085,6 +1085,8 @@ std::vector< Quad_Coord > make_geometry(const Way_Skeleton& way, const std::vect
{
std::vector< Quad_Coord > result;
+ result.reserve(way.nds.size());
+
for (std::vector< Node::Id_Type >::const_iterator it3(way.nds.begin());
it3 != way.nds.end(); ++it3)
{
diff --git a/src/overpass_api/statements/area_query.cc b/src/overpass_api/statements/area_query.cc
index cd10022..765df08 100644
--- a/src/overpass_api/statements/area_query.cc
+++ b/src/overpass_api/statements/area_query.cc
@@ -16,6 +16,7 @@
* along with Overpass_API. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <cctype>
#include <fstream>
#include <iostream>
@@ -35,6 +36,109 @@
#include "recurse.h"
+
+namespace area_query {
+
+namespace detail {
+
+const static int HIT = 1;
+const static int TOGGLE_EAST = 2;
+const static int TOGGLE_WEST = 4;
+
+int check_area_block2
+(uint32 ll_index_ilat, int32 ll_index_ilon, const Area_Block& area_block,
+ uint32 coord_lat, int32 coord_lon)
+{
+ int state = 0;
+
+ auto it(area_block.get_ilat_ilon_pairs().begin());
+ uint32 lat = ll_index_ilat | it->first;
+ int32 lon = ll_index_ilon | (it->second ^ 0x80000000);
+
+ while (++it != area_block.get_ilat_ilon_pairs().end())
+ {
+ uint32 last_lat = lat;
+ int32 last_lon = lon;
+
+ lat = ll_index_ilat | it->first;
+ lon = ll_index_ilon | (it->second ^ 0x80000000);
+
+ if (last_lon < lon)
+ {
+ if (lon < coord_lon)
+ continue; // case (1)
+ else if (last_lon > coord_lon)
+ continue; // case (1)
+ else if (lon == coord_lon)
+ {
+ if (lat < coord_lat)
+ state ^= TOGGLE_WEST; // case (4)
+ else if (lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ else if (last_lon == coord_lon)
+ {
+ if (last_lat < coord_lat)
+ state ^= TOGGLE_EAST; // case (4)
+ else if (last_lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ }
+ else if (last_lon > lon)
+ {
+ if (lon > coord_lon)
+ continue; // case (1)
+ else if (last_lon < coord_lon)
+ continue; // case (1)
+ else if (lon == coord_lon)
+ {
+ if (lat < coord_lat)
+ state ^= TOGGLE_EAST; // case (4)
+ else if (lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ else if (last_lon == coord_lon)
+ {
+ if (last_lat < coord_lat)
+ state ^= TOGGLE_WEST; // case (4)
+ else if (last_lat == coord_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ continue;
+ }
+ }
+ else // last_lon == lon
+ {
+ if (lon == coord_lon &&
+ ((last_lat <= coord_lat && coord_lat <= lat) || (lat <= coord_lat && coord_lat <= last_lat)))
+ return HIT; // case (2)
+ continue; // else: case (1)
+ }
+
+ uint32 intersect_lat = lat +
+ ((int64)coord_lon - lon)*((int64)last_lat - lat)/((int64)last_lon - lon);
+ if (coord_lat > intersect_lat)
+ state ^= (TOGGLE_EAST | TOGGLE_WEST); // case (3)
+ else if (coord_lat == intersect_lat)
+ return HIT; // case (2)
+ // else: case (1)
+ }
+ return state;
+}
+
+
+}
+
+}
+
+
+
class Area_Constraint : public Query_Constraint
{
public:
@@ -351,79 +455,80 @@ bool Area_Constraint::delivers_data(Resource_Manager& rman)
return (counter <= 12);
}
-
-void Area_Query_Statement::collect_nodes
- (const std::set< std::pair< Uint32_Index, Uint32_Index > >& nodes_req,
- const std::set< Uint31_Index >& req,
- std::vector< Node::Id_Type >* ids,
- std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
- Resource_Manager& rman)
-{
- Block_Backend< Uint31_Index, Area_Block > area_blocks_db
- (rman.get_area_transaction()->data_index(area_settings().AREA_BLOCKS));
- Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
- (rman.get_transaction()->data_index(osm_base_settings().NODES));
- Block_Backend< Uint31_Index, Area_Block >::Discrete_Iterator
- area_it(area_blocks_db.discrete_begin(req.begin(), req.end()));
- Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
- nodes_it(nodes_db.range_begin(nodes_req.begin(), nodes_req.end()));
- uint32 current_idx(0);
- if (!(area_it == area_blocks_db.discrete_end()))
- current_idx = area_it.index().val();
- while (!(area_it == area_blocks_db.discrete_end()))
- {
- rman.health_check(*this);
-
- std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > > areas;
- while ((!(area_it == area_blocks_db.discrete_end())) &&
- (area_it.index().val() == current_idx))
- {
- if (binary_search(area_id.begin(), area_id.end(), area_it.object().id))
- areas[area_it.object().id].push_back(area_it.object());
- ++area_it;
- }
- while ((!(nodes_it == nodes_db.range_end())) &&
- ((nodes_it.index().val() & 0xffffff00) == current_idx))
- {
- if ((ids != 0) &&
- (!binary_search(ids->begin(), ids->end(), nodes_it.object().id)))
- {
- ++nodes_it;
- continue;
- }
-
- uint32 ilat((::lat(nodes_it.index().val(), nodes_it.object().ll_lower)
- + 91.0)*10000000+0.5);
- int32 ilon(::lon(nodes_it.index().val(), nodes_it.object().ll_lower)*10000000
- + (::lon(nodes_it.index().val(), nodes_it.object().ll_lower) > 0
- ? 0.5 : -0.5));
- for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
- it != areas.end(); ++it)
- {
- int inside = 0;
- for (std::vector< Area_Block >::const_iterator it2 = it->second.begin(); it2 != it->second.end();
- ++it2)
- {
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
- if (check == Coord_Query_Statement::HIT)
- {
- inside = 1;
- break;
- }
- else if (check != 0)
- inside ^= check;
- }
- if (inside)
- {
- nodes[nodes_it.index()].push_back(nodes_it.object());
- break;
- }
- }
- ++nodes_it;
- }
- current_idx = area_it.index().val();
- }
-}
+// NO LONGER USED & OBSOLETE CODE?
+//
+//void Area_Query_Statement::collect_nodes
+// (const std::set< std::pair< Uint32_Index, Uint32_Index > >& nodes_req,
+// const std::set< Uint31_Index >& req,
+// std::vector< Node::Id_Type >* ids,
+// std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
+// Resource_Manager& rman)
+//{
+// Block_Backend< Uint31_Index, Area_Block > area_blocks_db
+// (rman.get_area_transaction()->data_index(area_settings().AREA_BLOCKS));
+// Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
+// (rman.get_transaction()->data_index(osm_base_settings().NODES));
+// Block_Backend< Uint31_Index, Area_Block >::Discrete_Iterator
+// area_it(area_blocks_db.discrete_begin(req.begin(), req.end()));
+// Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
+// nodes_it(nodes_db.range_begin(nodes_req.begin(), nodes_req.end()));
+// uint32 current_idx(0);
+// if (!(area_it == area_blocks_db.discrete_end()))
+// current_idx = area_it.index().val();
+// while (!(area_it == area_blocks_db.discrete_end()))
+// {
+// rman.health_check(*this);
+//
+// std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > > areas;
+// while ((!(area_it == area_blocks_db.discrete_end())) &&
+// (area_it.index().val() == current_idx))
+// {
+// if (binary_search(area_id.begin(), area_id.end(), area_it.object().id))
+// areas[area_it.object().id].push_back(area_it.object());
+// ++area_it;
+// }
+// while ((!(nodes_it == nodes_db.range_end())) &&
+// ((nodes_it.index().val() & 0xffffff00) == current_idx))
+// {
+// if ((ids != 0) &&
+// (!binary_search(ids->begin(), ids->end(), nodes_it.object().id)))
+// {
+// ++nodes_it;
+// continue;
+// }
+//
+// uint32 ilat((::lat(nodes_it.index().val(), nodes_it.object().ll_lower)
+// + 91.0)*10000000+0.5);
+// int32 ilon(::lon(nodes_it.index().val(), nodes_it.object().ll_lower)*10000000
+// + (::lon(nodes_it.index().val(), nodes_it.object().ll_lower) > 0
+// ? 0.5 : -0.5));
+// for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
+// it != areas.end(); ++it)
+// {
+// int inside = 0;
+// for (std::vector< Area_Block >::const_iterator it2 = it->second.begin(); it2 != it->second.end();
+// ++it2)
+// {
+// int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+// if (check == Coord_Query_Statement::HIT)
+// {
+// inside = 1;
+// break;
+// }
+// else if (check != 0)
+// inside ^= check;
+// }
+// if (inside)
+// {
+// nodes[nodes_it.index()].push_back(nodes_it.object());
+// break;
+// }
+// }
+// ++nodes_it;
+// }
+// current_idx = area_it.index().val();
+// }
+//}
template< typename Node_Skeleton >
@@ -441,6 +546,10 @@ void Area_Query_Statement::collect_nodes
uint32 loop_count = 0;
uint32 current_idx(0);
+
+ uint32 current_idx_ilat(0);
+ int32 current_idx_ilon(0);
+
while (!(area_it == area_blocks_db.discrete_end()))
{
current_idx = area_it.index().val();
@@ -459,6 +568,15 @@ void Area_Query_Statement::collect_nodes
++area_it;
}
+ /* Test: Populate ilat/ilon pairs */
+ {
+ current_idx_ilat = ::ilat(current_idx, 0);
+ current_idx_ilon = ::ilon(current_idx, 0);
+ }
+
+ /* ------------------------------ */
+
+
while (nodes_it != nodes.end() && nodes_it->first.val() < current_idx)
{
nodes_it->second.clear();
@@ -475,6 +593,7 @@ void Area_Query_Statement::collect_nodes
+ 91.0)*10000000+0.5);
int32 ilon(::lon(nodes_it->first.val(), iit->ll_lower)*10000000
+ (::lon(nodes_it->first.val(), iit->ll_lower) > 0 ? 0.5 : -0.5));
+
for (std::map< Area_Skeleton::Id_Type, std::vector< Area_Block > >::const_iterator it = areas.begin();
it != areas.end(); ++it)
{
@@ -484,7 +603,8 @@ void Area_Query_Statement::collect_nodes
{
++loop_count;
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ int check(area_query::detail::check_area_block2(current_idx_ilat, current_idx_ilon, *it2, ilat, ilon));
+ //int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
if (check == Coord_Query_Statement::HIT && add_border)
{
inside = 1;
@@ -494,10 +614,10 @@ void Area_Query_Statement::collect_nodes
inside ^= check;
}
if (inside)
- {
- into.push_back(*iit);
- break;
- }
+ {
+ into.push_back(*iit);
+ break;
+ }
}
}
nodes_it->second.swap(into);
@@ -616,6 +736,7 @@ inline int longitude_a_intersects_inner
int intersects_inner(const Area_Block& string_a, const Area_Block& string_b)
{
+ /*
std::vector< std::pair< uint32, uint32 > > coords_a;
for (std::vector< uint64 >::const_iterator it = string_a.coors.begin(); it != string_a.coors.end(); ++it)
coords_a.push_back(std::make_pair(::ilat(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull)),
@@ -626,6 +747,13 @@ int intersects_inner(const Area_Block& string_a, const Area_Block& string_b)
coords_b.push_back(std::make_pair(::ilat(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull)),
::ilon(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull))));
+
+ */
+ const std::vector< std::pair< uint32, int32 > > coords_a = string_a.get_ilat_ilon_pairs();
+ const std::vector< std::pair< uint32, int32 > > coords_b = string_b.get_ilat_ilon_pairs();
+
+
+
for (std::vector< std::pair< uint32, uint32 > >::size_type i = 0; i < coords_a.size()-1; ++i)
{
if (coords_a[i].second < coords_a[i+1].second)
@@ -667,10 +795,13 @@ int intersects_inner(const Area_Block& string_a, const Area_Block& string_b)
void has_inner_points(const Area_Block& string_a, const Area_Block& string_b, int& inside)
{
+ /*
std::vector< std::pair< uint32, uint32 > > coords_a;
for (std::vector< uint64 >::const_iterator it = string_a.coors.begin(); it != string_a.coors.end(); ++it)
coords_a.push_back(std::make_pair(::ilat(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull)),
::ilon(uint32((*it>>32)&0xff), uint32(*it & 0xffffffffull))));
+ */
+ const std::vector< std::pair< uint32, int32 > > coords_a = string_a.get_ilat_ilon_pairs();
// Check additionally the middle of the segment to also get segments
// that run through the area
@@ -678,7 +809,10 @@ void has_inner_points(const Area_Block& string_a, const Area_Block& string_b, in
{
uint32 ilat = (coords_a[i].first + coords_a[i+1].first)/2;
uint32 ilon = (coords_a[i].second + coords_a[i+1].second)/2 + 0x80000000u;
- int check = Coord_Query_Statement::check_area_block(0, string_b, ilat, ilon);
+
+ //int check = Coord_Query_Statement::check_area_block(0, string_b, ilat, ilon);
+ int check(area_query::detail::check_area_block2(0, 0, string_b, ilat, ilon));
+
if (check & Coord_Query_Statement::HIT)
inside = check;
else if (check)
@@ -724,6 +858,9 @@ void Area_Query_Statement::collect_ways
// Fill node_status with the area related status of each node and segment
uint32 loop_count = 0;
uint32 current_idx(0);
+ uint32 current_idx_ilat(0);
+ int32 current_idx_ilon(0);
+
while (!(area_it == area_blocks_db.discrete_end()))
{
current_idx = area_it.index().val();
@@ -742,6 +879,12 @@ void Area_Query_Statement::collect_ways
++area_it;
}
+ /* Test: Populate ilat/ilon pairs */
+ {
+ current_idx_ilat = ::ilat(current_idx, 0);
+ current_idx_ilon = ::ilon(current_idx, 0);
+ }
+
// check nodes
while (nodes_it != way_coords_to_id.end() && nodes_it->first < current_idx)
++nodes_it;
@@ -763,7 +906,8 @@ void Area_Query_Statement::collect_ways
{
++loop_count;
- int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ // int check(Coord_Query_Statement::check_area_block(current_idx, *it2, ilat, ilon));
+ int check(area_query::detail::check_area_block2(current_idx_ilat, current_idx_ilon, *it2, ilat, ilon));
if (check == Coord_Query_Statement::HIT)
{
inside = Coord_Query_Statement::HIT;
@@ -845,20 +989,21 @@ void Area_Query_Statement::collect_ways
}
-void collect_nodes_from_req
- (const std::set< std::pair< Uint32_Index, Uint32_Index > >& req,
- std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
- Resource_Manager& rman)
-{
- Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
- (rman.get_transaction()->data_index(osm_base_settings().NODES));
- for (Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
- it(nodes_db.range_begin
- (Default_Range_Iterator< Uint32_Index >(req.begin()),
- Default_Range_Iterator< Uint32_Index >(req.end())));
- !(it == nodes_db.range_end()); ++it)
- nodes[it.index()].push_back(it.object());
-}
+//
+//void collect_nodes_from_req
+// (const std::set< std::pair< Uint32_Index, Uint32_Index > >& req,
+// std::map< Uint32_Index, std::vector< Node_Skeleton > >& nodes,
+// Resource_Manager& rman)
+//{
+// Block_Backend< Uint32_Index, Node_Skeleton > nodes_db
+// (rman.get_transaction()->data_index(osm_base_settings().NODES));
+// for (Block_Backend< Uint32_Index, Node_Skeleton >::Range_Iterator
+// it(nodes_db.range_begin
+// (Default_Range_Iterator< Uint32_Index >(req.begin()),
+// Default_Range_Iterator< Uint32_Index >(req.end())));
+// !(it == nodes_db.range_end()); ++it)
+// nodes[it.index()].push_back(it.object());
+//}
void Area_Query_Statement::execute(Resource_Manager& rman)