Skip to content

Commit ef940c6

Browse files
committed
Write our own area assembler wrapper class
This is very similar to the one provided by libosmium. But it is a bit simpler, removing some code that is unnecessary for us. The actual work is done in the osmium::area::detail::BasicAssembler class anyway. And the new class is still based on that.
1 parent f8c78ae commit ef940c6

File tree

4 files changed

+135
-11
lines changed

4 files changed

+135
-11
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ target_sources(osm2pgsql_lib PRIVATE
2525
flex-table-column.cpp
2626
flex-table.cpp
2727
flex-write.cpp
28+
geom-area-assembler.cpp
2829
geom-box.cpp
2930
geom-from-osm.cpp
3031
geom-functions.cpp

src/geom-area-assembler.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* SPDX-License-Identifier: GPL-2.0-or-later
3+
*
4+
* This file is part of osm2pgsql (https://osm2pgsql.org/).
5+
*
6+
* Copyright (C) 2006-2024 by the osm2pgsql developer community.
7+
* For a full list of authors see the git log.
8+
*/
9+
10+
#include "geom-area-assembler.hpp"
11+
12+
#include <osmium/builder/osm_object_builder.hpp>
13+
14+
namespace geom {
15+
16+
const osmium::area::AssemblerConfig area_config;
17+
18+
area_assembler_t::area_assembler_t(osmium::memory::Buffer *buffer)
19+
: osmium::area::detail::BasicAssembler(area_config), m_buffer(buffer)
20+
{
21+
}
22+
23+
bool area_assembler_t::make_area()
24+
{
25+
if (!create_rings()) {
26+
return false;
27+
}
28+
29+
m_buffer->clear();
30+
{
31+
osmium::builder::AreaBuilder builder{*m_buffer};
32+
add_rings_to_area(builder);
33+
}
34+
m_buffer->commit();
35+
36+
return true;
37+
}
38+
39+
bool area_assembler_t::operator()(const osmium::Way &way)
40+
{
41+
segment_list().extract_segments_from_way(nullptr, stats().duplicate_nodes,
42+
way);
43+
return make_area();
44+
}
45+
46+
// Currently the relation is not needed for assembling the area, because
47+
// the roles on the members are ignored. In the future we might want to use
48+
// the roles, so we leave the function signature as it is.
49+
bool area_assembler_t::operator()(const osmium::Relation & /*relation*/,
50+
const osmium::memory::Buffer &ways_buffer)
51+
{
52+
for (const auto &way : ways_buffer.select<osmium::Way>()) {
53+
segment_list().extract_segments_from_way(nullptr,
54+
stats().duplicate_nodes, way);
55+
}
56+
return make_area();
57+
}
58+
59+
} // namespace geom

src/geom-area-assembler.hpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#ifndef OSM2PGSQL_GEOM_AREA_ASSEMBLER_HPP
2+
#define OSM2PGSQL_GEOM_AREA_ASSEMBLER_HPP
3+
4+
/**
5+
* SPDX-License-Identifier: GPL-2.0-or-later
6+
*
7+
* This file is part of osm2pgsql (https://osm2pgsql.org/).
8+
*
9+
* Copyright (C) 2006-2024 by the osm2pgsql developer community.
10+
* For a full list of authors see the git log.
11+
*/
12+
13+
/**
14+
* \file
15+
*
16+
* Code for assembling areas from ways or relations.
17+
*/
18+
19+
#include <osmium/area/detail/basic_assembler.hpp>
20+
21+
namespace geom {
22+
23+
/**
24+
* The area_assembler_t class is a light wrapper around the libosmium class
25+
* for assembling areas.
26+
*/
27+
class area_assembler_t : public osmium::area::detail::BasicAssembler
28+
{
29+
public:
30+
area_assembler_t(osmium::memory::Buffer *buffer);
31+
32+
/**
33+
* Assemble an area from the given way.
34+
*
35+
* @returns false if there was some kind of error building the
36+
* area, true otherwise.
37+
*/
38+
bool operator()(const osmium::Way &way);
39+
40+
/**
41+
* Assemble an area from the given relation and its member ways
42+
* which are in the ways_buffer.
43+
*
44+
* @returns false if there was some kind of error building the
45+
* area, true otherwise.
46+
*/
47+
bool operator()(const osmium::Relation &relation,
48+
const osmium::memory::Buffer &ways_buffer);
49+
50+
/**
51+
* Access the area that was built last.
52+
*/
53+
osmium::Area const &get_area() const noexcept
54+
{
55+
return m_buffer->get<osmium::Area>(0);
56+
}
57+
58+
private:
59+
bool make_area();
60+
61+
osmium::memory::Buffer* m_buffer;
62+
63+
}; // class area_assembler_t
64+
65+
} // namespace geom
66+
67+
#endif // OSM2PGSQL_GEOM_AREA_ASSEMBLER_HPP

src/geom-from-osm.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
*/
99

1010
#include "geom-from-osm.hpp"
11+
12+
#include "geom-area-assembler.hpp"
1113
#include "osmtypes.hpp"
1214

13-
#include <osmium/area/geom_assembler.hpp>
1415
#include <osmium/osm/way.hpp>
1516

1617
#include <utility>
@@ -99,17 +100,15 @@ void create_polygon(geometry_t *geom, osmium::Way const &way)
99100
return;
100101
}
101102

102-
osmium::area::AssemblerConfig area_config;
103-
area_config.ignore_invalid_locations = true;
104-
osmium::area::GeomAssembler assembler{area_config};
105103
osmium::memory::Buffer area_buffer{1024};
104+
geom::area_assembler_t assembler{&area_buffer};
106105

107-
if (!assembler(way, area_buffer)) {
106+
if (!assembler(way)) {
108107
geom->reset();
109108
return;
110109
}
111110

112-
auto const &area = area_buffer.get<osmium::Area>(0);
111+
auto const &area = assembler.get_area();
113112
auto const &ring = *area.begin<osmium::OuterRing>();
114113

115114
fill_point_list(&polygon.outer(), ring);
@@ -208,17 +207,15 @@ geometry_t create_multilinestring(osmium::memory::Buffer const &buffer,
208207
void create_multipolygon(geometry_t *geom, osmium::Relation const &relation,
209208
osmium::memory::Buffer const &buffer)
210209
{
211-
osmium::area::AssemblerConfig area_config;
212-
area_config.ignore_invalid_locations = true;
213-
osmium::area::GeomAssembler assembler{area_config};
214210
osmium::memory::Buffer area_buffer{1024};
211+
geom::area_assembler_t assembler{&area_buffer};
215212

216-
if (!assembler(relation, buffer, area_buffer)) {
213+
if (!assembler(relation, buffer)) {
217214
geom->reset();
218215
return;
219216
}
220217

221-
auto const &area = area_buffer.get<osmium::Area>(0);
218+
auto const &area = assembler.get_area();
222219

223220
if (area.is_multipolygon()) {
224221
auto &multipolygon = geom->set<multipolygon_t>();

0 commit comments

Comments
 (0)