mirror of
https://github.com/osm2pgsql-dev/osm2pgsql.git
synced 2025-07-22 12:00:31 +00:00
Make locator also work with geometry collections
This commit is contained in:
@ -88,6 +88,24 @@ void locator_t::build_index()
|
||||
m_rtree.insert(m_data.cbegin(), m_data.cend());
|
||||
}
|
||||
|
||||
void locator_t::all_intersecting_visit(geom::geometry_t const &geom,
|
||||
std::set<std::string> *results)
|
||||
{
|
||||
geom.visit(overloaded{[&](geom::nullgeom_t const & /*val*/) {},
|
||||
[&](geom::collection_t const &val) {
|
||||
for (auto const &sgeom : val) {
|
||||
all_intersecting_visit(sgeom, results);
|
||||
}
|
||||
},
|
||||
[&](auto const &val) {
|
||||
for (auto it = begin_intersects(val);
|
||||
it != end_query(); ++it) {
|
||||
auto const ®ion = m_regions[it->second];
|
||||
results->emplace(region.name());
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
std::set<std::string> locator_t::all_intersecting(geom::geometry_t const &geom)
|
||||
{
|
||||
if (m_rtree.size() < m_regions.size()) {
|
||||
@ -95,18 +113,29 @@ std::set<std::string> locator_t::all_intersecting(geom::geometry_t const &geom)
|
||||
}
|
||||
|
||||
std::set<std::string> results;
|
||||
all_intersecting_visit(geom, &results);
|
||||
return results;
|
||||
}
|
||||
|
||||
geom.visit(overloaded{[&](geom::nullgeom_t const & /*input*/) {},
|
||||
[&](geom::collection_t const & /*input*/) {}, // TODO
|
||||
void locator_t::first_intersecting_visit(geom::geometry_t const &geom,
|
||||
std::string *result)
|
||||
{
|
||||
geom.visit(overloaded{[&](geom::nullgeom_t const & /*val*/) {},
|
||||
[&](geom::collection_t const &val) {
|
||||
for (auto const &sgeom : val) {
|
||||
first_intersecting_visit(sgeom, result);
|
||||
if (!result->empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
[&](auto const &val) {
|
||||
for (auto it = begin_intersects(val);
|
||||
it != end_query(); ++it) {
|
||||
auto const it = begin_intersects(val);
|
||||
if (it != end_query()) {
|
||||
auto const ®ion = m_regions[it->second];
|
||||
results.emplace(region.name());
|
||||
*result = region.name();
|
||||
}
|
||||
}});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::string locator_t::first_intersecting(geom::geometry_t const &geom)
|
||||
@ -116,16 +145,6 @@ std::string locator_t::first_intersecting(geom::geometry_t const &geom)
|
||||
}
|
||||
|
||||
std::string result;
|
||||
|
||||
geom.visit(overloaded{[&](geom::nullgeom_t const & /*input*/) {},
|
||||
[&](geom::collection_t const & /*input*/) {}, // TODO
|
||||
[&](auto const &val) {
|
||||
auto const it = begin_intersects(val);
|
||||
if (it != end_query()) {
|
||||
auto const ®ion = m_regions[it->second];
|
||||
result = region.name();
|
||||
}
|
||||
}});
|
||||
|
||||
first_intersecting_visit(geom, &result);
|
||||
return result;
|
||||
}
|
||||
|
@ -98,6 +98,12 @@ private:
|
||||
|
||||
tree_t::const_query_iterator end_query() { return m_rtree.qend(); }
|
||||
|
||||
void all_intersecting_visit(geom::geometry_t const &geom,
|
||||
std::set<std::string> *results);
|
||||
|
||||
void first_intersecting_visit(geom::geometry_t const &geom,
|
||||
std::string *result);
|
||||
|
||||
public:
|
||||
/// The name of this locator (for logging only)
|
||||
std::string const &name() const noexcept { return m_name; }
|
||||
|
@ -80,7 +80,7 @@ Feature: Locators
|
||||
Error in 'first_intersecting': Need locator and geometry arguments
|
||||
"""
|
||||
|
||||
Scenario: Use a all_intersecting() without geometry fails
|
||||
Scenario: Use of all_intersecting() without geometry fails
|
||||
Given the OSM data
|
||||
"""
|
||||
n10 v1 dV Tamenity=post_box x0.5 y0.5
|
||||
@ -231,3 +231,69 @@ Feature: Locators
|
||||
| node_id | region | ST_AsText(geom) |
|
||||
| 10 | P1 | 15 8 |
|
||||
|
||||
Scenario: Define and use a locator with relation from db
|
||||
Given the 10.0 grid with origin 10.0 10.0
|
||||
| 10 | 11 | 12 |
|
||||
| 13 | 14 | 15 |
|
||||
And the OSM data
|
||||
"""
|
||||
w29 v1 dV Tregion=P1 Nn10,n11,n14,n13,n10
|
||||
"""
|
||||
And the lua style
|
||||
"""
|
||||
local regions = osm2pgsql.define_way_table('osm2pgsql_test_regions', {
|
||||
{ column = 'region', type = 'text' },
|
||||
{ column = 'geom', type = 'polygon', projection = 4326 },
|
||||
})
|
||||
|
||||
function osm2pgsql.process_way(object)
|
||||
regions:insert({
|
||||
region = object.tags.region,
|
||||
geom = object:as_polygon(),
|
||||
})
|
||||
end
|
||||
"""
|
||||
When running osm2pgsql flex
|
||||
Then table osm2pgsql_test_regions contains exactly
|
||||
| way_id | region | ST_AsText(geom) |
|
||||
| 29 | P1 | (10 0,20 0,20 10,10 10, 10 0) |
|
||||
|
||||
Given the 10.0 grid with origin 10.0 10.0
|
||||
| 10 | 11 | 12 |
|
||||
| 13 | 14 | 15 |
|
||||
And the OSM data
|
||||
"""
|
||||
w20 v1 dV Nn10,n11,n13
|
||||
w21 v1 dV Nn13,n10
|
||||
w22 v1 dV Nn14,n15
|
||||
w23 v1 dV Nn12,n15
|
||||
r30 v1 dV Tfoo=bar Mw20@,w21@,w22@,n12@
|
||||
r31 v1 dV Tfoo=bar Mn12@,n15@
|
||||
r32 v1 dV Tfoo=bar Mw23@
|
||||
"""
|
||||
And the lua style
|
||||
"""
|
||||
local regions = osm2pgsql.define_locator({ name = 'regions' })
|
||||
regions:add_from_db('SELECT region, geom FROM osm2pgsql_test_regions')
|
||||
|
||||
local points = osm2pgsql.define_relation_table('osm2pgsql_test_rels', {
|
||||
{ column = 'region', type = 'text' },
|
||||
{ column = 'geom', type = 'geometry', projection = 4326 },
|
||||
})
|
||||
|
||||
function osm2pgsql.process_relation(object)
|
||||
local g = object:as_geometrycollection()
|
||||
local r = regions:first_intersecting(g)
|
||||
if r then
|
||||
points:insert({
|
||||
region = r,
|
||||
geom = g,
|
||||
})
|
||||
end
|
||||
end
|
||||
"""
|
||||
When running osm2pgsql flex
|
||||
Then table osm2pgsql_test_rels contains exactly
|
||||
| relation_id | region | ST_GeometryType(geom) |
|
||||
| 30 | P1 | ST_GeometryCollection |
|
||||
|
||||
|
Reference in New Issue
Block a user