Skip to content
Commits on Source (7)
......@@ -172,11 +172,6 @@ matrix:
dist: bionic
# OSX Clang Builds
- os: osx
osx_image: xcode8.3
compiler: xcode83-clang-dev
env: CC='clang' CXX='clang++' BUILD_TYPE='Dev'
- os: osx
osx_image: xcode9.4
compiler: xcode94-clang-dev
......
......@@ -12,6 +12,17 @@ This project adheres to [Semantic Versioning](https://semver.org/).
### Fixed
## [2.15.4] - 2019-11-28
### Added
* Add osmium::Options::empty() for consistency with STL containers.
### Fixed
* Massive reduction of memory consumption in area assembly code. For some
very complex polygons memory usage can drop from multiple gigabytes to just
megabytes.
## [2.15.3] - 2019-09-16
......@@ -974,7 +985,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
Doxygen (up to version 1.8.8). This version contains a workaround to fix
this.
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.3...HEAD
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.4...HEAD
[2.15.4]: https://github.com/osmcode/libosmium/compare/v2.15.3...v2.15.4
[2.15.3]: https://github.com/osmcode/libosmium/compare/v2.15.2...v2.15.3
[2.15.2]: https://github.com/osmcode/libosmium/compare/v2.15.1...v2.15.2
[2.15.1]: https://github.com/osmcode/libosmium/compare/v2.15.0...v2.15.1
......
......@@ -40,7 +40,7 @@ project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
set(LIBOSMIUM_VERSION_MINOR 15)
set(LIBOSMIUM_VERSION_PATCH 3)
set(LIBOSMIUM_VERSION_PATCH 4)
set(LIBOSMIUM_VERSION
"${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
......
libosmium (2.15.4-1~bpo10+1) buster-backports; urgency=medium
* Rebuild for buster-backports.
-- Bas Couwenberg <sebastic@debian.org> Fri, 06 Dec 2019 06:50:11 +0100
libosmium (2.15.4-1) unstable; urgency=medium
* New upstream release.
* Bump Standards-Version to 4.4.1, no changes.
-- Bas Couwenberg <sebastic@debian.org> Fri, 29 Nov 2019 06:35:55 +0100
libosmium (2.15.3-1~bpo10+1) buster-backports; urgency=medium
* Rebuild for buster-backports.
......
......@@ -15,7 +15,7 @@ Build-Depends: debhelper (>= 9),
libprotozero-dev (>= 1.6.3),
libsparsehash-dev,
zlib1g-dev
Standards-Version: 4.4.0
Standards-Version: 4.4.1
Vcs-Browser: https://salsa.debian.org/debian-gis-team/libosmium/
Vcs-Git: https://salsa.debian.org/debian-gis-team/libosmium.git -b buster-backports
Homepage: https://osmcode.org/libosmium/
......
......@@ -713,7 +713,7 @@ namespace osmium {
};
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, candidate& cand) {
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, const candidate& cand, unsigned depth = 0) {
if (debug()) {
std::cerr << " find_candidates sum=" << cand.sum << " start=" << cand.start_location << " stop=" << cand.stop_location << "\n";
for (const auto& ring : cand.rings) {
......@@ -751,13 +751,30 @@ namespace osmium {
if (debug()) {
std::cerr << " found candidate\n";
}
candidates.push_back(c);
if (candidates.empty()) {
candidates.push_back(c);
} else if (candidates.size() == 1) {
// add new candidate to vector, keep sorted
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.insert(candidates.begin(), c);
} else {
candidates.push_back(c);
}
} else {
// add new candidate if it has either smallest or largest area
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.front() = c;
} else if (std::abs(c.sum) > std::abs(candidates.back().sum)) {
candidates.back() = c;
}
}
} else if (loc_done.count(c.stop_location) == 0) {
if (debug()) {
std::cerr << " recurse...\n";
std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << ")\n";
}
loc_done.insert(c.stop_location);
find_candidates(candidates, loc_done, xrings, c);
find_candidates(candidates, loc_done, xrings, c, depth + 1);
loc_done.erase(c.stop_location);
if (debug()) {
std::cerr << " ...back\n";
......@@ -800,7 +817,7 @@ namespace osmium {
ring.reset();
}
candidate cand{*ring_min, false};
const candidate cand{*ring_min, false};
// Locations we have visited while finding candidates, used
// to detect loops.
......@@ -838,26 +855,20 @@ namespace osmium {
}
// Find the candidate with the smallest/largest area
const auto chosen_cand = ring_min_is_outer ?
std::min_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
return std::abs(lhs.sum) < std::abs(rhs.sum);
}) :
std::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
return std::abs(lhs.sum) < std::abs(rhs.sum);
});
const auto chosen_cand = ring_min_is_outer ? candidates.front() : candidates.back();
if (debug()) {
std::cerr << " Decided on: sum=" << chosen_cand->sum << "\n";
for (const auto& ring : chosen_cand->rings) {
std::cerr << " Decided on: sum=" << chosen_cand.sum << "\n";
for (const auto& ring : chosen_cand.rings) {
std::cerr << " " << ring.first.ring() << (ring.second ? " reverse" : "") << "\n";
}
}
// Join all (open) rings in the candidate to get one closed ring.
assert(chosen_cand->rings.size() > 1);
const auto& first_ring = chosen_cand->rings.front().first;
assert(chosen_cand.rings.size() > 1);
const auto& first_ring = chosen_cand.rings.front().first;
const ProtoRing& remaining_ring = first_ring.ring();
for (auto it = std::next(chosen_cand->rings.begin()); it != chosen_cand->rings.end(); ++it) {
for (auto it = std::next(chosen_cand.rings.begin()); it != chosen_cand.rings.end(); ++it) {
merge_two_rings(open_ring_its, first_ring, it->first);
}
......@@ -1088,7 +1099,7 @@ namespace osmium {
create_rings_simple_case();
timer_simple_case.stop();
} else if (m_split_locations.size() > max_split_locations) {
if (debug()) {
if (m_config.debug_level > 0) {
std::cerr << " Ignoring polygon with "
<< m_split_locations.size()
<< " split locations (>"
......@@ -1097,8 +1108,10 @@ namespace osmium {
}
return false;
} else {
if (debug()) {
std::cerr << " Found split locations -> using complex algorithm\n";
if (m_config.debug_level > 0) {
std::cerr << " Found "
<< m_split_locations.size()
<< " split locations -> using complex algorithm\n";
}
++m_stats.area_touching_rings_case;
......
......@@ -102,14 +102,10 @@ namespace osmium {
NodeRefSegment() noexcept = default;
NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role, const osmium::Way* way) noexcept :
m_first(nr1),
m_second(nr2),
m_first(nr1.location() < nr2.location() ? nr1 : nr2),
m_second(nr1.location() < nr2.location() ? nr2 : nr1),
m_way(way),
m_role(role) {
if (nr2.location() < nr1.location()) {
using std::swap;
swap(m_first, m_second);
}
}
/**
......@@ -206,7 +202,7 @@ namespace osmium {
/**
* The "determinant" of this segment. Used for calculating
* the winding order or a ring.
* the winding order of a ring.
*/
int64_t det() const noexcept {
const vec a{start()};
......
......@@ -196,12 +196,14 @@ namespace osmium {
}
void join_forward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (NodeRefSegment* segment : other.m_segments) {
add_segment_back(segment);
}
}
void join_backward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (auto it = other.m_segments.rbegin(); it != other.m_segments.rend(); ++it) {
(*it)->reverse();
add_segment_back(*it);
......
......@@ -147,6 +147,13 @@ namespace osmium {
return !(value == "false" || value == "no");
}
/**
* Is the set of options empty?
*/
bool empty() const noexcept {
return m_options.empty();
}
/**
* The number of options set.
*/
......
......@@ -35,8 +35,8 @@ DEALINGS IN THE SOFTWARE.
#define LIBOSMIUM_VERSION_MAJOR 2
#define LIBOSMIUM_VERSION_MINOR 15
#define LIBOSMIUM_VERSION_PATCH 3
#define LIBOSMIUM_VERSION_PATCH 4
#define LIBOSMIUM_VERSION_STRING "2.15.3"
#define LIBOSMIUM_VERSION_STRING "2.15.4"
#endif // OSMIUM_VERSION_HPP
......@@ -5,6 +5,8 @@
TEST_CASE("Set a single option value from string") {
osmium::Options o;
REQUIRE(o.empty());
o.set("foo", "bar");
REQUIRE("bar" == o.get("foo"));
REQUIRE(o.get("empty").empty());
......@@ -17,6 +19,7 @@ TEST_CASE("Set a single option value from string") {
REQUIRE(o.is_not_false("empty"));
REQUIRE(1 == o.size());
REQUIRE_FALSE(o.empty());
}
TEST_CASE("Set option values from booleans") {
......