[libosmium] 01/04: Imported Upstream version 2.12.2

Bas Couwenberg sebastic at debian.org
Wed May 3 16:36:32 UTC 2017


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch experimental
in repository libosmium.

commit afcae4980d66b6b68f068678cf7edeb6cada8c6a
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Wed May 3 18:19:56 2017 +0200

    Imported Upstream version 2.12.2
---
 CHANGELOG.md                                       |   37 +-
 CMakeLists.txt                                     |   14 +-
 appveyor.yml                                       |    5 +
 build-appveyor.bat                                 |    3 +-
 cmake/FindOsmium.cmake                             |    4 +
 include/osmium/area/assembler.hpp                  |    2 +
 include/osmium/area/detail/basic_assembler.hpp     |   36 +-
 include/osmium/area/detail/node_ref_segment.hpp    |    2 +-
 include/osmium/area/detail/proto_ring.hpp          |   18 +-
 include/osmium/area/detail/segment_list.hpp        |   21 +-
 include/osmium/area/multipolygon_collector.hpp     |    1 +
 include/osmium/area/problem_reporter.hpp           |    8 +
 include/osmium/area/problem_reporter_exception.hpp |    6 +
 include/osmium/area/problem_reporter_ogr.hpp       |   16 +
 include/osmium/area/problem_reporter_stream.hpp    |    5 +
 include/osmium/area/stats.hpp                      |    3 +
 include/osmium/index/map/dense_file_array.hpp      |    4 +
 include/osmium/index/map/dense_mem_array.hpp       |    4 +
 include/osmium/index/map/dense_mmap_array.hpp      |    4 +
 include/osmium/index/map/sparse_file_array.hpp     |    4 +
 include/osmium/index/map/sparse_mem_array.hpp      |    4 +
 include/osmium/index/map/sparse_mem_map.hpp        |    4 +
 include/osmium/index/map/sparse_mem_table.hpp      |   24 +-
 include/osmium/index/map/sparse_mmap_array.hpp     |    4 +
 include/osmium/index/node_locations_map.hpp        |    2 +
 include/osmium/io/detail/input_format.hpp          |   53 +-
 include/osmium/io/detail/o5m_input_format.hpp      |   14 +-
 include/osmium/io/detail/opl_input_format.hpp      |   19 +-
 include/osmium/io/detail/pbf_input_format.hpp      |   14 +-
 include/osmium/io/detail/xml_input_format.hpp      |   14 +-
 include/osmium/io/reader.hpp                       |   54 +-
 include/osmium/io/writer.hpp                       |   26 +-
 include/osmium/tags/matcher.hpp                    |   13 +-
 include/osmium/util/file.hpp                       |    4 +-
 include/osmium/util/string_matcher.hpp             |    2 +-
 include/osmium/version.hpp                         |    4 +-
 test/CMakeLists.txt                                |    2 +-
 test/data-tests/CMakeLists.txt                     |    6 +-
 test/data-tests/multipolygon.qgs                   | 2089 ++++++++++++--------
 test/data-tests/testdata-xml.cpp                   |   10 +-
 test/t/area/test_node_ref_segment.cpp              |   65 +-
 test/t/io/data-nonl.opl                            |    1 +
 test/t/io/data.opl                                 |    1 +
 test/t/io/test_opl_parser.cpp                      |   22 +
 test/t/io/test_reader.cpp                          |   52 +-
 test/t/io/test_reader_with_mock_parser.cpp         |   14 +-
 test/t/io/test_writer_with_mock_encoder.cpp        |    2 +-
 47 files changed, 1647 insertions(+), 1069 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02cda06..a7ddcc3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,40 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 ### Fixed
 
 
+## [2.12.2] - 2017-05-3
+
+### Added
+
+- Add two argument (key, value) overload of `TagMatcher::operator()`.
+
+### Changed
+
+- Detect, report, and remove duplicate ways in multipolygon relations.
+- Change EOF behaviour of Reader: The `Reader::read()` function will now
+  always return an invalid buffer exactly once to signal EOF.
+- Update QGIS multipolygon project that is part of the test suite to show
+  more problem types.
+- Copy multipolygon QGIS file for tests to build dir in cmake step.
+- Some code cleanups and improved debug output in multipolygon code.
+- Refactor I/O code to simplify code.
+- Disable some warnings on MSVC.
+- Various small code and build script changes.
+
+### Fixed
+
+- Two bugs in area assembler affecting very complex multipolygons and
+  multipolygons with overlapping or nearly overlapping lines.
+- Invalid use of iterators leading to undefined behaviour in area assembler
+  code.
+- Area assembler stats were not correctly counting inner rings that are
+  areas in their own right.
+- Fix a thread problem valgrind found that might or might not be real.
+- Read OPL file correctly even if trailing newline in file is missing.
+- Include order for `osmium/index/map` headers and
+  `osmium/index/node_locations_map.hpp` (or
+  `osmium/handler/node_locations_for_ways.hpp`) doesn't matter any more.
+
+
 ## [2.12.1] - 2017-04-10
 
 ### Added
@@ -606,7 +640,8 @@ This project adheres to [Semantic Versioning](http://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.12.1...HEAD
+[unreleased]: https://github.com/osmcode/libosmium/compare/v2.12.2...HEAD
+[2.12.2]: https://github.com/osmcode/libosmium/compare/v2.12.1...v2.12.2
 [2.12.1]: https://github.com/osmcode/libosmium/compare/v2.12.0...v2.12.1
 [2.12.0]: https://github.com/osmcode/libosmium/compare/v2.11.0...v2.12.0
 [2.11.0]: https://github.com/osmcode/libosmium/compare/v2.10.3...v2.11.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c570fb3..264c3ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ project(libosmium)
 
 set(LIBOSMIUM_VERSION_MAJOR 2)
 set(LIBOSMIUM_VERSION_MINOR 12)
-set(LIBOSMIUM_VERSION_PATCH 1)
+set(LIBOSMIUM_VERSION_PATCH 2)
 
 set(LIBOSMIUM_VERSION
     "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
@@ -205,7 +205,8 @@ endif()
 #-----------------------------------------------------------------------------
 if(MSVC)
     set(USUAL_COMPILE_OPTIONS "/Ox")
-    set(USUAL_LINK_OPTIONS "/debug")
+    # do not show warnings caused by missing .pdb files for libraries
+    set(USUAL_LINK_OPTIONS "/debug /ignore:4099")
 else()
     set(USUAL_COMPILE_OPTIONS "-O3 -g")
     set(USUAL_LINK_OPTIONS "")
@@ -231,6 +232,15 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}"
     CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds."
     FORCE)
 
+set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${USUAL_LINK_OPTIONS}"
+    CACHE STRING "Flags used by the linker during RELWITHDEBINFO builds."
+    FORCE)
+
+mark_as_advanced(
+    CMAKE_CXX_FLAGS_RELWITHDEBINFO
+    CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
+)
+
 if(WITH_PROFILING)
     add_definitions(-fno-omit-frame-pointer)
 endif()
diff --git a/appveyor.yml b/appveyor.yml
index 7e6060a..d1eea30 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,3 +24,8 @@ platform: x64
 
 build_script:
   - build-appveyor.bat
+
+# remove garbage VS messages
+# http://help.appveyor.com/discussions/problems/4569-the-target-_convertpdbfiles-listed-in-a-beforetargets-attribute-at-c-does-not-exist-in-the-project-and-will-be-ignored
+before_build:
+  - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
diff --git a/build-appveyor.bat b/build-appveyor.bat
index 27d387c..b4f45f3 100644
--- a/build-appveyor.bat
+++ b/build-appveyor.bat
@@ -101,7 +101,8 @@ msbuild libosmium.sln ^
 /p:Configuration=%config% ^
 /toolsversion:14.0 ^
 /p:Platform=x64 ^
-/p:PlatformToolset=v140
+/p:PlatformToolset=v140 ^
+/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 IF %ERRORLEVEL% NEQ 0 GOTO ERROR
 
 ctest --output-on-failure ^
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
index 0877ef2..adc457f 100644
--- a/cmake/FindOsmium.cmake
+++ b/cmake/FindOsmium.cmake
@@ -333,6 +333,10 @@ if(MSVC)
     # old compilers anyway.
     add_definitions(-wd4351)
 
+    # Disable warning C4503: "decorated name length exceeded, name was truncated"
+    # there are more than 150 of generated names in libosmium longer than 4096 symbols supported in MSVC
+    add_definitions(-wd4503)
+
     add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
 endif()
 
diff --git a/include/osmium/area/assembler.hpp b/include/osmium/area/assembler.hpp
index 8ec7935..9e8541a 100644
--- a/include/osmium/area/assembler.hpp
+++ b/include/osmium/area/assembler.hpp
@@ -335,6 +335,7 @@ namespace osmium {
                 ++stats().from_relations;
                 stats().invalid_locations = segment_list().extract_segments_from_ways(config().problem_reporter,
                                                                                       stats().duplicate_nodes,
+                                                                                      stats().duplicate_ways,
                                                                                       relation,
                                                                                       members);
                 if (!config().ignore_invalid_locations && stats().invalid_locations > 0) {
@@ -408,6 +409,7 @@ namespace osmium {
                     if (!assembler(*way, out_buffer)) {
                         okay = false;
                     }
+                    stats() += assembler.stats();
                 }
 
                 return okay;
diff --git a/include/osmium/area/detail/basic_assembler.hpp b/include/osmium/area/detail/basic_assembler.hpp
index 13bd976..1337611 100644
--- a/include/osmium/area/detail/basic_assembler.hpp
+++ b/include/osmium/area/detail/basic_assembler.hpp
@@ -243,17 +243,17 @@ namespace osmium {
 
                 class rings_stack_element {
 
-                    int32_t m_y;
+                    double m_y;
                     detail::ProtoRing* m_ring_ptr;
 
                 public:
 
-                    rings_stack_element(int32_t y, detail::ProtoRing* ring_ptr) :
+                    rings_stack_element(double y, detail::ProtoRing* ring_ptr) :
                         m_y(y),
                         m_ring_ptr(ring_ptr) {
                     }
 
-                    int32_t y() const noexcept {
+                    double y() const noexcept {
                         return m_y;
                     }
 
@@ -334,7 +334,7 @@ namespace osmium {
                                 }
                                 if (segment->ring()->is_outer()) {
                                     if (debug()) {
-                                        std::cerr << "        Segment belongs to outer ring\n";
+                                        std::cerr << "        Segment belongs to outer ring (y=" << a.y() << " ring=" << *segment->ring() << ")\n";
                                     }
                                     outer_rings.emplace_back(a.y(), segment->ring());
                                 }
@@ -358,10 +358,10 @@ namespace osmium {
                                     std::cerr << "        Segment is below (nesting=" << nesting << ")\n";
                                 }
                                 if (segment->ring()->is_outer()) {
+                                    const double y = ay + (by - ay) * (lx - ax) / double(bx - ax);
                                     if (debug()) {
-                                        std::cerr << "        Segment belongs to outer ring\n";
+                                        std::cerr << "        Segment belongs to outer ring (y=" << y << " ring=" << *segment->ring() << ")\n";
                                     }
-                                    const int32_t y = int32_t(ay + (by - ay) * (lx - ax) / (bx - ax));
                                     outer_rings.emplace_back(y, segment->ring());
                                 }
                             }
@@ -616,7 +616,7 @@ namespace osmium {
 
                     for (auto it = open_ring_its.begin(); it != open_ring_its.end(); ++it) {
                         if (debug()) {
-                            std::cerr << "      Ring: " << **it << "\n";
+                            std::cerr << "      " << **it << '\n';
                         }
                         xrings.emplace_back((*it)->get_node_ref_start().location(), it, true);
                         xrings.emplace_back((*it)->get_node_ref_stop().location(), it, false);
@@ -628,8 +628,8 @@ namespace osmium {
                 }
 
                 void merge_two_rings(open_ring_its_type& open_ring_its, const location_to_ring_map& m1, const location_to_ring_map& m2) {
-                    auto& r1 = *m1.ring_it;
-                    auto& r2 = *m2.ring_it;
+                    std::list<detail::ProtoRing>::iterator r1 = *m1.ring_it;
+                    std::list<detail::ProtoRing>::iterator r2 = *m2.ring_it;
 
                     if (r1->get_node_ref_stop().location() == r2->get_node_ref_start().location()) {
                         r1->join_forward(*r2);
@@ -645,11 +645,11 @@ namespace osmium {
                         assert(false);
                     }
 
+                    open_ring_its.erase(std::find(open_ring_its.begin(), open_ring_its.end(), r2));
                     m_rings.erase(r2);
-                    open_ring_its.remove(r2);
 
                     if (r1->closed()) {
-                        open_ring_its.remove(r1);
+                        open_ring_its.erase(std::find(open_ring_its.begin(), open_ring_its.end(), r1));
                     }
                 }
 
@@ -659,7 +659,7 @@ namespace osmium {
                     }
 
                     if (debug()) {
-                        std::cerr << "    Trying to merge " << open_ring_its.size() << " open rings\n";
+                        std::cerr << "    Trying to merge " << open_ring_its.size() << " open rings (try_to_merge)\n";
                     }
 
                     std::vector<location_to_ring_map> xrings = create_location_to_ring_map(open_ring_its);
@@ -721,8 +721,8 @@ namespace osmium {
                     }
 
                     const auto connections = make_range(std::equal_range(xrings.cbegin(),
-                                                                        xrings.cend(),
-                                                                        location_to_ring_map{cand.stop_location}));
+                                                                         xrings.cend(),
+                                                                         location_to_ring_map{cand.stop_location}));
 
                     assert(connections.begin() != connections.end());
 
@@ -757,6 +757,7 @@ namespace osmium {
                                 }
                                 loc_done.insert(c.stop_location);
                                 find_candidates(candidates, loc_done, xrings, c);
+                                loc_done.erase(c.stop_location);
                                 if (debug()) {
                                     std::cerr << "          ...back\n";
                                 }
@@ -779,7 +780,7 @@ namespace osmium {
                     assert(!open_ring_its.empty());
 
                     if (debug()) {
-                        std::cerr << "    Trying to merge " << open_ring_its.size() << " open rings\n";
+                        std::cerr << "    Trying to merge " << open_ring_its.size() << " open rings (join_connected_rings)\n";
                     }
 
                     std::vector<location_to_ring_map> xrings = create_location_to_ring_map(open_ring_its);
@@ -854,12 +855,13 @@ namespace osmium {
                     // 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;
-                    for (auto it = chosen_cand->rings.begin() + 1; it != chosen_cand->rings.end(); ++it) {
+                    const ProtoRing& remaining_ring = first_ring.ring();
+                    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);
                     }
 
                     if (debug()) {
-                        std::cerr << "    Merged to " << first_ring.ring() << "\n";
+                        std::cerr << "    Merged to " << remaining_ring << '\n';
                     }
 
                     return true;
diff --git a/include/osmium/area/detail/node_ref_segment.hpp b/include/osmium/area/detail/node_ref_segment.hpp
index 585ac95..8b37437 100644
--- a/include/osmium/area/detail/node_ref_segment.hpp
+++ b/include/osmium/area/detail/node_ref_segment.hpp
@@ -106,7 +106,7 @@ namespace osmium {
                     m_role(role_type::unknown) {
                 }
 
-                NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role = role_type::unknown, const osmium::Way* way = nullptr) noexcept :
+                NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role, const osmium::Way* way) noexcept :
                     m_first(nr1),
                     m_second(nr2),
                     m_way(way),
diff --git a/include/osmium/area/detail/proto_ring.hpp b/include/osmium/area/detail/proto_ring.hpp
index e1ad796..7ab353b 100644
--- a/include/osmium/area/detail/proto_ring.hpp
+++ b/include/osmium/area/detail/proto_ring.hpp
@@ -77,6 +77,15 @@ namespace osmium {
                 // If this is an inner ring, points to the outer ring.
                 ProtoRing* m_outer_ring;
 
+#ifdef OSMIUM_DEBUG_RING_NO
+                static int64_t next_num() noexcept {
+                    static int64_t counter = 0;
+                    return ++counter;
+                }
+
+                int64_t m_num;
+#endif
+
                 int64_t m_sum;
 
             public:
@@ -86,6 +95,9 @@ namespace osmium {
                     m_inner(),
                     m_min_segment(segment),
                     m_outer_ring(nullptr),
+#ifdef OSMIUM_DEBUG_RING_NO
+                    m_num(next_num()),
+#endif
                     m_sum(0) {
                     add_segment_back(segment);
                 }
@@ -200,7 +212,11 @@ namespace osmium {
                 }
 
                 void print(std::ostream& out) const {
-                    out << "[";
+#ifdef OSMIUM_DEBUG_RING_NO
+                    out << "Ring #" << m_num << " [";
+#else
+                    out << "Ring [";
+#endif
                     if (!m_segments.empty()) {
                         out << m_segments.front()->start().ref();
                     }
diff --git a/include/osmium/area/detail/segment_list.hpp b/include/osmium/area/detail/segment_list.hpp
index 2dc58a3..efc45a5 100644
--- a/include/osmium/area/detail/segment_list.hpp
+++ b/include/osmium/area/detail/segment_list.hpp
@@ -40,6 +40,7 @@ DEALINGS IN THE SOFTWARE.
 #include <iostream>
 #include <iterator>
 #include <numeric>
+#include <unordered_set>
 #include <vector>
 
 #include <osmium/area/detail/node_ref_segment.hpp>
@@ -232,7 +233,11 @@ namespace osmium {
                  * Extract all segments from all ways that make up this
                  * multipolygon relation and add them to the list.
                  */
-                uint32_t extract_segments_from_ways(osmium::area::ProblemReporter* problem_reporter, uint64_t& duplicate_nodes, const osmium::Relation& relation, const std::vector<const osmium::Way*>& members) {
+                uint32_t extract_segments_from_ways(osmium::area::ProblemReporter* problem_reporter,
+                                                    uint64_t& duplicate_nodes,
+                                                    uint64_t& duplicate_ways,
+                                                    const osmium::Relation& relation,
+                                                    const std::vector<const osmium::Way*>& members) {
                     assert(relation.members().size() >= members.size());
 
                     const size_t num_segments = get_num_segments(members);
@@ -241,10 +246,20 @@ namespace osmium {
                     }
                     m_segments.reserve(num_segments);
 
+                    std::unordered_set<osmium::object_id_type> ids;
+                    ids.reserve(members.size());
                     uint32_t invalid_locations = 0;
                     for_each_member(relation, members, [&](const osmium::RelationMember& member, const osmium::Way& way) {
-                        const auto role = parse_role(member.role());
-                        invalid_locations += extract_segments_from_way_impl(problem_reporter, duplicate_nodes, way, role);
+                        if (ids.count(way.id()) == 0) {
+                            ids.insert(way.id());
+                            const auto role = parse_role(member.role());
+                            invalid_locations += extract_segments_from_way_impl(problem_reporter, duplicate_nodes, way, role);
+                        } else {
+                            ++duplicate_ways;
+                            if (problem_reporter) {
+                                problem_reporter->report_duplicate_way(way);
+                            }
+                        }
                     });
 
                     return invalid_locations;
diff --git a/include/osmium/area/multipolygon_collector.hpp b/include/osmium/area/multipolygon_collector.hpp
index cc790e9..ad2e56d 100644
--- a/include/osmium/area/multipolygon_collector.hpp
+++ b/include/osmium/area/multipolygon_collector.hpp
@@ -174,6 +174,7 @@ namespace osmium {
                 const osmium::memory::Buffer& buffer = this->members_buffer();
 
                 std::vector<const osmium::Way*> ways;
+                ways.reserve(relation.members().size());
                 for (const auto& member : relation.members()) {
                     if (member.ref() != 0) {
                         const size_t offset = this->get_offset(member.type(), member.ref());
diff --git a/include/osmium/area/problem_reporter.hpp b/include/osmium/area/problem_reporter.hpp
index 373403b..797845b 100644
--- a/include/osmium/area/problem_reporter.hpp
+++ b/include/osmium/area/problem_reporter.hpp
@@ -199,6 +199,14 @@ namespace osmium {
             }
 
             /**
+             * Report a way that is more than once in a relation.
+             *
+             * @param way The way
+             */
+            virtual void report_duplicate_way(const osmium::Way& way) {
+            }
+
+            /**
              * In addition to reporting specific problems, this is used to
              * report all ways belonging to areas having problems.
              *
diff --git a/include/osmium/area/problem_reporter_exception.hpp b/include/osmium/area/problem_reporter_exception.hpp
index cc5eb98..f1d64d8 100644
--- a/include/osmium/area/problem_reporter_exception.hpp
+++ b/include/osmium/area/problem_reporter_exception.hpp
@@ -120,6 +120,12 @@ namespace osmium {
                 throw std::runtime_error{m_sstream.str()};
             }
 
+            void report_duplicate_way(const osmium::Way& way) override {
+                m_sstream.str("");
+                ProblemReporterStream::report_duplicate_way(way);
+                throw std::runtime_error{m_sstream.str()};
+            }
+
         }; // class ProblemReporterException
 
     } // namespace area
diff --git a/include/osmium/area/problem_reporter_ogr.hpp b/include/osmium/area/problem_reporter_ogr.hpp
index 2d8026a..80cbbc2 100644
--- a/include/osmium/area/problem_reporter_ogr.hpp
+++ b/include/osmium/area/problem_reporter_ogr.hpp
@@ -202,6 +202,22 @@ namespace osmium {
                 }
             }
 
+            void report_duplicate_way(const osmium::Way& way) override {
+                if (way.nodes().size() < 2) {
+                    return;
+                }
+                try {
+                    gdalcpp::Feature feature{m_layer_lerror, m_ogr_factory.create_linestring(way)};
+                    set_object(feature);
+                    feature.set_field("id1", int32_t(way.id()));
+                    feature.set_field("id2", 0);
+                    feature.set_field("problem", "duplicate_way");
+                    feature.add_to_layer();
+                } catch (const osmium::geometry_error&) {
+                    // XXX
+                }
+            }
+
             void report_way(const osmium::Way& way) override {
                 if (way.nodes().empty()) {
                     return;
diff --git a/include/osmium/area/problem_reporter_stream.hpp b/include/osmium/area/problem_reporter_stream.hpp
index 910eb4e..ee414a6 100644
--- a/include/osmium/area/problem_reporter_stream.hpp
+++ b/include/osmium/area/problem_reporter_stream.hpp
@@ -119,6 +119,11 @@ namespace osmium {
                 *m_out << "way_id=" << way_id << " node_id=" << node_id << '\n';
             }
 
+            void report_duplicate_way(const osmium::Way& way) override {
+                header("duplicate way");
+                *m_out << "way_id=" << way.id() << '\n';
+            }
+
         }; // class ProblemReporterStream
 
     } // namespace area
diff --git a/include/osmium/area/stats.hpp b/include/osmium/area/stats.hpp
index 48b4088..2fc18b7 100644
--- a/include/osmium/area/stats.hpp
+++ b/include/osmium/area/stats.hpp
@@ -52,6 +52,7 @@ namespace osmium {
             uint64_t area_touching_rings_case = 0; ///< More difficult case with touching rings
             uint64_t duplicate_nodes = 0; ///< Consecutive identical nodes or consecutive nodes with same location
             uint64_t duplicate_segments = 0; ///< Segments duplicated (going back and forth)
+            uint64_t duplicate_ways = 0; ///< Ways that are in relation more than once
             uint64_t from_relations = 0; ///< Area created from multipolygon relation
             uint64_t from_ways = 0; ///< Area created from way
             uint64_t inner_rings = 0; ///< Number of inner rings
@@ -76,6 +77,7 @@ namespace osmium {
                 area_touching_rings_case += other.area_touching_rings_case;
                 duplicate_nodes += other.duplicate_nodes;
                 duplicate_segments += other.duplicate_segments;
+                duplicate_ways += other.duplicate_ways;
                 from_relations += other.from_relations;
                 from_ways += other.from_ways;
                 inner_rings += other.inner_rings;
@@ -105,6 +107,7 @@ namespace osmium {
                        << " area_touching_rings_case=" << s.area_touching_rings_case
                        << " duplicate_nodes=" << s.duplicate_nodes
                        << " duplicate_segments=" << s.duplicate_segments
+                       << " duplicate_ways=" << s.duplicate_ways
                        << " from_relations=" << s.from_relations
                        << " from_ways=" << s.from_ways
                        << " inner_rings=" << s.inner_rings
diff --git a/include/osmium/index/map/dense_file_array.hpp b/include/osmium/index/map/dense_file_array.hpp
index cdde373..c567612 100644
--- a/include/osmium/index/map/dense_file_array.hpp
+++ b/include/osmium/index/map/dense_file_array.hpp
@@ -64,4 +64,8 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::DenseFileArray, dense_file_array)
+#endif
+
 #endif // OSMIUM_INDEX_MAP_DENSE_FILE_ARRAY_HPP
diff --git a/include/osmium/index/map/dense_mem_array.hpp b/include/osmium/index/map/dense_mem_array.hpp
index af610a8..8398258 100644
--- a/include/osmium/index/map/dense_mem_array.hpp
+++ b/include/osmium/index/map/dense_mem_array.hpp
@@ -54,4 +54,8 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::DenseMemArray, dense_mem_array)
+#endif
+
 #endif // OSMIUM_INDEX_MAP_DENSE_MEM_ARRAY_HPP
diff --git a/include/osmium/index/map/dense_mmap_array.hpp b/include/osmium/index/map/dense_mmap_array.hpp
index 85057dc..8f51cc5 100644
--- a/include/osmium/index/map/dense_mmap_array.hpp
+++ b/include/osmium/index/map/dense_mmap_array.hpp
@@ -55,6 +55,10 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::DenseMmapArray, dense_mmap_array)
+#endif
+
 #endif // __linux__
 
 #endif // OSMIUM_INDEX_MAP_DENSE_MMAP_ARRAY_HPP
diff --git a/include/osmium/index/map/sparse_file_array.hpp b/include/osmium/index/map/sparse_file_array.hpp
index 778b010..8898dd0 100644
--- a/include/osmium/index/map/sparse_file_array.hpp
+++ b/include/osmium/index/map/sparse_file_array.hpp
@@ -64,4 +64,8 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::SparseFileArray, sparse_file_array)
+#endif
+
 #endif // OSMIUM_INDEX_MAP_SPARSE_FILE_ARRAY_HPP
diff --git a/include/osmium/index/map/sparse_mem_array.hpp b/include/osmium/index/map/sparse_mem_array.hpp
index 752e3b0..28255a5 100644
--- a/include/osmium/index/map/sparse_mem_array.hpp
+++ b/include/osmium/index/map/sparse_mem_array.hpp
@@ -57,4 +57,8 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::SparseMemArray, sparse_mem_array)
+#endif
+
 #endif // OSMIUM_INDEX_MAP_SPARSE_MEM_ARRAY_HPP
diff --git a/include/osmium/index/map/sparse_mem_map.hpp b/include/osmium/index/map/sparse_mem_map.hpp
index f57df09..3287c33 100644
--- a/include/osmium/index/map/sparse_mem_map.hpp
+++ b/include/osmium/index/map/sparse_mem_map.hpp
@@ -120,4 +120,8 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::SparseMemMap, sparse_mem_map)
+#endif
+
 #endif // OSMIUM_INDEX_MAP_SPARSE_MEM_MAP_HPP
diff --git a/include/osmium/index/map/sparse_mem_table.hpp b/include/osmium/index/map/sparse_mem_table.hpp
index e241462..b08384b 100644
--- a/include/osmium/index/map/sparse_mem_table.hpp
+++ b/include/osmium/index/map/sparse_mem_table.hpp
@@ -54,16 +54,16 @@ namespace osmium {
         namespace map {
 
             /**
-            * The SparseMemTable index stores elements in a Google sparsetable,
-            * a data structure that can hold sparsly filled tables in a
-            * space efficient way. It will resize automatically.
-            *
-            * Use this index if the ID space is only sparsly
-            * populated, such as when working with smaller OSM files (like
-            * country extracts).
-            *
-            * This will only work on 64 bit machines.
-            */
+             * The SparseMemTable index stores elements in a Google sparsetable,
+             * a data structure that can hold sparsly filled tables in a
+             * space efficient way. It will resize automatically.
+             *
+             * Use this index if the ID space is only sparsly
+             * populated, such as when working with smaller OSM files (like
+             * country extracts).
+             *
+             * This will only work on 64 bit machines.
+             */
             template <typename TId, typename TValue>
             class SparseMemTable : public osmium::index::map::Map<TId, TValue> {
 
@@ -150,6 +150,10 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::SparseMemTable, sparse_mem_table)
+#endif
+
 #endif // OSMIUM_WITH_SPARSEHASH
 
 #endif // OSMIUM_INDEX_MAP_SPARSE_MEM_TABLE_HPP
diff --git a/include/osmium/index/map/sparse_mmap_array.hpp b/include/osmium/index/map/sparse_mmap_array.hpp
index 1c15abc..03b49a5 100644
--- a/include/osmium/index/map/sparse_mmap_array.hpp
+++ b/include/osmium/index/map/sparse_mmap_array.hpp
@@ -55,6 +55,10 @@ namespace osmium {
 
 } // namespace osmium
 
+#ifdef OSMIUM_WANT_NODE_LOCATION_MAPS
+    REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::SparseMmapArray, sparse_mmap_array)
+#endif
+
 #endif // __linux__
 
 #endif // OSMIUM_INDEX_MAP_SPARSE_MMAP_ARRAY_HPP
diff --git a/include/osmium/index/node_locations_map.hpp b/include/osmium/index/node_locations_map.hpp
index 0642875..4b096c4 100644
--- a/include/osmium/index/node_locations_map.hpp
+++ b/include/osmium/index/node_locations_map.hpp
@@ -35,6 +35,8 @@ DEALINGS IN THE SOFTWARE.
 
 #include <osmium/index/map.hpp> // IWYU pragma: keep
 
+#define OSMIUM_WANT_NODE_LOCATION_MAPS
+
 #ifdef OSMIUM_HAS_INDEX_MAP_DENSE_FILE_ARRAY
     REGISTER_MAP(osmium::unsigned_object_id_type, osmium::Location, osmium::index::map::DenseFileArray, dense_file_array)
 #endif
diff --git a/include/osmium/io/detail/input_format.hpp b/include/osmium/io/detail/input_format.hpp
index beb5b68..8651a35 100644
--- a/include/osmium/io/detail/input_format.hpp
+++ b/include/osmium/io/detail/input_format.hpp
@@ -55,9 +55,12 @@ namespace osmium {
 
         namespace detail {
 
-            struct reader_options {
-                osmium::osm_entity_bits::type read_which_entities = osm_entity_bits::all;
-                osmium::io::read_meta read_metadata = read_meta::yes;
+            struct parser_arguments {
+                future_string_queue_type& input_queue;
+                future_buffer_queue_type& output_queue;
+                std::promise<osmium::io::Header>& header_promise;
+                osmium::osm_entity_bits::type read_which_entities;
+                osmium::io::read_meta read_metadata;
             };
 
             class Parser {
@@ -65,7 +68,8 @@ namespace osmium {
                 future_buffer_queue_type& m_output_queue;
                 std::promise<osmium::io::Header>& m_header_promise;
                 queue_wrapper<std::string> m_input_queue;
-                reader_options m_options;
+                osmium::osm_entity_bits::type m_read_which_entities;
+                osmium::io::read_meta m_read_metadata;
                 bool m_header_is_done;
 
             protected:
@@ -79,11 +83,11 @@ namespace osmium {
                 }
 
                 osmium::osm_entity_bits::type read_types() const noexcept {
-                    return m_options.read_which_entities;
+                    return m_read_which_entities;
                 }
 
                 osmium::io::read_meta read_metadata() const noexcept {
-                    return m_options.read_metadata;
+                    return m_read_metadata;
                 }
 
                 bool header_is_done() const noexcept {
@@ -117,14 +121,12 @@ namespace osmium {
 
             public:
 
-                Parser(future_string_queue_type& input_queue,
-                       future_buffer_queue_type& output_queue,
-                       std::promise<osmium::io::Header>& header_promise,
-                       osmium::io::detail::reader_options options) :
-                    m_output_queue(output_queue),
-                    m_header_promise(header_promise),
-                    m_input_queue(input_queue),
-                    m_options(options),
+                Parser(parser_arguments& args) :
+                    m_output_queue(args.output_queue),
+                    m_header_promise(args.header_promise),
+                    m_input_queue(args.input_queue),
+                    m_read_which_entities(args.read_which_entities),
+                    m_read_metadata(args.read_metadata),
                     m_header_is_done(false) {
                 }
 
@@ -163,10 +165,7 @@ namespace osmium {
 
             public:
 
-                using create_parser_type = std::function<std::unique_ptr<Parser>(future_string_queue_type&,
-                                                                                 future_buffer_queue_type&,
-                                                                                 std::promise<osmium::io::Header>& header_promise,
-                                                                                 osmium::io::detail::reader_options options)>;
+                using create_parser_type = std::function<std::unique_ptr<Parser>(parser_arguments&)>;
 
             private:
 
@@ -185,22 +184,20 @@ namespace osmium {
                     return factory;
                 }
 
-                bool register_parser(osmium::io::file_format format, create_parser_type create_function) {
-                    if (! m_callbacks.insert(map_type::value_type(format, create_function)).second) {
-                        return false;
-                    }
-                    return true;
+                bool register_parser(osmium::io::file_format format, create_parser_type&& create_function) {
+                    const auto result = m_callbacks.emplace(format, std::forward<create_parser_type>(create_function));
+                    return result.second;
                 }
 
-                create_parser_type get_creator_function(const osmium::io::File& file) {
-                    auto it = m_callbacks.find(file.format());
+                create_parser_type get_creator_function(const osmium::io::File& file) const {
+                    const auto it = m_callbacks.find(file.format());
                     if (it == m_callbacks.end()) {
-                        throw unsupported_file_format_error(
-                                std::string("Can not open file '") +
+                        throw unsupported_file_format_error{
+                                std::string{"Can not open file '"} +
                                 file.filename() +
                                 "' with type '" +
                                 as_string(file.format()) +
-                                "'. No support for reading this format in this program.");
+                                "'. No support for reading this format in this program."};
                     }
                     return it->second;
                 }
diff --git a/include/osmium/io/detail/o5m_input_format.hpp b/include/osmium/io/detail/o5m_input_format.hpp
index 36db4e4..fa47ed0 100644
--- a/include/osmium/io/detail/o5m_input_format.hpp
+++ b/include/osmium/io/detail/o5m_input_format.hpp
@@ -589,11 +589,8 @@ namespace osmium {
 
             public:
 
-                O5mParser(future_string_queue_type& input_queue,
-                          future_buffer_queue_type& output_queue,
-                          std::promise<osmium::io::Header>& header_promise,
-                          osmium::io::detail::reader_options options) :
-                    Parser(input_queue, output_queue, header_promise, options),
+                O5mParser(parser_arguments& args) :
+                    Parser(args),
                     m_header(),
                     m_buffer(buffer_size),
                     m_input(),
@@ -616,11 +613,8 @@ namespace osmium {
             // the variable is only a side-effect, it will never be used
             const bool registered_o5m_parser = ParserFactory::instance().register_parser(
                 file_format::o5m,
-                [](future_string_queue_type& input_queue,
-                    future_buffer_queue_type& output_queue,
-                    std::promise<osmium::io::Header>& header_promise,
-                    osmium::io::detail::reader_options options) {
-                    return std::unique_ptr<Parser>(new O5mParser(input_queue, output_queue, header_promise, options));
+                [](parser_arguments& args) {
+                    return std::unique_ptr<Parser>(new O5mParser{args});
             });
 
             // dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/opl_input_format.hpp b/include/osmium/io/detail/opl_input_format.hpp
index 135f1a5..fd556e6 100644
--- a/include/osmium/io/detail/opl_input_format.hpp
+++ b/include/osmium/io/detail/opl_input_format.hpp
@@ -79,11 +79,8 @@ namespace osmium {
 
             public:
 
-                OPLParser(future_string_queue_type& input_queue,
-                          future_buffer_queue_type& output_queue,
-                          std::promise<osmium::io::Header>& header_promise,
-                          osmium::io::detail::reader_options options) :
-                    Parser(input_queue, output_queue, header_promise, options) {
+                OPLParser(parser_arguments& args) :
+                    Parser(args) {
                     set_header_value(osmium::io::Header{});
                 }
 
@@ -123,6 +120,11 @@ namespace osmium {
                         rest = input.substr(ppos);
                     }
 
+                    if (!rest.empty()) {
+                        m_data = rest.data();
+                        parse_line();
+                    }
+
                     if (m_buffer.committed() > 0) {
                         send_to_output_queue(std::move(m_buffer));
                     }
@@ -134,11 +136,8 @@ namespace osmium {
             // the variable is only a side-effect, it will never be used
             const bool registered_opl_parser = ParserFactory::instance().register_parser(
                 file_format::opl,
-                [](future_string_queue_type& input_queue,
-                    future_buffer_queue_type& output_queue,
-                    std::promise<osmium::io::Header>& header_promise,
-                    osmium::io::detail::reader_options options) {
-                    return std::unique_ptr<Parser>(new OPLParser(input_queue, output_queue, header_promise, options));
+                [](parser_arguments& args) {
+                    return std::unique_ptr<Parser>(new OPLParser{args});
             });
 
             // dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/pbf_input_format.hpp b/include/osmium/io/detail/pbf_input_format.hpp
index 74fc4f8..b5cd058 100644
--- a/include/osmium/io/detail/pbf_input_format.hpp
+++ b/include/osmium/io/detail/pbf_input_format.hpp
@@ -192,11 +192,8 @@ namespace osmium {
 
             public:
 
-                PBFParser(future_string_queue_type& input_queue,
-                          future_buffer_queue_type& output_queue,
-                          std::promise<osmium::io::Header>& header_promise,
-                          osmium::io::detail::reader_options options) :
-                    Parser(input_queue, output_queue, header_promise, options),
+                PBFParser(parser_arguments& args) :
+                    Parser(args),
                     m_input_buffer() {
                 }
 
@@ -218,11 +215,8 @@ namespace osmium {
             // the variable is only a side-effect, it will never be used
             const bool registered_pbf_parser = ParserFactory::instance().register_parser(
                 file_format::pbf,
-                [](future_string_queue_type& input_queue,
-                    future_buffer_queue_type& output_queue,
-                    std::promise<osmium::io::Header>& header_promise,
-                    osmium::io::detail::reader_options options) {
-                    return std::unique_ptr<Parser>(new PBFParser(input_queue, output_queue, header_promise, options));
+                [](parser_arguments& args) {
+                    return std::unique_ptr<Parser>(new PBFParser{args});
             });
 
             // dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/xml_input_format.hpp b/include/osmium/io/detail/xml_input_format.hpp
index 1b849ae..a14c7f9 100644
--- a/include/osmium/io/detail/xml_input_format.hpp
+++ b/include/osmium/io/detail/xml_input_format.hpp
@@ -627,11 +627,8 @@ namespace osmium {
 
             public:
 
-                XMLParser(future_string_queue_type& input_queue,
-                          future_buffer_queue_type& output_queue,
-                          std::promise<osmium::io::Header>& header_promise,
-                          osmium::io::detail::reader_options options) :
-                    Parser(input_queue, output_queue, header_promise, options),
+                XMLParser(parser_arguments& args) :
+                    Parser(args),
                     m_context(context::root),
                     m_last_context(context::root),
                     m_in_delete_section(false),
@@ -675,11 +672,8 @@ namespace osmium {
             // the variable is only a side-effect, it will never be used
             const bool registered_xml_parser = ParserFactory::instance().register_parser(
                 file_format::xml,
-                [](future_string_queue_type& input_queue,
-                    future_buffer_queue_type& output_queue,
-                    std::promise<osmium::io::Header>& header_promise,
-                    osmium::io::detail::reader_options options) {
-                    return std::unique_ptr<Parser>(new XMLParser{input_queue, output_queue, header_promise, options});
+                [](parser_arguments& args) {
+                    return std::unique_ptr<Parser>(new XMLParser{args});
             });
 
             // dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/reader.hpp b/include/osmium/io/reader.hpp
index 825cb41..55b13be 100644
--- a/include/osmium/io/reader.hpp
+++ b/include/osmium/io/reader.hpp
@@ -97,7 +97,7 @@ namespace osmium {
             enum class status {
                 okay   = 0, // normal reading
                 error  = 1, // some error occurred while reading
-                closed = 2, // close() called successfully after eof
+                closed = 2, // close() called
                 eof    = 3  // eof of file was reached without error
             } m_status;
 
@@ -119,14 +119,15 @@ namespace osmium {
 
             size_t m_file_size;
 
-            osmium::io::detail::reader_options m_options;
+            osmium::osm_entity_bits::type m_read_which_entities = osmium::osm_entity_bits::all;
+            osmium::io::read_meta m_read_metadata = osmium::io::read_meta::yes;
 
             void set_option(osmium::osm_entity_bits::type value) noexcept {
-                m_options.read_which_entities = value;
+                m_read_which_entities = value;
             }
 
             void set_option(osmium::io::read_meta value) noexcept {
-                m_options.read_metadata = value;
+                m_read_metadata = value;
             }
 
             // This function will run in a separate thread.
@@ -134,10 +135,17 @@ namespace osmium {
                                       detail::future_string_queue_type& input_queue,
                                       detail::future_buffer_queue_type& osmdata_queue,
                                       std::promise<osmium::io::Header>&& header_promise,
-                                      osmium::io::detail::reader_options options) {
+                                      osmium::osm_entity_bits::type read_which_entities,
+                                      osmium::io::read_meta read_metadata) {
                 std::promise<osmium::io::Header> promise = std::move(header_promise);
-                const auto parser = creator(input_queue, osmdata_queue, promise, options);
-                parser->parse();
+                osmium::io::detail::parser_arguments args = {
+                    input_queue,
+                    osmdata_queue,
+                    promise,
+                    read_which_entities,
+                    read_metadata
+                };
+                creator(args)->parse();
             }
 
 #ifndef _WIN32
@@ -155,11 +163,11 @@ namespace osmium {
             static int execute(const std::string& command, const std::string& filename, int* childpid) {
                 int pipefd[2];
                 if (pipe(pipefd) < 0) {
-                    throw std::system_error(errno, std::system_category(), "opening pipe failed");
+                    throw std::system_error{errno, std::system_category(), "opening pipe failed"};
                 }
                 const pid_t pid = fork();
                 if (pid < 0) {
-                    throw std::system_error(errno, std::system_category(), "fork failed");
+                    throw std::system_error{errno, std::system_category(), "fork failed"};
                 }
                 if (pid == 0) { // child
                     // close all file descriptors except one end of the pipe
@@ -203,7 +211,7 @@ namespace osmium {
 #ifndef _WIN32
                     return execute("curl", filename, childpid);
 #else
-                    throw io_error("Reading OSM files from the network currently not supported on Windows.");
+                    throw io_error{"Reading OSM files from the network currently not supported on Windows."};
 #endif
                 } else {
                     return osmium::io::detail::open_for_reading(filename);
@@ -258,7 +266,7 @@ namespace osmium {
 
                 std::promise<osmium::io::Header> header_promise;
                 m_header_future = header_promise.get_future();
-                m_thread = osmium::thread::thread_handler{parser_thread, std::ref(m_creator), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_options};
+                m_thread = osmium::thread::thread_handler{parser_thread, std::ref(m_creator), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_read_which_entities, m_read_metadata};
             }
 
             template <typename... TArgs>
@@ -313,7 +321,7 @@ namespace osmium {
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wold-style-cast"
                     if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-                        throw std::system_error(errno, std::system_category(), "subprocess returned error");
+                        throw std::system_error{errno, std::system_category(), "subprocess returned error"};
                     }
 #pragma GCC diagnostic pop
                     m_childpid = 0;
@@ -329,30 +337,26 @@ namespace osmium {
              */
             osmium::io::Header header() {
                 if (m_status == status::error) {
-                    throw io_error("Can not get header from reader when in status 'error'");
+                    throw io_error{"Can not get header from reader when in status 'error'"};
                 }
 
                 try {
                     if (m_header_future.valid()) {
                         m_header = m_header_future.get();
-                        if (m_options.read_which_entities == osmium::osm_entity_bits::nothing) {
-                            m_status = status::eof;
-                        }
                     }
                 } catch (...) {
                     close();
                     m_status = status::error;
                     throw;
                 }
+
                 return m_header;
             }
 
             /**
              * Reads the next buffer from the input. An invalid buffer signals
-             * end-of-file. After end-of-file all read() calls will return an
-             * invalid buffer. An invalid buffer is also always returned if
-             * osmium::osm_entity_bits::nothing was set when the Reader was
-             * constructed.
+             * end-of-file. After end-of-file all read() calls will throw an
+             * osmium::io_error.
              *
              * @returns Buffer.
              * @throws Some form of osmium::io_error if there is an error.
@@ -360,9 +364,13 @@ namespace osmium {
             osmium::memory::Buffer read() {
                 osmium::memory::Buffer buffer;
 
-                if (m_status != status::okay ||
-                    m_options.read_which_entities == osmium::osm_entity_bits::nothing) {
-                    throw io_error("Can not read from reader when in status 'closed', 'eof', or 'error'");
+                if (m_status != status::okay) {
+                    throw io_error{"Can not read from reader when in status 'closed', 'eof', or 'error'"};
+                }
+
+                if (m_read_which_entities == osmium::osm_entity_bits::nothing) {
+                    m_status = status::eof;
+                    return buffer;
                 }
 
                 try {
diff --git a/include/osmium/io/writer.hpp b/include/osmium/io/writer.hpp
index f38a706..1397a22 100644
--- a/include/osmium/io/writer.hpp
+++ b/include/osmium/io/writer.hpp
@@ -183,6 +183,17 @@ namespace osmium {
                 options.sync = value;
             }
 
+            void do_close() {
+                if (m_status == status::okay) {
+                    ensure_cleanup([&](){
+                        do_write(std::move(m_buffer));
+                        m_output->write_end();
+                        m_status = status::closed;
+                        detail::add_end_of_data_to_queue(m_output_queue);
+                    });
+                }
+            }
+
         public:
 
             /**
@@ -245,12 +256,12 @@ namespace osmium {
 
             template <typename... TArgs>
             explicit Writer(const std::string& filename, TArgs&&... args) :
-                Writer(osmium::io::File(filename), std::forward<TArgs>(args)...) {
+                Writer(osmium::io::File{filename}, std::forward<TArgs>(args)...) {
             }
 
             template <typename... TArgs>
             explicit Writer(const char* filename, TArgs&&... args) :
-                Writer(osmium::io::File(filename), std::forward<TArgs>(args)...) {
+                Writer(osmium::io::File{filename}, std::forward<TArgs>(args)...) {
             }
 
             Writer(const Writer&) = delete;
@@ -261,7 +272,7 @@ namespace osmium {
 
             ~Writer() noexcept {
                 try {
-                    close();
+                    do_close();
                 } catch (...) {
                     // Ignore any exceptions because destructor must not throw.
                 }
@@ -342,14 +353,7 @@ namespace osmium {
              * @throws Some form of osmium::io_error when there is a problem.
              */
             void close() {
-                if (m_status == status::okay) {
-                    ensure_cleanup([&](){
-                        do_write(std::move(m_buffer));
-                        m_output->write_end();
-                        m_status = status::closed;
-                        detail::add_end_of_data_to_queue(m_output_queue);
-                    });
-                }
+                do_close();
 
                 if (m_write_future.valid()) {
                     m_write_future.get();
diff --git a/include/osmium/tags/matcher.hpp b/include/osmium/tags/matcher.hpp
index d424a5d..4b1978b 100644
--- a/include/osmium/tags/matcher.hpp
+++ b/include/osmium/tags/matcher.hpp
@@ -93,13 +93,22 @@ namespace osmium {
         }
 
         /**
+         * Match against the specified key and value.
+         *
+         * @returns true if the tag matches.
+         */
+        bool operator()(const char* key, const char* value) const noexcept {
+            return m_key_matcher(key) &&
+                   (m_value_matcher(value) == m_result);
+        }
+
+        /**
          * Match against the specified tag.
          *
          * @returns true if the tag matches.
          */
         bool operator()(const osmium::Tag& tag) const noexcept {
-            return m_key_matcher(tag.key()) &&
-                   (m_value_matcher(tag.value()) == m_result);
+            return operator()(tag.key(), tag.value());
         }
 
         /**
diff --git a/include/osmium/util/file.hpp b/include/osmium/util/file.hpp
index b103057..17897b4 100644
--- a/include/osmium/util/file.hpp
+++ b/include/osmium/util/file.hpp
@@ -42,7 +42,9 @@ DEALINGS IN THE SOFTWARE.
 #include <sys/types.h>
 
 #ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN // Prevent winsock.h inclusion; avoid winsock2.h conflict
+#  ifndef WIN32_LEAN_AND_MEAN
+#   define WIN32_LEAN_AND_MEAN // Prevent winsock.h inclusion; avoid winsock2.h conflict
+#  endif
 # include <io.h>
 # include <windows.h>
 #endif
diff --git a/include/osmium/util/string_matcher.hpp b/include/osmium/util/string_matcher.hpp
index 9c79ecb..1aff423 100644
--- a/include/osmium/util/string_matcher.hpp
+++ b/include/osmium/util/string_matcher.hpp
@@ -188,7 +188,7 @@ namespace osmium {
             }
 
             bool match(const char* test_string) const noexcept {
-                return std::strstr(test_string, m_str.c_str());
+                return std::strstr(test_string, m_str.c_str()) != nullptr;
             }
 
             template <typename TChar, typename TTraits>
diff --git a/include/osmium/version.hpp b/include/osmium/version.hpp
index d5f88b5..5f3b10e 100644
--- a/include/osmium/version.hpp
+++ b/include/osmium/version.hpp
@@ -35,8 +35,8 @@ DEALINGS IN THE SOFTWARE.
 
 #define LIBOSMIUM_VERSION_MAJOR 2
 #define LIBOSMIUM_VERSION_MINOR 12
-#define LIBOSMIUM_VERSION_PATCH 1
+#define LIBOSMIUM_VERSION_PATCH 2
 
-#define LIBOSMIUM_VERSION_STRING "2.12.1"
+#define LIBOSMIUM_VERSION_STRING "2.12.2"
 
 #endif // OSMIUM_VERSION_HPP
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index bf1b02d..767972e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -174,7 +174,7 @@ add_unit_test(io test_reader LIBS "${OSMIUM_XML_LIBRARIES};${OSMIUM_PBF_LIBRARIE
 add_unit_test(io test_reader_fileformat ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
 add_unit_test(io test_reader_with_mock_decompression ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES})
 add_unit_test(io test_reader_with_mock_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
-add_unit_test(io test_opl_parser)
+add_unit_test(io test_opl_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
 add_unit_test(io test_output_utils)
 add_unit_test(io test_output_iterator ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
 add_unit_test(io test_string_table)
diff --git a/test/data-tests/CMakeLists.txt b/test/data-tests/CMakeLists.txt
index 8e05267..eed19f3 100644
--- a/test/data-tests/CMakeLists.txt
+++ b/test/data-tests/CMakeLists.txt
@@ -92,7 +92,10 @@ set_tests_properties(testdata-overview PROPERTIES
 #-----------------------------------------------------------------------------
 
 find_program(RUBY ruby)
-find_package(Gem COMPONENTS json)
+if(RUBY)
+    find_package(Gem COMPONENTS json)
+endif()
+
 find_program(SPATIALITE spatialite)
 
 if(RUBY AND GEM_json_FOUND AND SPATIALITE)
@@ -110,6 +113,7 @@ if(RUBY AND GEM_json_FOUND AND SPATIALITE)
                 -P ${CMAKE_CURRENT_SOURCE_DIR}/run-testdata-multipolygon.cmake)
 
     set_tests_properties(testdata-multipolygon PROPERTIES LABELS "data;slow")
+    configure_file(multipolygon.qgs ${CMAKE_CURRENT_BINARY_DIR}/multipolygon.qgs @ONLY)
 else()
     message(WARNING "Disabled testdata-multipolygon test because 'ruby' and/or 'json' ruby gem and/or 'spatialite' was not found")
 endif()
diff --git a/test/data-tests/multipolygon.qgs b/test/data-tests/multipolygon.qgs
index 5553670..cf121c3 100644
--- a/test/data-tests/multipolygon.qgs
+++ b/test/data-tests/multipolygon.qgs
@@ -1,880 +1,1213 @@
 <!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
-<qgis projectname="" version="2.2.0-Valmiera">
-    <title></title>
-    <relations/>
-    <mapcanvas>
-        <units>degrees</units>
-        <extent>
-            <xmin>0.77500024999999972</xmin>
-            <ymin>-0.84791712574962541</ymin>
-            <xmax>10.22498975000000065</xmax>
-            <ymax>3.94791712574962572</ymax>
-        </extent>
-        <projections>0</projections>
-        <destinationsrs>
-            <spatialrefsys>
-                <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
-                <srsid>3452</srsid>
-                <srid>4326</srid>
-                <authid>EPSG:4326</authid>
-                <description>WGS 84</description>
-                <projectionacronym>longlat</projectionacronym>
-                <ellipsoidacronym>WGS84</ellipsoidacronym>
-                <geographicflag>true</geographicflag>
-            </spatialrefsys>
-        </destinationsrs>
-        <layer_coordinate_transform_info/>
-    </mapcanvas>
-    <legend updateDrawingOrder="true">
-        <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Error Points" showFeatureCount="0">
-            <filegroup open="true" hidden="false">
-                <legendlayerfile isInOverview="0" layerid="perrors20140228163658956" visible="1"/>
-            </filegroup>
-        </legendlayer>
-        <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Error Lines" showFeatureCount="0">
-            <filegroup open="true" hidden="false">
-                <legendlayerfile isInOverview="0" layerid="lerrors20140228172357933" visible="1"/>
-            </filegroup>
-        </legendlayer>
-        <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="multipolygons" showFeatureCount="0">
-            <filegroup open="true" hidden="false">
-                <legendlayerfile isInOverview="0" layerid="multipolygons20140221151811742" visible="1"/>
-            </filegroup>
-        </legendlayer>
-        <legendgroup embedded="1" drawingOrder="-1" open="true" checked="Qt::Checked" name="Overview" project="../../../osm-testdata/grid/tests.qgs"/>
-        <legendgroup embedded="1" drawingOrder="-1" open="true" checked="Qt::Checked" name="Test Framework" project="../../../osm-testdata/grid/tests.qgs"/>
-    </legend>
-    <projectlayers layercount="9">
-        <maplayer minimumScale="-4.65661e-10" maximumScale="1e+08" simplifyDrawingHints="1" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Line" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
-            <id>lerrors20140228172357933</id>
-            <datasource>dbname='./multipolygon.db' table="lerrors" (GEOMETRY) sql=</datasource>
-            <title></title>
-            <abstract></abstract>
-            <keywordList>
-                <value></value>
-            </keywordList>
-            <layername>Error Lines</layername>
-            <srs>
-                <spatialrefsys>
-                    <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
-                    <srsid>3452</srsid>
-                    <srid>4326</srid>
-                    <authid>EPSG:4326</authid>
-                    <description>WGS 84</description>
-                    <projectionacronym>longlat</projectionacronym>
-                    <ellipsoidacronym>WGS84</ellipsoidacronym>
-                    <geographicflag>true</geographicflag>
-                </spatialrefsys>
-            </srs>
-            <provider encoding="System">spatialite</provider>
-            <previewExpression>COALESCE( "OGC_FID", '<NULL>' )</previewExpression>
-            <vectorjoins/>
-            <renderer-v2 attr="problem_type" symbollevels="0" type="categorizedSymbol">
-                <categories>
-                    <category symbol="0" value="intersection" label="intersection"/>
-                    <category symbol="1" value="role_should_be_outer" label="role_should_be_outer"/>
-                    <category symbol="2" value="role_should_be_inner" label="role_should_be_inner"/>
-                    <category symbol="3" value="" label=""/>
-                </categories>
-                <symbols>
-                    <symbol alpha="1" type="line" name="0">
-                        <layer pass="0" class="SimpleLine" locked="0">
-                            <prop k="capstyle" v="square"/>
-                            <prop k="color" v="255,0,0,255"/>
-                            <prop k="customdash" v="5;2"/>
-                            <prop k="customdash_unit" v="MM"/>
-                            <prop k="draw_inside_polygon" v="0"/>
-                            <prop k="joinstyle" v="bevel"/>
-                            <prop k="offset" v="0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="penstyle" v="solid"/>
-                            <prop k="use_custom_dash" v="0"/>
-                            <prop k="width" v="0.5"/>
-                            <prop k="width_unit" v="MM"/>
-                        </layer>
-                    </symbol>
-                    <symbol alpha="1" type="line" name="1">
-                        <layer pass="0" class="SimpleLine" locked="0">
-                            <prop k="capstyle" v="square"/>
-                            <prop k="color" v="255,122,33,255"/>
-                            <prop k="customdash" v="5;2"/>
-                            <prop k="customdash_unit" v="MM"/>
-                            <prop k="draw_inside_polygon" v="0"/>
-                            <prop k="joinstyle" v="bevel"/>
-                            <prop k="offset" v="0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="penstyle" v="solid"/>
-                            <prop k="use_custom_dash" v="0"/>
-                            <prop k="width" v="0.5"/>
-                            <prop k="width_unit" v="MM"/>
-                        </layer>
-                    </symbol>
-                    <symbol alpha="1" type="line" name="2">
-                        <layer pass="0" class="SimpleLine" locked="0">
-                            <prop k="capstyle" v="square"/>
-                            <prop k="color" v="255,122,33,255"/>
-                            <prop k="customdash" v="5;2"/>
-                            <prop k="customdash_unit" v="MM"/>
-                            <prop k="draw_inside_polygon" v="0"/>
-                            <prop k="joinstyle" v="bevel"/>
-                            <prop k="offset" v="0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="penstyle" v="dash"/>
-                            <prop k="use_custom_dash" v="0"/>
-                            <prop k="width" v="0.5"/>
-                            <prop k="width_unit" v="MM"/>
-                        </layer>
-                    </symbol>
-                    <symbol alpha="1" type="line" name="3">
-                        <layer pass="0" class="SimpleLine" locked="0">
-                            <prop k="capstyle" v="square"/>
-                            <prop k="color" v="255,0,0,255"/>
-                            <prop k="customdash" v="5;2"/>
-                            <prop k="customdash_unit" v="MM"/>
-                            <prop k="draw_inside_polygon" v="0"/>
-                            <prop k="joinstyle" v="bevel"/>
-                            <prop k="offset" v="0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="penstyle" v="solid"/>
-                            <prop k="use_custom_dash" v="0"/>
-                            <prop k="width" v="0.5"/>
-                            <prop k="width_unit" v="MM"/>
-                        </layer>
-                    </symbol>
-                </symbols>
-                <source-symbol>
-                    <symbol alpha="1" type="line" name="0">
-                        <layer pass="0" class="SimpleLine" locked="0">
-                            <prop k="capstyle" v="square"/>
-                            <prop k="color" v="77,243,51,255"/>
-                            <prop k="customdash" v="5;2"/>
-                            <prop k="customdash_unit" v="MM"/>
-                            <prop k="draw_inside_polygon" v="0"/>
-                            <prop k="joinstyle" v="bevel"/>
-                            <prop k="offset" v="0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="penstyle" v="solid"/>
-                            <prop k="use_custom_dash" v="0"/>
-                            <prop k="width" v="0.26"/>
-                            <prop k="width_unit" v="MM"/>
-                        </layer>
-                    </symbol>
-                </source-symbol>
-                <rotation/>
-                <sizescale scalemethod="area"/>
-            </renderer-v2>
-            <customproperties>
-                <property key="labeling" value="pal"/>
-                <property key="labeling/addDirectionSymbol" value="false"/>
-                <property key="labeling/angleOffset" value="0"/>
-                <property key="labeling/blendMode" value="0"/>
-                <property key="labeling/bufferBlendMode" value="0"/>
-                <property key="labeling/bufferColorA" value="255"/>
-                <property key="labeling/bufferColorB" value="255"/>
-                <property key="labeling/bufferColorG" value="255"/>
-                <property key="labeling/bufferColorR" value="255"/>
-                <property key="labeling/bufferDraw" value="false"/>
-                <property key="labeling/bufferJoinStyle" value="64"/>
-                <property key="labeling/bufferNoFill" value="false"/>
-                <property key="labeling/bufferSize" value="1"/>
-                <property key="labeling/bufferSizeInMapUnits" value="false"/>
-                <property key="labeling/bufferTransp" value="0"/>
-                <property key="labeling/centroidWhole" value="false"/>
-                <property key="labeling/decimals" value="3"/>
-                <property key="labeling/displayAll" value="false"/>
-                <property key="labeling/dist" value="0"/>
-                <property key="labeling/distInMapUnits" value="false"/>
-                <property key="labeling/enabled" value="false"/>
-                <property key="labeling/fieldName" value=""/>
-                <property key="labeling/fontBold" value="false"/>
-                <property key="labeling/fontCapitals" value="0"/>
-                <property key="labeling/fontFamily" value="Sans"/>
-                <property key="labeling/fontItalic" value="false"/>
-                <property key="labeling/fontLetterSpacing" value="0"/>
-                <property key="labeling/fontLimitPixelSize" value="false"/>
-                <property key="labeling/fontMaxPixelSize" value="10000"/>
-                <property key="labeling/fontMinPixelSize" value="3"/>
-                <property key="labeling/fontSize" value="10"/>
-                <property key="labeling/fontSizeInMapUnits" value="false"/>
-                <property key="labeling/fontStrikeout" value="false"/>
-                <property key="labeling/fontUnderline" value="false"/>
-                <property key="labeling/fontWeight" value="50"/>
-                <property key="labeling/fontWordSpacing" value="0"/>
-                <property key="labeling/formatNumbers" value="false"/>
-                <property key="labeling/isExpression" value="false"/>
-                <property key="labeling/labelOffsetInMapUnits" value="true"/>
-                <property key="labeling/labelPerPart" value="false"/>
-                <property key="labeling/leftDirectionSymbol" value="<"/>
-                <property key="labeling/limitNumLabels" value="false"/>
-                <property key="labeling/maxCurvedCharAngleIn" value="20"/>
-                <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
-                <property key="labeling/maxNumLabels" value="2000"/>
-                <property key="labeling/mergeLines" value="false"/>
-                <property key="labeling/minFeatureSize" value="0"/>
-                <property key="labeling/multilineAlign" value="0"/>
-                <property key="labeling/multilineHeight" value="1"/>
-                <property key="labeling/namedStyle" value=""/>
-                <property key="labeling/obstacle" value="true"/>
-                <property key="labeling/placeDirectionSymbol" value="0"/>
-                <property key="labeling/placement" value="2"/>
-                <property key="labeling/placementFlags" value="10"/>
-                <property key="labeling/plussign" value="false"/>
-                <property key="labeling/preserveRotation" value="true"/>
-                <property key="labeling/previewBkgrdColor" value="#ffffff"/>
-                <property key="labeling/priority" value="5"/>
-                <property key="labeling/quadOffset" value="4"/>
-                <property key="labeling/reverseDirectionSymbol" value="false"/>
-                <property key="labeling/rightDirectionSymbol" value=">"/>
-                <property key="labeling/scaleMax" value="10000000"/>
-                <property key="labeling/scaleMin" value="1"/>
-                <property key="labeling/scaleVisibility" value="false"/>
-                <property key="labeling/shadowBlendMode" value="6"/>
-                <property key="labeling/shadowColorB" value="0"/>
-                <property key="labeling/shadowColorG" value="0"/>
-                <property key="labeling/shadowColorR" value="0"/>
-                <property key="labeling/shadowDraw" value="false"/>
-                <property key="labeling/shadowOffsetAngle" value="135"/>
-                <property key="labeling/shadowOffsetDist" value="1"/>
-                <property key="labeling/shadowOffsetGlobal" value="true"/>
-                <property key="labeling/shadowOffsetUnits" value="1"/>
-                <property key="labeling/shadowRadius" value="1.5"/>
-                <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
-                <property key="labeling/shadowRadiusUnits" value="1"/>
-                <property key="labeling/shadowScale" value="100"/>
-                <property key="labeling/shadowTransparency" value="30"/>
-                <property key="labeling/shadowUnder" value="0"/>
-                <property key="labeling/shapeBlendMode" value="0"/>
-                <property key="labeling/shapeBorderColorA" value="255"/>
-                <property key="labeling/shapeBorderColorB" value="128"/>
-                <property key="labeling/shapeBorderColorG" value="128"/>
-                <property key="labeling/shapeBorderColorR" value="128"/>
-                <property key="labeling/shapeBorderWidth" value="0"/>
-                <property key="labeling/shapeBorderWidthUnits" value="1"/>
-                <property key="labeling/shapeDraw" value="false"/>
-                <property key="labeling/shapeFillColorA" value="255"/>
-                <property key="labeling/shapeFillColorB" value="255"/>
-                <property key="labeling/shapeFillColorG" value="255"/>
-                <property key="labeling/shapeFillColorR" value="255"/>
-                <property key="labeling/shapeJoinStyle" value="64"/>
-                <property key="labeling/shapeOffsetUnits" value="1"/>
-                <property key="labeling/shapeOffsetX" value="0"/>
-                <property key="labeling/shapeOffsetY" value="0"/>
-                <property key="labeling/shapeRadiiUnits" value="1"/>
-                <property key="labeling/shapeRadiiX" value="0"/>
-                <property key="labeling/shapeRadiiY" value="0"/>
-                <property key="labeling/shapeRotation" value="0"/>
-                <property key="labeling/shapeRotationType" value="0"/>
-                <property key="labeling/shapeSVGFile" value=""/>
-                <property key="labeling/shapeSizeType" value="0"/>
-                <property key="labeling/shapeSizeUnits" value="1"/>
-                <property key="labeling/shapeSizeX" value="0"/>
-                <property key="labeling/shapeSizeY" value="0"/>
-                <property key="labeling/shapeTransparency" value="0"/>
-                <property key="labeling/shapeType" value="0"/>
-                <property key="labeling/textColorA" value="255"/>
-                <property key="labeling/textColorB" value="0"/>
-                <property key="labeling/textColorG" value="0"/>
-                <property key="labeling/textColorR" value="0"/>
-                <property key="labeling/textTransp" value="0"/>
-                <property key="labeling/upsidedownLabels" value="0"/>
-                <property key="labeling/wrapChar" value=""/>
-                <property key="labeling/xOffset" value="0"/>
-                <property key="labeling/yOffset" value="0"/>
-            </customproperties>
-            <blendMode>0</blendMode>
-            <featureBlendMode>0</featureBlendMode>
-            <layerTransparency>0</layerTransparency>
-            <displayfield>OGC_FID</displayfield>
-            <label>0</label>
-            <labelattributes>
-                <label fieldname="" text="Label"/>
-                <family fieldname="" name="Sans"/>
-                <size fieldname="" units="pt" value="12"/>
-                <bold fieldname="" on="0"/>
-                <italic fieldname="" on="0"/>
-                <underline fieldname="" on="0"/>
-                <strikeout fieldname="" on="0"/>
-                <color fieldname="" red="0" blue="0" green="0"/>
-                <x fieldname=""/>
-                <y fieldname=""/>
-                <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
-                <angle fieldname="" value="0" auto="0"/>
-                <alignment fieldname="" value="center"/>
-                <buffercolor fieldname="" red="255" blue="255" green="255"/>
-                <buffersize fieldname="" units="pt" value="1"/>
-                <bufferenabled fieldname="" on=""/>
-                <multilineenabled fieldname="" on=""/>
-                <selectedonly on=""/>
-            </labelattributes>
-            <edittypes>
-                <edittype labelontop="0" editable="1" type="0" name="OGC_FID"/>
-                <edittype labelontop="0" editable="1" type="0" name="id"/>
-                <edittype labelontop="0" editable="1" type="0" name="object_id"/>
-                <edittype labelontop="0" editable="1" type="0" name="problem_type"/>
-                <edittype labelontop="0" editable="1" type="0" name="type"/>
-                <edittype labelontop="0" editable="1" type="0" name="way_id"/>
-            </edittypes>
-            <editform>.</editform>
-            <editforminit></editforminit>
-            <featformsuppress>0</featformsuppress>
-            <annotationform>.</annotationform>
-            <editorlayout>generatedlayout</editorlayout>
-            <excludeAttributesWMS/>
-            <excludeAttributesWFS/>
-            <attributeactions/>
-        </maplayer>
-        <maplayer minimumScale="-4.65661e-10" maximumScale="1e+08" simplifyDrawingHints="1" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Polygon" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
-            <id>multipolygons20140221151811742</id>
-            <datasource>dbname='./multipolygon.db' table="multipolygons" (GEOMETRY) sql=</datasource>
-            <title></title>
-            <abstract></abstract>
-            <keywordList>
-                <value></value>
-            </keywordList>
-            <layername>multipolygons</layername>
-            <srs>
-                <spatialrefsys>
-                    <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
-                    <srsid>3452</srsid>
-                    <srid>4326</srid>
-                    <authid>EPSG:4326</authid>
-                    <description>WGS 84</description>
-                    <projectionacronym>longlat</projectionacronym>
-                    <ellipsoidacronym>WGS84</ellipsoidacronym>
-                    <geographicflag>true</geographicflag>
-                </spatialrefsys>
-            </srs>
-            <provider encoding="System">spatialite</provider>
-            <previewExpression></previewExpression>
-            <vectorjoins/>
-            <renderer-v2 symbollevels="0" type="singleSymbol">
-                <symbols>
-                    <symbol alpha="0.494118" type="fill" name="0">
-                        <layer pass="0" class="SimpleFill" locked="0">
-                            <prop k="border_width_unit" v="MM"/>
-                            <prop k="color" v="0,170,255,255"/>
-                            <prop k="color_border" v="0,0,0,255"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="style" v="solid"/>
-                            <prop k="style_border" v="solid"/>
-                            <prop k="width_border" v="0.26"/>
-                        </layer>
-                    </symbol>
-                </symbols>
-                <rotation/>
-                <sizescale scalemethod="area"/>
-            </renderer-v2>
-            <customproperties>
-                <property key="labeling" value="pal"/>
-                <property key="labeling/addDirectionSymbol" value="false"/>
-                <property key="labeling/angleOffset" value="0"/>
-                <property key="labeling/blendMode" value="0"/>
-                <property key="labeling/bufferBlendMode" value="0"/>
-                <property key="labeling/bufferColorA" value="255"/>
-                <property key="labeling/bufferColorB" value="255"/>
-                <property key="labeling/bufferColorG" value="255"/>
-                <property key="labeling/bufferColorR" value="255"/>
-                <property key="labeling/bufferDraw" value="false"/>
-                <property key="labeling/bufferJoinStyle" value="64"/>
-                <property key="labeling/bufferNoFill" value="false"/>
-                <property key="labeling/bufferSize" value="1"/>
-                <property key="labeling/bufferSizeInMapUnits" value="false"/>
-                <property key="labeling/bufferTransp" value="0"/>
-                <property key="labeling/centroidWhole" value="false"/>
-                <property key="labeling/decimals" value="3"/>
-                <property key="labeling/displayAll" value="false"/>
-                <property key="labeling/dist" value="0"/>
-                <property key="labeling/distInMapUnits" value="false"/>
-                <property key="labeling/enabled" value="false"/>
-                <property key="labeling/fieldName" value=""/>
-                <property key="labeling/fontBold" value="false"/>
-                <property key="labeling/fontCapitals" value="0"/>
-                <property key="labeling/fontFamily" value="Sans"/>
-                <property key="labeling/fontItalic" value="false"/>
-                <property key="labeling/fontLetterSpacing" value="0"/>
-                <property key="labeling/fontLimitPixelSize" value="false"/>
-                <property key="labeling/fontMaxPixelSize" value="10000"/>
-                <property key="labeling/fontMinPixelSize" value="3"/>
-                <property key="labeling/fontSize" value="10"/>
-                <property key="labeling/fontSizeInMapUnits" value="false"/>
-                <property key="labeling/fontStrikeout" value="false"/>
-                <property key="labeling/fontUnderline" value="false"/>
-                <property key="labeling/fontWeight" value="50"/>
-                <property key="labeling/fontWordSpacing" value="0"/>
-                <property key="labeling/formatNumbers" value="false"/>
-                <property key="labeling/isExpression" value="false"/>
-                <property key="labeling/labelOffsetInMapUnits" value="true"/>
-                <property key="labeling/labelPerPart" value="false"/>
-                <property key="labeling/leftDirectionSymbol" value="<"/>
-                <property key="labeling/limitNumLabels" value="false"/>
-                <property key="labeling/maxCurvedCharAngleIn" value="20"/>
-                <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
-                <property key="labeling/maxNumLabels" value="2000"/>
-                <property key="labeling/mergeLines" value="false"/>
-                <property key="labeling/minFeatureSize" value="0"/>
-                <property key="labeling/multilineAlign" value="0"/>
-                <property key="labeling/multilineHeight" value="1"/>
-                <property key="labeling/namedStyle" value=""/>
-                <property key="labeling/obstacle" value="true"/>
-                <property key="labeling/placeDirectionSymbol" value="0"/>
-                <property key="labeling/placement" value="0"/>
-                <property key="labeling/placementFlags" value="0"/>
-                <property key="labeling/plussign" value="false"/>
-                <property key="labeling/preserveRotation" value="true"/>
-                <property key="labeling/previewBkgrdColor" value="#ffffff"/>
-                <property key="labeling/priority" value="5"/>
-                <property key="labeling/quadOffset" value="4"/>
-                <property key="labeling/reverseDirectionSymbol" value="false"/>
-                <property key="labeling/rightDirectionSymbol" value=">"/>
-                <property key="labeling/scaleMax" value="10000000"/>
-                <property key="labeling/scaleMin" value="1"/>
-                <property key="labeling/scaleVisibility" value="false"/>
-                <property key="labeling/shadowBlendMode" value="6"/>
-                <property key="labeling/shadowColorB" value="0"/>
-                <property key="labeling/shadowColorG" value="0"/>
-                <property key="labeling/shadowColorR" value="0"/>
-                <property key="labeling/shadowDraw" value="false"/>
-                <property key="labeling/shadowOffsetAngle" value="135"/>
-                <property key="labeling/shadowOffsetDist" value="1"/>
-                <property key="labeling/shadowOffsetGlobal" value="true"/>
-                <property key="labeling/shadowOffsetUnits" value="1"/>
-                <property key="labeling/shadowRadius" value="1.5"/>
-                <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
-                <property key="labeling/shadowRadiusUnits" value="1"/>
-                <property key="labeling/shadowScale" value="100"/>
-                <property key="labeling/shadowTransparency" value="30"/>
-                <property key="labeling/shadowUnder" value="0"/>
-                <property key="labeling/shapeBlendMode" value="0"/>
-                <property key="labeling/shapeBorderColorA" value="255"/>
-                <property key="labeling/shapeBorderColorB" value="128"/>
-                <property key="labeling/shapeBorderColorG" value="128"/>
-                <property key="labeling/shapeBorderColorR" value="128"/>
-                <property key="labeling/shapeBorderWidth" value="0"/>
-                <property key="labeling/shapeBorderWidthUnits" value="1"/>
-                <property key="labeling/shapeDraw" value="false"/>
-                <property key="labeling/shapeFillColorA" value="255"/>
-                <property key="labeling/shapeFillColorB" value="255"/>
-                <property key="labeling/shapeFillColorG" value="255"/>
-                <property key="labeling/shapeFillColorR" value="255"/>
-                <property key="labeling/shapeJoinStyle" value="64"/>
-                <property key="labeling/shapeOffsetUnits" value="1"/>
-                <property key="labeling/shapeOffsetX" value="0"/>
-                <property key="labeling/shapeOffsetY" value="0"/>
-                <property key="labeling/shapeRadiiUnits" value="1"/>
-                <property key="labeling/shapeRadiiX" value="0"/>
-                <property key="labeling/shapeRadiiY" value="0"/>
-                <property key="labeling/shapeRotation" value="0"/>
-                <property key="labeling/shapeRotationType" value="0"/>
-                <property key="labeling/shapeSVGFile" value=""/>
-                <property key="labeling/shapeSizeType" value="0"/>
-                <property key="labeling/shapeSizeUnits" value="1"/>
-                <property key="labeling/shapeSizeX" value="0"/>
-                <property key="labeling/shapeSizeY" value="0"/>
-                <property key="labeling/shapeTransparency" value="0"/>
-                <property key="labeling/shapeType" value="0"/>
-                <property key="labeling/textColorA" value="255"/>
-                <property key="labeling/textColorB" value="0"/>
-                <property key="labeling/textColorG" value="0"/>
-                <property key="labeling/textColorR" value="0"/>
-                <property key="labeling/textTransp" value="0"/>
-                <property key="labeling/upsidedownLabels" value="0"/>
-                <property key="labeling/wrapChar" value=""/>
-                <property key="labeling/xOffset" value="0"/>
-                <property key="labeling/yOffset" value="0"/>
-            </customproperties>
-            <blendMode>0</blendMode>
-            <featureBlendMode>0</featureBlendMode>
-            <layerTransparency>0</layerTransparency>
-            <displayfield>OGC_FID</displayfield>
-            <label>0</label>
-            <labelattributes>
-                <label fieldname="" text="Label"/>
-                <family fieldname="" name="Sans"/>
-                <size fieldname="" units="pt" value="12"/>
-                <bold fieldname="" on="0"/>
-                <italic fieldname="" on="0"/>
-                <underline fieldname="" on="0"/>
-                <strikeout fieldname="" on="0"/>
-                <color fieldname="" red="0" blue="0" green="0"/>
-                <x fieldname=""/>
-                <y fieldname=""/>
-                <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
-                <angle fieldname="" value="0" auto="0"/>
-                <alignment fieldname="" value="center"/>
-                <buffercolor fieldname="" red="255" blue="255" green="255"/>
-                <buffersize fieldname="" units="pt" value="1"/>
-                <bufferenabled fieldname="" on=""/>
-                <multilineenabled fieldname="" on=""/>
-                <selectedonly on=""/>
-            </labelattributes>
-            <edittypes>
-                <edittype labelontop="0" editable="1" type="0" name="OGC_FID"/>
-                <edittype labelontop="0" editable="1" type="0" name="id"/>
-                <edittype labelontop="0" editable="1" type="0" name="type"/>
-            </edittypes>
-            <editform>.</editform>
-            <editforminit></editforminit>
-            <featformsuppress>0</featformsuppress>
-            <annotationform>.</annotationform>
-            <editorlayout>generatedlayout</editorlayout>
-            <excludeAttributesWMS/>
-            <excludeAttributesWFS/>
-            <attributeactions/>
-        </maplayer>
-        <maplayer minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Point" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
-            <id>perrors20140228163658956</id>
-            <datasource>dbname='./multipolygon.db' table="perrors" (GEOMETRY) sql=</datasource>
-            <title></title>
-            <abstract></abstract>
-            <keywordList>
-                <value></value>
-            </keywordList>
-            <layername>Error Points</layername>
-            <srs>
-                <spatialrefsys>
-                    <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
-                    <srsid>3452</srsid>
-                    <srid>4326</srid>
-                    <authid>EPSG:4326</authid>
-                    <description>WGS 84</description>
-                    <projectionacronym>longlat</projectionacronym>
-                    <ellipsoidacronym>WGS84</ellipsoidacronym>
-                    <geographicflag>true</geographicflag>
-                </spatialrefsys>
-            </srs>
-            <provider encoding="System">spatialite</provider>
-            <previewExpression>COALESCE( "OGC_FID", '<NULL>' )</previewExpression>
-            <vectorjoins/>
-            <renderer-v2 attr="problem_type" symbollevels="0" type="categorizedSymbol">
-                <categories>
-                    <category symbol="0" value="intersection" label="intersection"/>
-                    <category symbol="1" value="ring_not_closed" label="ring_not_closed"/>
-                    <category symbol="2" value="duplicate_node" label="duplicate_node"/>
-                </categories>
-                <symbols>
-                    <symbol alpha="1" type="marker" name="0">
-                        <layer pass="0" class="SimpleMarker" locked="0">
-                            <prop k="angle" v="0"/>
-                            <prop k="color" v="255,0,0,255"/>
-                            <prop k="color_border" v="255,255,255,255"/>
-                            <prop k="horizontal_anchor_point" v="1"/>
-                            <prop k="name" v="diamond"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="outline_style" v="solid"/>
-                            <prop k="outline_width" v="0.4"/>
-                            <prop k="outline_width_unit" v="MM"/>
-                            <prop k="scale_method" v="area"/>
-                            <prop k="size" v="2.8"/>
-                            <prop k="size_unit" v="MM"/>
-                            <prop k="vertical_anchor_point" v="1"/>
-                        </layer>
-                    </symbol>
-                    <symbol alpha="1" type="marker" name="1">
-                        <layer pass="0" class="SimpleMarker" locked="0">
-                            <prop k="angle" v="0"/>
-                            <prop k="color" v="255,0,0,255"/>
-                            <prop k="color_border" v="255,255,255,255"/>
-                            <prop k="horizontal_anchor_point" v="1"/>
-                            <prop k="name" v="triangle"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="outline_style" v="solid"/>
-                            <prop k="outline_width" v="0.4"/>
-                            <prop k="outline_width_unit" v="MM"/>
-                            <prop k="scale_method" v="area"/>
-                            <prop k="size" v="2.8"/>
-                            <prop k="size_unit" v="MM"/>
-                            <prop k="vertical_anchor_point" v="1"/>
-                        </layer>
-                    </symbol>
-                    <symbol alpha="1" type="marker" name="2">
-                        <layer pass="0" class="SimpleMarker" locked="0">
-                            <prop k="angle" v="0"/>
-                            <prop k="color" v="255,255,255,255"/>
-                            <prop k="color_border" v="255,0,0,255"/>
-                            <prop k="horizontal_anchor_point" v="1"/>
-                            <prop k="name" v="circle"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="outline_style" v="solid"/>
-                            <prop k="outline_width" v="0.4"/>
-                            <prop k="outline_width_unit" v="MM"/>
-                            <prop k="scale_method" v="area"/>
-                            <prop k="size" v="2.4"/>
-                            <prop k="size_unit" v="MM"/>
-                            <prop k="vertical_anchor_point" v="1"/>
-                        </layer>
-                        <layer pass="0" class="SimpleMarker" locked="0">
-                            <prop k="angle" v="0"/>
-                            <prop k="color" v="255,0,0,255"/>
-                            <prop k="color_border" v="255,0,0,255"/>
-                            <prop k="horizontal_anchor_point" v="1"/>
-                            <prop k="name" v="circle"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="outline_style" v="solid"/>
-                            <prop k="outline_width" v="0.8"/>
-                            <prop k="outline_width_unit" v="MM"/>
-                            <prop k="scale_method" v="area"/>
-                            <prop k="size" v="0.5"/>
-                            <prop k="size_unit" v="MM"/>
-                            <prop k="vertical_anchor_point" v="1"/>
-                        </layer>
-                    </symbol>
-                </symbols>
-                <source-symbol>
-                    <symbol alpha="1" type="marker" name="0">
-                        <layer pass="0" class="SimpleMarker" locked="0">
-                            <prop k="angle" v="0"/>
-                            <prop k="color" v="139,168,110,255"/>
-                            <prop k="color_border" v="0,0,0,255"/>
-                            <prop k="horizontal_anchor_point" v="1"/>
-                            <prop k="name" v="circle"/>
-                            <prop k="offset" v="0,0"/>
-                            <prop k="offset_unit" v="MM"/>
-                            <prop k="outline_style" v="solid"/>
-                            <prop k="outline_width" v="0"/>
-                            <prop k="outline_width_unit" v="MM"/>
-                            <prop k="scale_method" v="area"/>
-                            <prop k="size" v="2"/>
-                            <prop k="size_unit" v="MM"/>
-                            <prop k="vertical_anchor_point" v="1"/>
-                        </layer>
-                    </symbol>
-                </source-symbol>
-                <rotation/>
-                <sizescale scalemethod="area"/>
-            </renderer-v2>
-            <customproperties>
-                <property key="labeling" value="pal"/>
-                <property key="labeling/addDirectionSymbol" value="false"/>
-                <property key="labeling/angleOffset" value="0"/>
-                <property key="labeling/blendMode" value="0"/>
-                <property key="labeling/bufferBlendMode" value="0"/>
-                <property key="labeling/bufferColorA" value="255"/>
-                <property key="labeling/bufferColorB" value="255"/>
-                <property key="labeling/bufferColorG" value="255"/>
-                <property key="labeling/bufferColorR" value="255"/>
-                <property key="labeling/bufferDraw" value="false"/>
-                <property key="labeling/bufferJoinStyle" value="64"/>
-                <property key="labeling/bufferNoFill" value="false"/>
-                <property key="labeling/bufferSize" value="1"/>
-                <property key="labeling/bufferSizeInMapUnits" value="false"/>
-                <property key="labeling/bufferTransp" value="0"/>
-                <property key="labeling/centroidWhole" value="false"/>
-                <property key="labeling/decimals" value="3"/>
-                <property key="labeling/displayAll" value="false"/>
-                <property key="labeling/dist" value="0"/>
-                <property key="labeling/distInMapUnits" value="false"/>
-                <property key="labeling/enabled" value="false"/>
-                <property key="labeling/fieldName" value=""/>
-                <property key="labeling/fontBold" value="false"/>
-                <property key="labeling/fontCapitals" value="0"/>
-                <property key="labeling/fontFamily" value="Sans"/>
-                <property key="labeling/fontItalic" value="false"/>
-                <property key="labeling/fontLetterSpacing" value="0"/>
-                <property key="labeling/fontLimitPixelSize" value="false"/>
-                <property key="labeling/fontMaxPixelSize" value="10000"/>
-                <property key="labeling/fontMinPixelSize" value="3"/>
-                <property key="labeling/fontSize" value="10"/>
-                <property key="labeling/fontSizeInMapUnits" value="false"/>
-                <property key="labeling/fontStrikeout" value="false"/>
-                <property key="labeling/fontUnderline" value="false"/>
-                <property key="labeling/fontWeight" value="50"/>
-                <property key="labeling/fontWordSpacing" value="0"/>
-                <property key="labeling/formatNumbers" value="false"/>
-                <property key="labeling/isExpression" value="false"/>
-                <property key="labeling/labelOffsetInMapUnits" value="true"/>
-                <property key="labeling/labelPerPart" value="false"/>
-                <property key="labeling/leftDirectionSymbol" value="<"/>
-                <property key="labeling/limitNumLabels" value="false"/>
-                <property key="labeling/maxCurvedCharAngleIn" value="20"/>
-                <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
-                <property key="labeling/maxNumLabels" value="2000"/>
-                <property key="labeling/mergeLines" value="false"/>
-                <property key="labeling/minFeatureSize" value="0"/>
-                <property key="labeling/multilineAlign" value="0"/>
-                <property key="labeling/multilineHeight" value="1"/>
-                <property key="labeling/namedStyle" value=""/>
-                <property key="labeling/obstacle" value="true"/>
-                <property key="labeling/placeDirectionSymbol" value="0"/>
-                <property key="labeling/placement" value="0"/>
-                <property key="labeling/placementFlags" value="0"/>
-                <property key="labeling/plussign" value="false"/>
-                <property key="labeling/preserveRotation" value="true"/>
-                <property key="labeling/previewBkgrdColor" value="#ffffff"/>
-                <property key="labeling/priority" value="5"/>
-                <property key="labeling/quadOffset" value="4"/>
-                <property key="labeling/reverseDirectionSymbol" value="false"/>
-                <property key="labeling/rightDirectionSymbol" value=">"/>
-                <property key="labeling/scaleMax" value="10000000"/>
-                <property key="labeling/scaleMin" value="1"/>
-                <property key="labeling/scaleVisibility" value="false"/>
-                <property key="labeling/shadowBlendMode" value="6"/>
-                <property key="labeling/shadowColorB" value="0"/>
-                <property key="labeling/shadowColorG" value="0"/>
-                <property key="labeling/shadowColorR" value="0"/>
-                <property key="labeling/shadowDraw" value="false"/>
-                <property key="labeling/shadowOffsetAngle" value="135"/>
-                <property key="labeling/shadowOffsetDist" value="1"/>
-                <property key="labeling/shadowOffsetGlobal" value="true"/>
-                <property key="labeling/shadowOffsetUnits" value="1"/>
-                <property key="labeling/shadowRadius" value="1.5"/>
-                <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
-                <property key="labeling/shadowRadiusUnits" value="1"/>
-                <property key="labeling/shadowScale" value="100"/>
-                <property key="labeling/shadowTransparency" value="30"/>
-                <property key="labeling/shadowUnder" value="0"/>
-                <property key="labeling/shapeBlendMode" value="0"/>
-                <property key="labeling/shapeBorderColorA" value="255"/>
-                <property key="labeling/shapeBorderColorB" value="128"/>
-                <property key="labeling/shapeBorderColorG" value="128"/>
-                <property key="labeling/shapeBorderColorR" value="128"/>
-                <property key="labeling/shapeBorderWidth" value="0"/>
-                <property key="labeling/shapeBorderWidthUnits" value="1"/>
-                <property key="labeling/shapeDraw" value="false"/>
-                <property key="labeling/shapeFillColorA" value="255"/>
-                <property key="labeling/shapeFillColorB" value="255"/>
-                <property key="labeling/shapeFillColorG" value="255"/>
-                <property key="labeling/shapeFillColorR" value="255"/>
-                <property key="labeling/shapeJoinStyle" value="64"/>
-                <property key="labeling/shapeOffsetUnits" value="1"/>
-                <property key="labeling/shapeOffsetX" value="0"/>
-                <property key="labeling/shapeOffsetY" value="0"/>
-                <property key="labeling/shapeRadiiUnits" value="1"/>
-                <property key="labeling/shapeRadiiX" value="0"/>
-                <property key="labeling/shapeRadiiY" value="0"/>
-                <property key="labeling/shapeRotation" value="0"/>
-                <property key="labeling/shapeRotationType" value="0"/>
-                <property key="labeling/shapeSVGFile" value=""/>
-                <property key="labeling/shapeSizeType" value="0"/>
-                <property key="labeling/shapeSizeUnits" value="1"/>
-                <property key="labeling/shapeSizeX" value="0"/>
-                <property key="labeling/shapeSizeY" value="0"/>
-                <property key="labeling/shapeTransparency" value="0"/>
-                <property key="labeling/shapeType" value="0"/>
-                <property key="labeling/textColorA" value="255"/>
-                <property key="labeling/textColorB" value="0"/>
-                <property key="labeling/textColorG" value="0"/>
-                <property key="labeling/textColorR" value="0"/>
-                <property key="labeling/textTransp" value="0"/>
-                <property key="labeling/upsidedownLabels" value="0"/>
-                <property key="labeling/wrapChar" value=""/>
-                <property key="labeling/xOffset" value="0"/>
-                <property key="labeling/yOffset" value="0"/>
-            </customproperties>
-            <blendMode>0</blendMode>
-            <featureBlendMode>0</featureBlendMode>
-            <layerTransparency>0</layerTransparency>
-            <displayfield>OGC_FID</displayfield>
-            <label>0</label>
-            <labelattributes>
-                <label fieldname="" text="Label"/>
-                <family fieldname="" name="Sans"/>
-                <size fieldname="" units="pt" value="12"/>
-                <bold fieldname="" on="0"/>
-                <italic fieldname="" on="0"/>
-                <underline fieldname="" on="0"/>
-                <strikeout fieldname="" on="0"/>
-                <color fieldname="" red="0" blue="0" green="0"/>
-                <x fieldname=""/>
-                <y fieldname=""/>
-                <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
-                <angle fieldname="" value="0" auto="0"/>
-                <alignment fieldname="" value="center"/>
-                <buffercolor fieldname="" red="255" blue="255" green="255"/>
-                <buffersize fieldname="" units="pt" value="1"/>
-                <bufferenabled fieldname="" on=""/>
-                <multilineenabled fieldname="" on=""/>
-                <selectedonly on=""/>
-            </labelattributes>
-            <edittypes>
-                <edittype labelontop="0" editable="1" type="0" name="OGC_FID"/>
-                <edittype labelontop="0" editable="1" type="0" name="id"/>
-                <edittype labelontop="0" editable="1" type="0" name="node_id"/>
-                <edittype labelontop="0" editable="1" type="0" name="object_id"/>
-                <edittype labelontop="0" editable="1" type="0" name="problem_type"/>
-                <edittype labelontop="0" editable="1" type="0" name="type"/>
-            </edittypes>
-            <editform>.</editform>
-            <editforminit></editforminit>
-            <featformsuppress>0</featformsuppress>
-            <annotationform>.</annotationform>
-            <editorlayout>generatedlayout</editorlayout>
-            <excludeAttributesWMS/>
-            <excludeAttributesWFS/>
-            <attributeactions/>
-        </maplayer>
-    </projectlayers>
-    <properties>
-        <WMSContactPerson type="QString"></WMSContactPerson>
-        <WMSOnlineResource type="QString"></WMSOnlineResource>
-        <WMSContactOrganization type="QString"></WMSContactOrganization>
-        <WMSExtent type="QStringList">
-            <value>0.82500024999999999</value>
-            <value>-0.35415386986094277</value>
-            <value>8.17498974999999994</value>
-            <value>3.45415386986094308</value>
-        </WMSExtent>
-        <WMSKeywordList type="QStringList">
-            <value></value>
-        </WMSKeywordList>
-        <WFSUrl type="QString"></WFSUrl>
-        <Paths>
-            <Absolute type="bool">false</Absolute>
-        </Paths>
-        <WMSServiceTitle type="QString">mp test</WMSServiceTitle>
-        <WFSLayers type="QStringList"/>
-        <WMSContactMail type="QString"></WMSContactMail>
-        <PositionPrecision>
-            <DecimalPlaces type="int">2</DecimalPlaces>
-            <Automatic type="bool">true</Automatic>
-            <DegreeFormat type="QString">D</DegreeFormat>
-        </PositionPrecision>
-        <WCSUrl type="QString"></WCSUrl>
-        <WMSContactPhone type="QString"></WMSContactPhone>
-        <WMSServiceCapabilities type="bool">true</WMSServiceCapabilities>
-        <WMSServiceAbstract type="QString"></WMSServiceAbstract>
-        <WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
-        <Measure>
-            <Ellipsoid type="QString">NONE</Ellipsoid>
-        </Measure>
-        <WFSTLayers>
-            <Insert type="QStringList"/>
-            <Update type="QStringList"/>
-            <Delete type="QStringList"/>
-        </WFSTLayers>
-        <Gui>
-            <SelectionColorBluePart type="int">0</SelectionColorBluePart>
-            <CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
-            <CanvasColorRedPart type="int">255</CanvasColorRedPart>
-            <SelectionColorRedPart type="int">255</SelectionColorRedPart>
-            <SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
-            <SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
-            <CanvasColorBluePart type="int">255</CanvasColorBluePart>
-        </Gui>
-        <Identify>
-            <disabledLayers type="QStringList"/>
-        </Identify>
-        <Macros>
-            <pythonCode type="QString"></pythonCode>
-        </Macros>
-        <WMSAccessConstraints type="QString"></WMSAccessConstraints>
-        <WCSLayers type="QStringList"/>
-        <SpatialRefSys>
-            <ProjectCrs type="QString">EPSG:4326</ProjectCrs>
-        </SpatialRefSys>
-        <DefaultStyles>
-            <Fill type="QString"></Fill>
-            <Line type="QString"></Line>
-            <Marker type="QString"></Marker>
-            <RandomColors type="bool">true</RandomColors>
-            <AlphaInt type="int">255</AlphaInt>
-            <ColorRamp type="QString"></ColorRamp>
-        </DefaultStyles>
-        <WMSFees type="QString"></WMSFees>
-        <WMSUrl type="QString"></WMSUrl>
-    </properties>
+<qgis projectname="" version="2.18.0">
+  <title></title>
+  <autotransaction active="0"/>
+  <evaluateDefaultValues active="0"/>
+  <layer-tree-group expanded="1" checked="Qt::Checked" name="">
+    <customproperties/>
+    <layer-tree-layer expanded="1" checked="Qt::Checked" id="perrors20140228163658956" name="Error Points">
+      <customproperties/>
+    </layer-tree-layer>
+    <layer-tree-layer expanded="1" checked="Qt::Checked" id="lerrors20140228172357933" name="Error Lines">
+      <customproperties/>
+    </layer-tree-layer>
+    <layer-tree-layer expanded="1" checked="Qt::Checked" id="multipolygons20140221151811742" name="multipolygons">
+      <customproperties/>
+    </layer-tree-layer>
+    <layer-tree-group expanded="1" checked="Qt::Checked" name="Overview">
+      <customproperties>
+        <property key="embedded" value="1"/>
+        <property key="embedded-invisible-layers"/>
+        <property key="embedded_project" value="@OSM_TESTDATA@/grid/tests.qgs"/>
+      </customproperties>
+    </layer-tree-group>
+    <layer-tree-group expanded="1" checked="Qt::Checked" name="Test Framework">
+      <customproperties>
+        <property key="embedded" value="1"/>
+        <property key="embedded-invisible-layers"/>
+        <property key="embedded_project" value="@OSM_TESTDATA@/grid/tests.qgs"/>
+      </customproperties>
+    </layer-tree-group>
+  </layer-tree-group>
+  <relations/>
+  <mapcanvas>
+    <units>degrees</units>
+    <extent>
+      <xmin>0.77500024999999972</xmin>
+      <ymin>0.97250000000000003</ymin>
+      <xmax>10.22498975000000065</xmax>
+      <ymax>2.12750000000000039</ymax>
+    </extent>
+    <rotation>0</rotation>
+    <projections>0</projections>
+    <destinationsrs>
+      <spatialrefsys>
+        <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
+        <srsid>3452</srsid>
+        <srid>4326</srid>
+        <authid>EPSG:4326</authid>
+        <description>WGS 84</description>
+        <projectionacronym>longlat</projectionacronym>
+        <ellipsoidacronym>WGS84</ellipsoidacronym>
+        <geographicflag>true</geographicflag>
+      </spatialrefsys>
+    </destinationsrs>
+    <rendermaptile>0</rendermaptile>
+    <layer_coordinate_transform_info/>
+  </mapcanvas>
+  <layer-tree-canvas>
+    <custom-order enabled="0">
+      <item>perrors20140228163658956</item>
+      <item>lerrors20140228172357933</item>
+      <item>multipolygons20140221151811742</item>
+      <item>labels20140221110837046</item>
+      <item>nodes20140221105814325</item>
+      <item>ways20140221105814338</item>
+      <item>multipolygons20140224153504671</item>
+      <item>titles20140220153751089</item>
+      <item>grid20140213154358889</item>
+    </custom-order>
+  </layer-tree-canvas>
+  <legend updateDrawingOrder="true">
+    <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Error Points" showFeatureCount="0">
+      <filegroup open="true" hidden="false">
+        <legendlayerfile isInOverview="0" layerid="perrors20140228163658956" visible="1"/>
+      </filegroup>
+    </legendlayer>
+    <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Error Lines" showFeatureCount="0">
+      <filegroup open="true" hidden="false">
+        <legendlayerfile isInOverview="0" layerid="lerrors20140228172357933" visible="1"/>
+      </filegroup>
+    </legendlayer>
+    <legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="multipolygons" showFeatureCount="0">
+      <filegroup open="true" hidden="false">
+        <legendlayerfile isInOverview="0" layerid="multipolygons20140221151811742" visible="1"/>
+      </filegroup>
+    </legendlayer>
+    <legendgroup embedded="1" open="true" checked="Qt::Checked" name="Overview" project="@OSM_TESTDATA@/grid/tests.qgs"/>
+    <legendgroup embedded="1" open="true" checked="Qt::Checked" name="Test Framework" project="@OSM_TESTDATA@/grid/tests.qgs"/>
+  </legend>
+  <projectlayers>
+    <maplayer simplifyAlgorithm="0" minimumScale="-4.65661e-10" maximumScale="1e+08" simplifyDrawingHints="1" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Line" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
+      <id>lerrors20140228172357933</id>
+      <datasource>dbname='./multipolygon.db' table="lerrors" (GEOMETRY) sql=</datasource>
+      <keywordList>
+        <value></value>
+      </keywordList>
+      <layername>Error Lines</layername>
+      <srs>
+        <spatialrefsys>
+          <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
+          <srsid>3452</srsid>
+          <srid>4326</srid>
+          <authid>EPSG:4326</authid>
+          <description>WGS 84</description>
+          <projectionacronym>longlat</projectionacronym>
+          <ellipsoidacronym>WGS84</ellipsoidacronym>
+          <geographicflag>true</geographicflag>
+        </spatialrefsys>
+      </srs>
+      <provider encoding="System">spatialite</provider>
+      <previewExpression>COALESCE( "OGC_FID", '<NULL>' )</previewExpression>
+      <vectorjoins/>
+      <layerDependencies/>
+      <expressionfields/>
+      <defaults>
+        <default field="ogc_fid" expression=""/>
+        <default field="obj_type" expression=""/>
+        <default field="obj_id" expression=""/>
+        <default field="nodes" expression=""/>
+        <default field="id1" expression=""/>
+        <default field="id2" expression=""/>
+        <default field="problem" expression=""/>
+      </defaults>
+      <map-layer-style-manager current="">
+        <map-layer-style name=""/>
+      </map-layer-style-manager>
+      <edittypes>
+        <edittype widgetv2type="TextEdit" name="ogc_fid">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="obj_type">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="obj_id">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="nodes">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="id1">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="id2">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="problem">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+      </edittypes>
+      <renderer-v2 attr="problem" forceraster="0" symbollevels="0" type="categorizedSymbol" enableorderby="0">
+        <categories>
+          <category render="true" symbol="0" value="intersection" label="intersection"/>
+          <category render="true" symbol="1" value="role_should_be_outer" label="role_should_be_outer"/>
+          <category render="true" symbol="2" value="role_should_be_inner" label="role_should_be_inner"/>
+          <category render="true" symbol="3" value="duplicate_segment" label="duplicate_segment"/>
+          <category render="true" symbol="4" value="duplicate_way" label="duplicate_way"/>
+          <category render="true" symbol="5" value="inner_with_same_tags" label="inner_with_same_tags"/>
+          <category render="true" symbol="6" value="way_in_multiple_rings" label="way_in_multiple_rings"/>
+        </categories>
+        <symbols>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="0">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="255,0,0,255"/>
+              <prop k="line_style" v="solid"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="1">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="255,122,33,255"/>
+              <prop k="line_style" v="solid"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="2">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="255,122,33,255"/>
+              <prop k="line_style" v="dash"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="3">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="43,219,0,255"/>
+              <prop k="line_style" v="dot"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="4">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="255,5,0,255"/>
+              <prop k="line_style" v="dot"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="-0.6"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="255,0,0,255"/>
+              <prop k="line_style" v="dot"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0.6"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="5">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="243,235,0,255"/>
+              <prop k="line_style" v="solid"/>
+              <prop k="line_width" v="0.6"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="0,0,0,255"/>
+              <prop k="line_style" v="dot"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="6">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="60,208,0,255"/>
+              <prop k="line_style" v="solid"/>
+              <prop k="line_width" v="0.5"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+        </symbols>
+        <source-symbol>
+          <symbol alpha="1" clip_to_extent="1" type="line" name="0">
+            <layer pass="0" class="SimpleLine" locked="0">
+              <prop k="capstyle" v="square"/>
+              <prop k="customdash" v="5;2"/>
+              <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="customdash_unit" v="MM"/>
+              <prop k="draw_inside_polygon" v="0"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="line_color" v="77,243,51,255"/>
+              <prop k="line_style" v="solid"/>
+              <prop k="line_width" v="0.26"/>
+              <prop k="line_width_unit" v="MM"/>
+              <prop k="offset" v="0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="use_custom_dash" v="0"/>
+              <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+            </layer>
+          </symbol>
+        </source-symbol>
+        <rotation/>
+        <sizescale scalemethod="diameter"/>
+      </renderer-v2>
+      <labeling type="simple"/>
+      <customproperties>
+        <property key="labeling" value="pal"/>
+        <property key="labeling/addDirectionSymbol" value="false"/>
+        <property key="labeling/angleOffset" value="0"/>
+        <property key="labeling/blendMode" value="0"/>
+        <property key="labeling/bufferBlendMode" value="0"/>
+        <property key="labeling/bufferColorA" value="255"/>
+        <property key="labeling/bufferColorB" value="255"/>
+        <property key="labeling/bufferColorG" value="255"/>
+        <property key="labeling/bufferColorR" value="255"/>
+        <property key="labeling/bufferDraw" value="false"/>
+        <property key="labeling/bufferJoinStyle" value="64"/>
+        <property key="labeling/bufferNoFill" value="false"/>
+        <property key="labeling/bufferSize" value="1"/>
+        <property key="labeling/bufferSizeInMapUnits" value="false"/>
+        <property key="labeling/bufferTransp" value="0"/>
+        <property key="labeling/centroidWhole" value="false"/>
+        <property key="labeling/decimals" value="3"/>
+        <property key="labeling/displayAll" value="false"/>
+        <property key="labeling/dist" value="0"/>
+        <property key="labeling/distInMapUnits" value="false"/>
+        <property key="labeling/enabled" value="false"/>
+        <property key="labeling/fieldName" value=""/>
+        <property key="labeling/fontBold" value="false"/>
+        <property key="labeling/fontCapitals" value="0"/>
+        <property key="labeling/fontFamily" value="Sans"/>
+        <property key="labeling/fontItalic" value="false"/>
+        <property key="labeling/fontLetterSpacing" value="0"/>
+        <property key="labeling/fontLimitPixelSize" value="false"/>
+        <property key="labeling/fontMaxPixelSize" value="10000"/>
+        <property key="labeling/fontMinPixelSize" value="3"/>
+        <property key="labeling/fontSize" value="10"/>
+        <property key="labeling/fontSizeInMapUnits" value="false"/>
+        <property key="labeling/fontStrikeout" value="false"/>
+        <property key="labeling/fontUnderline" value="false"/>
+        <property key="labeling/fontWeight" value="50"/>
+        <property key="labeling/fontWordSpacing" value="0"/>
+        <property key="labeling/formatNumbers" value="false"/>
+        <property key="labeling/isExpression" value="false"/>
+        <property key="labeling/labelOffsetInMapUnits" value="true"/>
+        <property key="labeling/labelPerPart" value="false"/>
+        <property key="labeling/leftDirectionSymbol" value="<"/>
+        <property key="labeling/limitNumLabels" value="false"/>
+        <property key="labeling/maxCurvedCharAngleIn" value="20"/>
+        <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
+        <property key="labeling/maxNumLabels" value="2000"/>
+        <property key="labeling/mergeLines" value="false"/>
+        <property key="labeling/minFeatureSize" value="0"/>
+        <property key="labeling/multilineAlign" value="0"/>
+        <property key="labeling/multilineHeight" value="1"/>
+        <property key="labeling/namedStyle" value=""/>
+        <property key="labeling/obstacle" value="true"/>
+        <property key="labeling/placeDirectionSymbol" value="0"/>
+        <property key="labeling/placement" value="2"/>
+        <property key="labeling/placementFlags" value="10"/>
+        <property key="labeling/plussign" value="false"/>
+        <property key="labeling/preserveRotation" value="true"/>
+        <property key="labeling/previewBkgrdColor" value="#ffffff"/>
+        <property key="labeling/priority" value="5"/>
+        <property key="labeling/quadOffset" value="4"/>
+        <property key="labeling/reverseDirectionSymbol" value="false"/>
+        <property key="labeling/rightDirectionSymbol" value=">"/>
+        <property key="labeling/scaleMax" value="10000000"/>
+        <property key="labeling/scaleMin" value="1"/>
+        <property key="labeling/scaleVisibility" value="false"/>
+        <property key="labeling/shadowBlendMode" value="6"/>
+        <property key="labeling/shadowColorB" value="0"/>
+        <property key="labeling/shadowColorG" value="0"/>
+        <property key="labeling/shadowColorR" value="0"/>
+        <property key="labeling/shadowDraw" value="false"/>
+        <property key="labeling/shadowOffsetAngle" value="135"/>
+        <property key="labeling/shadowOffsetDist" value="1"/>
+        <property key="labeling/shadowOffsetGlobal" value="true"/>
+        <property key="labeling/shadowOffsetUnits" value="1"/>
+        <property key="labeling/shadowRadius" value="1.5"/>
+        <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
+        <property key="labeling/shadowRadiusUnits" value="1"/>
+        <property key="labeling/shadowScale" value="100"/>
+        <property key="labeling/shadowTransparency" value="30"/>
+        <property key="labeling/shadowUnder" value="0"/>
+        <property key="labeling/shapeBlendMode" value="0"/>
+        <property key="labeling/shapeBorderColorA" value="255"/>
+        <property key="labeling/shapeBorderColorB" value="128"/>
+        <property key="labeling/shapeBorderColorG" value="128"/>
+        <property key="labeling/shapeBorderColorR" value="128"/>
+        <property key="labeling/shapeBorderWidth" value="0"/>
+        <property key="labeling/shapeBorderWidthUnits" value="1"/>
+        <property key="labeling/shapeDraw" value="false"/>
+        <property key="labeling/shapeFillColorA" value="255"/>
+        <property key="labeling/shapeFillColorB" value="255"/>
+        <property key="labeling/shapeFillColorG" value="255"/>
+        <property key="labeling/shapeFillColorR" value="255"/>
+        <property key="labeling/shapeJoinStyle" value="64"/>
+        <property key="labeling/shapeOffsetUnits" value="1"/>
+        <property key="labeling/shapeOffsetX" value="0"/>
+        <property key="labeling/shapeOffsetY" value="0"/>
+        <property key="labeling/shapeRadiiUnits" value="1"/>
+        <property key="labeling/shapeRadiiX" value="0"/>
+        <property key="labeling/shapeRadiiY" value="0"/>
+        <property key="labeling/shapeRotation" value="0"/>
+        <property key="labeling/shapeRotationType" value="0"/>
+        <property key="labeling/shapeSVGFile" value=""/>
+        <property key="labeling/shapeSizeType" value="0"/>
+        <property key="labeling/shapeSizeUnits" value="1"/>
+        <property key="labeling/shapeSizeX" value="0"/>
+        <property key="labeling/shapeSizeY" value="0"/>
+        <property key="labeling/shapeTransparency" value="0"/>
+        <property key="labeling/shapeType" value="0"/>
+        <property key="labeling/textColorA" value="255"/>
+        <property key="labeling/textColorB" value="0"/>
+        <property key="labeling/textColorG" value="0"/>
+        <property key="labeling/textColorR" value="0"/>
+        <property key="labeling/textTransp" value="0"/>
+        <property key="labeling/upsidedownLabels" value="0"/>
+        <property key="labeling/wrapChar" value=""/>
+        <property key="labeling/xOffset" value="0"/>
+        <property key="labeling/yOffset" value="0"/>
+      </customproperties>
+      <blendMode>0</blendMode>
+      <featureBlendMode>0</featureBlendMode>
+      <layerTransparency>0</layerTransparency>
+      <displayfield>OGC_FID</displayfield>
+      <label>0</label>
+      <labelattributes>
+        <label fieldname="" text="Label"/>
+        <family fieldname="" name="Sans"/>
+        <size fieldname="" units="pt" value="12"/>
+        <bold fieldname="" on="0"/>
+        <italic fieldname="" on="0"/>
+        <underline fieldname="" on="0"/>
+        <strikeout fieldname="" on="0"/>
+        <color fieldname="" red="0" blue="0" green="0"/>
+        <x fieldname=""/>
+        <y fieldname=""/>
+        <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
+        <angle fieldname="" value="0" auto="0"/>
+        <alignment fieldname="" value="center"/>
+        <buffercolor fieldname="" red="255" blue="255" green="255"/>
+        <buffersize fieldname="" units="pt" value="1"/>
+        <bufferenabled fieldname="" on=""/>
+        <multilineenabled fieldname="" on=""/>
+        <selectedonly on=""/>
+      </labelattributes>
+      <annotationform>.</annotationform>
+      <aliases>
+        <alias field="ogc_fid" index="0" name=""/>
+        <alias field="obj_type" index="1" name=""/>
+        <alias field="obj_id" index="2" name=""/>
+        <alias field="nodes" index="3" name=""/>
+        <alias field="id1" index="4" name=""/>
+        <alias field="id2" index="5" name=""/>
+        <alias field="problem" index="6" name=""/>
+      </aliases>
+      <excludeAttributesWMS/>
+      <excludeAttributesWFS/>
+      <attributeactions default="-1"/>
+      <attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
+        <columns/>
+      </attributetableconfig>
+      <editform>.</editform>
+      <editforminit/>
+      <editforminitcodesource>0</editforminitcodesource>
+      <editforminitfilepath></editforminitfilepath>
+      <editforminitcode><![CDATA[]]></editforminitcode>
+      <featformsuppress>0</featformsuppress>
+      <editorlayout>generatedlayout</editorlayout>
+      <widgets/>
+      <conditionalstyles>
+        <rowstyles/>
+        <fieldstyles/>
+      </conditionalstyles>
+    </maplayer>
+    <maplayer simplifyAlgorithm="0" minimumScale="-4.65661e-10" maximumScale="1e+08" simplifyDrawingHints="1" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Polygon" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
+      <id>multipolygons20140221151811742</id>
+      <datasource>dbname='./multipolygon.db' table="multipolygons" (GEOMETRY) sql=</datasource>
+      <keywordList>
+        <value></value>
+      </keywordList>
+      <layername>multipolygons</layername>
+      <srs>
+        <spatialrefsys>
+          <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
+          <srsid>3452</srsid>
+          <srid>4326</srid>
+          <authid>EPSG:4326</authid>
+          <description>WGS 84</description>
+          <projectionacronym>longlat</projectionacronym>
+          <ellipsoidacronym>WGS84</ellipsoidacronym>
+          <geographicflag>true</geographicflag>
+        </spatialrefsys>
+      </srs>
+      <provider encoding="System">spatialite</provider>
+      <previewExpression></previewExpression>
+      <vectorjoins/>
+      <layerDependencies/>
+      <expressionfields/>
+      <defaults>
+        <default field="ogc_fid" expression=""/>
+        <default field="id" expression=""/>
+        <default field="from_type" expression=""/>
+      </defaults>
+      <map-layer-style-manager current="">
+        <map-layer-style name=""/>
+      </map-layer-style-manager>
+      <edittypes>
+        <edittype widgetv2type="TextEdit" name="ogc_fid">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="id">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="from_type">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+      </edittypes>
+      <renderer-v2 forceraster="0" symbollevels="0" type="singleSymbol" enableorderby="0">
+        <symbols>
+          <symbol alpha="0.494118" clip_to_extent="1" type="fill" name="0">
+            <layer pass="0" class="SimpleFill" locked="0">
+              <prop k="border_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="color" v="0,170,255,255"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.26"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="style" v="solid"/>
+            </layer>
+          </symbol>
+        </symbols>
+        <rotation/>
+        <sizescale scalemethod="diameter"/>
+      </renderer-v2>
+      <labeling type="simple"/>
+      <customproperties>
+        <property key="labeling" value="pal"/>
+        <property key="labeling/addDirectionSymbol" value="false"/>
+        <property key="labeling/angleOffset" value="0"/>
+        <property key="labeling/blendMode" value="0"/>
+        <property key="labeling/bufferBlendMode" value="0"/>
+        <property key="labeling/bufferColorA" value="255"/>
+        <property key="labeling/bufferColorB" value="255"/>
+        <property key="labeling/bufferColorG" value="255"/>
+        <property key="labeling/bufferColorR" value="255"/>
+        <property key="labeling/bufferDraw" value="false"/>
+        <property key="labeling/bufferJoinStyle" value="64"/>
+        <property key="labeling/bufferNoFill" value="false"/>
+        <property key="labeling/bufferSize" value="1"/>
+        <property key="labeling/bufferSizeInMapUnits" value="false"/>
+        <property key="labeling/bufferTransp" value="0"/>
+        <property key="labeling/centroidWhole" value="false"/>
+        <property key="labeling/decimals" value="3"/>
+        <property key="labeling/displayAll" value="false"/>
+        <property key="labeling/dist" value="0"/>
+        <property key="labeling/distInMapUnits" value="false"/>
+        <property key="labeling/enabled" value="false"/>
+        <property key="labeling/fieldName" value=""/>
+        <property key="labeling/fontBold" value="false"/>
+        <property key="labeling/fontCapitals" value="0"/>
+        <property key="labeling/fontFamily" value="Sans"/>
+        <property key="labeling/fontItalic" value="false"/>
+        <property key="labeling/fontLetterSpacing" value="0"/>
+        <property key="labeling/fontLimitPixelSize" value="false"/>
+        <property key="labeling/fontMaxPixelSize" value="10000"/>
+        <property key="labeling/fontMinPixelSize" value="3"/>
+        <property key="labeling/fontSize" value="10"/>
+        <property key="labeling/fontSizeInMapUnits" value="false"/>
+        <property key="labeling/fontStrikeout" value="false"/>
+        <property key="labeling/fontUnderline" value="false"/>
+        <property key="labeling/fontWeight" value="50"/>
+        <property key="labeling/fontWordSpacing" value="0"/>
+        <property key="labeling/formatNumbers" value="false"/>
+        <property key="labeling/isExpression" value="false"/>
+        <property key="labeling/labelOffsetInMapUnits" value="true"/>
+        <property key="labeling/labelPerPart" value="false"/>
+        <property key="labeling/leftDirectionSymbol" value="<"/>
+        <property key="labeling/limitNumLabels" value="false"/>
+        <property key="labeling/maxCurvedCharAngleIn" value="20"/>
+        <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
+        <property key="labeling/maxNumLabels" value="2000"/>
+        <property key="labeling/mergeLines" value="false"/>
+        <property key="labeling/minFeatureSize" value="0"/>
+        <property key="labeling/multilineAlign" value="0"/>
+        <property key="labeling/multilineHeight" value="1"/>
+        <property key="labeling/namedStyle" value=""/>
+        <property key="labeling/obstacle" value="true"/>
+        <property key="labeling/placeDirectionSymbol" value="0"/>
+        <property key="labeling/placement" value="0"/>
+        <property key="labeling/placementFlags" value="0"/>
+        <property key="labeling/plussign" value="false"/>
+        <property key="labeling/preserveRotation" value="true"/>
+        <property key="labeling/previewBkgrdColor" value="#ffffff"/>
+        <property key="labeling/priority" value="5"/>
+        <property key="labeling/quadOffset" value="4"/>
+        <property key="labeling/reverseDirectionSymbol" value="false"/>
+        <property key="labeling/rightDirectionSymbol" value=">"/>
+        <property key="labeling/scaleMax" value="10000000"/>
+        <property key="labeling/scaleMin" value="1"/>
+        <property key="labeling/scaleVisibility" value="false"/>
+        <property key="labeling/shadowBlendMode" value="6"/>
+        <property key="labeling/shadowColorB" value="0"/>
+        <property key="labeling/shadowColorG" value="0"/>
+        <property key="labeling/shadowColorR" value="0"/>
+        <property key="labeling/shadowDraw" value="false"/>
+        <property key="labeling/shadowOffsetAngle" value="135"/>
+        <property key="labeling/shadowOffsetDist" value="1"/>
+        <property key="labeling/shadowOffsetGlobal" value="true"/>
+        <property key="labeling/shadowOffsetUnits" value="1"/>
+        <property key="labeling/shadowRadius" value="1.5"/>
+        <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
+        <property key="labeling/shadowRadiusUnits" value="1"/>
+        <property key="labeling/shadowScale" value="100"/>
+        <property key="labeling/shadowTransparency" value="30"/>
+        <property key="labeling/shadowUnder" value="0"/>
+        <property key="labeling/shapeBlendMode" value="0"/>
+        <property key="labeling/shapeBorderColorA" value="255"/>
+        <property key="labeling/shapeBorderColorB" value="128"/>
+        <property key="labeling/shapeBorderColorG" value="128"/>
+        <property key="labeling/shapeBorderColorR" value="128"/>
+        <property key="labeling/shapeBorderWidth" value="0"/>
+        <property key="labeling/shapeBorderWidthUnits" value="1"/>
+        <property key="labeling/shapeDraw" value="false"/>
+        <property key="labeling/shapeFillColorA" value="255"/>
+        <property key="labeling/shapeFillColorB" value="255"/>
+        <property key="labeling/shapeFillColorG" value="255"/>
+        <property key="labeling/shapeFillColorR" value="255"/>
+        <property key="labeling/shapeJoinStyle" value="64"/>
+        <property key="labeling/shapeOffsetUnits" value="1"/>
+        <property key="labeling/shapeOffsetX" value="0"/>
+        <property key="labeling/shapeOffsetY" value="0"/>
+        <property key="labeling/shapeRadiiUnits" value="1"/>
+        <property key="labeling/shapeRadiiX" value="0"/>
+        <property key="labeling/shapeRadiiY" value="0"/>
+        <property key="labeling/shapeRotation" value="0"/>
+        <property key="labeling/shapeRotationType" value="0"/>
+        <property key="labeling/shapeSVGFile" value=""/>
+        <property key="labeling/shapeSizeType" value="0"/>
+        <property key="labeling/shapeSizeUnits" value="1"/>
+        <property key="labeling/shapeSizeX" value="0"/>
+        <property key="labeling/shapeSizeY" value="0"/>
+        <property key="labeling/shapeTransparency" value="0"/>
+        <property key="labeling/shapeType" value="0"/>
+        <property key="labeling/textColorA" value="255"/>
+        <property key="labeling/textColorB" value="0"/>
+        <property key="labeling/textColorG" value="0"/>
+        <property key="labeling/textColorR" value="0"/>
+        <property key="labeling/textTransp" value="0"/>
+        <property key="labeling/upsidedownLabels" value="0"/>
+        <property key="labeling/wrapChar" value=""/>
+        <property key="labeling/xOffset" value="0"/>
+        <property key="labeling/yOffset" value="0"/>
+      </customproperties>
+      <blendMode>0</blendMode>
+      <featureBlendMode>0</featureBlendMode>
+      <layerTransparency>0</layerTransparency>
+      <displayfield>OGC_FID</displayfield>
+      <label>0</label>
+      <labelattributes>
+        <label fieldname="" text="Label"/>
+        <family fieldname="" name="Sans"/>
+        <size fieldname="" units="pt" value="12"/>
+        <bold fieldname="" on="0"/>
+        <italic fieldname="" on="0"/>
+        <underline fieldname="" on="0"/>
+        <strikeout fieldname="" on="0"/>
+        <color fieldname="" red="0" blue="0" green="0"/>
+        <x fieldname=""/>
+        <y fieldname=""/>
+        <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
+        <angle fieldname="" value="0" auto="0"/>
+        <alignment fieldname="" value="center"/>
+        <buffercolor fieldname="" red="255" blue="255" green="255"/>
+        <buffersize fieldname="" units="pt" value="1"/>
+        <bufferenabled fieldname="" on=""/>
+        <multilineenabled fieldname="" on=""/>
+        <selectedonly on=""/>
+      </labelattributes>
+      <annotationform>.</annotationform>
+      <aliases>
+        <alias field="ogc_fid" index="0" name=""/>
+        <alias field="id" index="1" name=""/>
+        <alias field="from_type" index="2" name=""/>
+      </aliases>
+      <excludeAttributesWMS/>
+      <excludeAttributesWFS/>
+      <attributeactions default="0"/>
+      <attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
+        <columns/>
+      </attributetableconfig>
+      <editform>.</editform>
+      <editforminit/>
+      <editforminitcodesource>0</editforminitcodesource>
+      <editforminitfilepath></editforminitfilepath>
+      <editforminitcode><![CDATA[]]></editforminitcode>
+      <featformsuppress>0</featformsuppress>
+      <editorlayout>generatedlayout</editorlayout>
+      <widgets/>
+      <conditionalstyles>
+        <rowstyles/>
+        <fieldstyles/>
+      </conditionalstyles>
+    </maplayer>
+    <maplayer simplifyAlgorithm="0" minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="0" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Point" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
+      <id>perrors20140228163658956</id>
+      <datasource>dbname='./multipolygon.db' table="perrors" (GEOMETRY) sql=</datasource>
+      <keywordList>
+        <value></value>
+      </keywordList>
+      <layername>Error Points</layername>
+      <srs>
+        <spatialrefsys>
+          <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
+          <srsid>3452</srsid>
+          <srid>4326</srid>
+          <authid>EPSG:4326</authid>
+          <description>WGS 84</description>
+          <projectionacronym>longlat</projectionacronym>
+          <ellipsoidacronym>WGS84</ellipsoidacronym>
+          <geographicflag>true</geographicflag>
+        </spatialrefsys>
+      </srs>
+      <provider encoding="System">spatialite</provider>
+      <previewExpression>COALESCE( "OGC_FID", '<NULL>' )</previewExpression>
+      <vectorjoins/>
+      <layerDependencies/>
+      <expressionfields/>
+      <defaults>
+        <default field="ogc_fid" expression=""/>
+        <default field="obj_type" expression=""/>
+        <default field="obj_id" expression=""/>
+        <default field="nodes" expression=""/>
+        <default field="id1" expression=""/>
+        <default field="id2" expression=""/>
+        <default field="problem" expression=""/>
+      </defaults>
+      <map-layer-style-manager current="">
+        <map-layer-style name=""/>
+      </map-layer-style-manager>
+      <edittypes>
+        <edittype widgetv2type="TextEdit" name="ogc_fid">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="obj_type">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="obj_id">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="nodes">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="id1">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="id2">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+        <edittype widgetv2type="TextEdit" name="problem">
+          <widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
+        </edittype>
+      </edittypes>
+      <renderer-v2 attr="problem" forceraster="0" symbollevels="0" type="categorizedSymbol" enableorderby="0">
+        <categories>
+          <category render="true" symbol="0" value="touching_ring" label="touching_ring"/>
+          <category render="true" symbol="1" value="ring_not_closed" label="ring_not_closed"/>
+          <category render="true" symbol="2" value="duplicate_node" label="duplicate_node"/>
+          <category render="true" symbol="3" value="intersection" label="intersection"/>
+        </categories>
+        <symbols>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="0">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="255,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="diamond"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="255,255,255,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.4"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="diameter"/>
+              <prop k="size" v="2.8"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="255,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="triangle"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="255,255,255,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.4"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="diameter"/>
+              <prop k="size" v="2.8"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="2">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="255,255,255,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="circle"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="255,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.4"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="diameter"/>
+              <prop k="size" v="2.4"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="255,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="circle"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="255,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.8"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="diameter"/>
+              <prop k="size" v="0.5"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="3">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="139,168,110,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="cross2"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="255,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0.6"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="diameter"/>
+              <prop k="size" v="2"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </symbols>
+        <source-symbol>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="0">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="139,168,110,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="joinstyle" v="bevel"/>
+              <prop k="name" v="circle"/>
+              <prop k="offset" v="0,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="2"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </source-symbol>
+        <rotation/>
+        <sizescale scalemethod="diameter"/>
+      </renderer-v2>
+      <labeling type="simple"/>
+      <customproperties>
+        <property key="labeling" value="pal"/>
+        <property key="labeling/addDirectionSymbol" value="false"/>
+        <property key="labeling/angleOffset" value="0"/>
+        <property key="labeling/blendMode" value="0"/>
+        <property key="labeling/bufferBlendMode" value="0"/>
+        <property key="labeling/bufferColorA" value="255"/>
+        <property key="labeling/bufferColorB" value="255"/>
+        <property key="labeling/bufferColorG" value="255"/>
+        <property key="labeling/bufferColorR" value="255"/>
+        <property key="labeling/bufferDraw" value="false"/>
+        <property key="labeling/bufferJoinStyle" value="64"/>
+        <property key="labeling/bufferNoFill" value="false"/>
+        <property key="labeling/bufferSize" value="1"/>
+        <property key="labeling/bufferSizeInMapUnits" value="false"/>
+        <property key="labeling/bufferTransp" value="0"/>
+        <property key="labeling/centroidWhole" value="false"/>
+        <property key="labeling/decimals" value="3"/>
+        <property key="labeling/displayAll" value="false"/>
+        <property key="labeling/dist" value="0"/>
+        <property key="labeling/distInMapUnits" value="false"/>
+        <property key="labeling/enabled" value="false"/>
+        <property key="labeling/fieldName" value=""/>
+        <property key="labeling/fontBold" value="false"/>
+        <property key="labeling/fontCapitals" value="0"/>
+        <property key="labeling/fontFamily" value="Sans"/>
+        <property key="labeling/fontItalic" value="false"/>
+        <property key="labeling/fontLetterSpacing" value="0"/>
+        <property key="labeling/fontLimitPixelSize" value="false"/>
+        <property key="labeling/fontMaxPixelSize" value="10000"/>
+        <property key="labeling/fontMinPixelSize" value="3"/>
+        <property key="labeling/fontSize" value="10"/>
+        <property key="labeling/fontSizeInMapUnits" value="false"/>
+        <property key="labeling/fontStrikeout" value="false"/>
+        <property key="labeling/fontUnderline" value="false"/>
+        <property key="labeling/fontWeight" value="50"/>
+        <property key="labeling/fontWordSpacing" value="0"/>
+        <property key="labeling/formatNumbers" value="false"/>
+        <property key="labeling/isExpression" value="false"/>
+        <property key="labeling/labelOffsetInMapUnits" value="true"/>
+        <property key="labeling/labelPerPart" value="false"/>
+        <property key="labeling/leftDirectionSymbol" value="<"/>
+        <property key="labeling/limitNumLabels" value="false"/>
+        <property key="labeling/maxCurvedCharAngleIn" value="20"/>
+        <property key="labeling/maxCurvedCharAngleOut" value="-20"/>
+        <property key="labeling/maxNumLabels" value="2000"/>
+        <property key="labeling/mergeLines" value="false"/>
+        <property key="labeling/minFeatureSize" value="0"/>
+        <property key="labeling/multilineAlign" value="0"/>
+        <property key="labeling/multilineHeight" value="1"/>
+        <property key="labeling/namedStyle" value=""/>
+        <property key="labeling/obstacle" value="true"/>
+        <property key="labeling/placeDirectionSymbol" value="0"/>
+        <property key="labeling/placement" value="0"/>
+        <property key="labeling/placementFlags" value="0"/>
+        <property key="labeling/plussign" value="false"/>
+        <property key="labeling/preserveRotation" value="true"/>
+        <property key="labeling/previewBkgrdColor" value="#ffffff"/>
+        <property key="labeling/priority" value="5"/>
+        <property key="labeling/quadOffset" value="4"/>
+        <property key="labeling/reverseDirectionSymbol" value="false"/>
+        <property key="labeling/rightDirectionSymbol" value=">"/>
+        <property key="labeling/scaleMax" value="10000000"/>
+        <property key="labeling/scaleMin" value="1"/>
+        <property key="labeling/scaleVisibility" value="false"/>
+        <property key="labeling/shadowBlendMode" value="6"/>
+        <property key="labeling/shadowColorB" value="0"/>
+        <property key="labeling/shadowColorG" value="0"/>
+        <property key="labeling/shadowColorR" value="0"/>
+        <property key="labeling/shadowDraw" value="false"/>
+        <property key="labeling/shadowOffsetAngle" value="135"/>
+        <property key="labeling/shadowOffsetDist" value="1"/>
+        <property key="labeling/shadowOffsetGlobal" value="true"/>
+        <property key="labeling/shadowOffsetUnits" value="1"/>
+        <property key="labeling/shadowRadius" value="1.5"/>
+        <property key="labeling/shadowRadiusAlphaOnly" value="false"/>
+        <property key="labeling/shadowRadiusUnits" value="1"/>
+        <property key="labeling/shadowScale" value="100"/>
+        <property key="labeling/shadowTransparency" value="30"/>
+        <property key="labeling/shadowUnder" value="0"/>
+        <property key="labeling/shapeBlendMode" value="0"/>
+        <property key="labeling/shapeBorderColorA" value="255"/>
+        <property key="labeling/shapeBorderColorB" value="128"/>
+        <property key="labeling/shapeBorderColorG" value="128"/>
+        <property key="labeling/shapeBorderColorR" value="128"/>
+        <property key="labeling/shapeBorderWidth" value="0"/>
+        <property key="labeling/shapeBorderWidthUnits" value="1"/>
+        <property key="labeling/shapeDraw" value="false"/>
+        <property key="labeling/shapeFillColorA" value="255"/>
+        <property key="labeling/shapeFillColorB" value="255"/>
+        <property key="labeling/shapeFillColorG" value="255"/>
+        <property key="labeling/shapeFillColorR" value="255"/>
+        <property key="labeling/shapeJoinStyle" value="64"/>
+        <property key="labeling/shapeOffsetUnits" value="1"/>
+        <property key="labeling/shapeOffsetX" value="0"/>
+        <property key="labeling/shapeOffsetY" value="0"/>
+        <property key="labeling/shapeRadiiUnits" value="1"/>
+        <property key="labeling/shapeRadiiX" value="0"/>
+        <property key="labeling/shapeRadiiY" value="0"/>
+        <property key="labeling/shapeRotation" value="0"/>
+        <property key="labeling/shapeRotationType" value="0"/>
+        <property key="labeling/shapeSVGFile" value=""/>
+        <property key="labeling/shapeSizeType" value="0"/>
+        <property key="labeling/shapeSizeUnits" value="1"/>
+        <property key="labeling/shapeSizeX" value="0"/>
+        <property key="labeling/shapeSizeY" value="0"/>
+        <property key="labeling/shapeTransparency" value="0"/>
+        <property key="labeling/shapeType" value="0"/>
+        <property key="labeling/textColorA" value="255"/>
+        <property key="labeling/textColorB" value="0"/>
+        <property key="labeling/textColorG" value="0"/>
+        <property key="labeling/textColorR" value="0"/>
+        <property key="labeling/textTransp" value="0"/>
+        <property key="labeling/upsidedownLabels" value="0"/>
+        <property key="labeling/wrapChar" value=""/>
+        <property key="labeling/xOffset" value="0"/>
+        <property key="labeling/yOffset" value="0"/>
+      </customproperties>
+      <blendMode>0</blendMode>
+      <featureBlendMode>0</featureBlendMode>
+      <layerTransparency>0</layerTransparency>
+      <displayfield>OGC_FID</displayfield>
+      <label>0</label>
+      <labelattributes>
+        <label fieldname="" text="Label"/>
+        <family fieldname="" name="Sans"/>
+        <size fieldname="" units="pt" value="12"/>
+        <bold fieldname="" on="0"/>
+        <italic fieldname="" on="0"/>
+        <underline fieldname="" on="0"/>
+        <strikeout fieldname="" on="0"/>
+        <color fieldname="" red="0" blue="0" green="0"/>
+        <x fieldname=""/>
+        <y fieldname=""/>
+        <offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
+        <angle fieldname="" value="0" auto="0"/>
+        <alignment fieldname="" value="center"/>
+        <buffercolor fieldname="" red="255" blue="255" green="255"/>
+        <buffersize fieldname="" units="pt" value="1"/>
+        <bufferenabled fieldname="" on=""/>
+        <multilineenabled fieldname="" on=""/>
+        <selectedonly on=""/>
+      </labelattributes>
+      <annotationform>.</annotationform>
+      <aliases>
+        <alias field="ogc_fid" index="0" name=""/>
+        <alias field="obj_type" index="1" name=""/>
+        <alias field="obj_id" index="2" name=""/>
+        <alias field="nodes" index="3" name=""/>
+        <alias field="id1" index="4" name=""/>
+        <alias field="id2" index="5" name=""/>
+        <alias field="problem" index="6" name=""/>
+      </aliases>
+      <excludeAttributesWMS/>
+      <excludeAttributesWFS/>
+      <attributeactions default="-1"/>
+      <attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
+        <columns/>
+      </attributetableconfig>
+      <editform>.</editform>
+      <editforminit/>
+      <editforminitcodesource>0</editforminitcodesource>
+      <editforminitfilepath></editforminitfilepath>
+      <editforminitcode><![CDATA[]]></editforminitcode>
+      <featformsuppress>0</featformsuppress>
+      <editorlayout>generatedlayout</editorlayout>
+      <widgets/>
+      <conditionalstyles>
+        <rowstyles/>
+        <fieldstyles/>
+      </conditionalstyles>
+    </maplayer>
+  </projectlayers>
+  <properties>
+    <WMSContactPerson type="QString"></WMSContactPerson>
+    <WMSOnlineResource type="QString"></WMSOnlineResource>
+    <WMSContactOrganization type="QString"></WMSContactOrganization>
+    <WMSExtent type="QStringList">
+      <value>0.82500024999999999</value>
+      <value>-0.35415386986094277</value>
+      <value>8.17498974999999994</value>
+      <value>3.45415386986094308</value>
+    </WMSExtent>
+    <WMSKeywordList type="QStringList">
+      <value></value>
+    </WMSKeywordList>
+    <WFSUrl type="QString"></WFSUrl>
+    <Paths>
+      <Absolute type="bool">false</Absolute>
+    </Paths>
+    <WMSServiceTitle type="QString">mp test</WMSServiceTitle>
+    <WFSLayers type="QStringList"/>
+    <WMSContactMail type="QString"></WMSContactMail>
+    <PositionPrecision>
+      <DecimalPlaces type="int">2</DecimalPlaces>
+      <Automatic type="bool">true</Automatic>
+      <DegreeFormat type="QString">D</DegreeFormat>
+    </PositionPrecision>
+    <WCSUrl type="QString"></WCSUrl>
+    <WMSContactPhone type="QString"></WMSContactPhone>
+    <WMSServiceCapabilities type="bool">true</WMSServiceCapabilities>
+    <WMSServiceAbstract type="QString"></WMSServiceAbstract>
+    <WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
+    <Measure>
+      <Ellipsoid type="QString">NONE</Ellipsoid>
+    </Measure>
+    <WFSTLayers>
+      <Insert type="QStringList"/>
+      <Update type="QStringList"/>
+      <Delete type="QStringList"/>
+    </WFSTLayers>
+    <Gui>
+      <SelectionColorBluePart type="int">0</SelectionColorBluePart>
+      <CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
+      <CanvasColorRedPart type="int">255</CanvasColorRedPart>
+      <SelectionColorRedPart type="int">255</SelectionColorRedPart>
+      <SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
+      <SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
+      <CanvasColorBluePart type="int">255</CanvasColorBluePart>
+    </Gui>
+    <Identify>
+      <disabledLayers type="QStringList"/>
+    </Identify>
+    <Macros>
+      <pythonCode type="QString"></pythonCode>
+    </Macros>
+    <WMSAccessConstraints type="QString"></WMSAccessConstraints>
+    <WCSLayers type="QStringList"/>
+    <Legend>
+      <filterByMap type="bool">false</filterByMap>
+    </Legend>
+    <SpatialRefSys>
+      <ProjectCrs type="QString">EPSG:4326</ProjectCrs>
+    </SpatialRefSys>
+    <DefaultStyles>
+      <Fill type="QString"></Fill>
+      <Line type="QString"></Line>
+      <Marker type="QString"></Marker>
+      <RandomColors type="bool">true</RandomColors>
+      <AlphaInt type="int">255</AlphaInt>
+      <ColorRamp type="QString"></ColorRamp>
+    </DefaultStyles>
+    <WMSFees type="QString"></WMSFees>
+    <Measurement>
+      <DistanceUnits type="QString">meters</DistanceUnits>
+      <AreaUnits type="QString">m2</AreaUnits>
+    </Measurement>
+    <WMSUrl type="QString"></WMSUrl>
+  </properties>
+  <visibility-presets/>
 </qgis>
diff --git a/test/data-tests/testdata-xml.cpp b/test/data-tests/testdata-xml.cpp
index 5191f8a..5f11429 100644
--- a/test/data-tests/testdata-xml.cpp
+++ b/test/data-tests/testdata-xml.cpp
@@ -83,7 +83,14 @@ static header_buffer_type parse_xml(std::string input) {
     osmium::io::detail::add_to_queue(input_queue, std::move(input));
     osmium::io::detail::add_to_queue(input_queue, std::string{});
 
-    osmium::io::detail::XMLParser parser{input_queue, output_queue, header_promise, osmium::io::detail::reader_options{}};
+    osmium::io::detail::parser_arguments args = {
+        input_queue,
+        output_queue,
+        header_promise,
+        osmium::osm_entity_bits::all,
+        osmium::io::read_meta::yes
+    };
+    osmium::io::detail::XMLParser parser{args};
     parser.parse();
 
     header_buffer_type result;
@@ -485,6 +492,7 @@ TEST_CASE("Reading OSM XML 200: Using Reader asking for header only") {
     const osmium::io::Header header{reader.header()};
     REQUIRE(header.get("generator") == "testdata");
 
+    REQUIRE_FALSE(reader.read());
     REQUIRE_THROWS(reader.read());
 
     reader.close();
diff --git a/test/t/area/test_node_ref_segment.cpp b/test/t/area/test_node_ref_segment.cpp
index 9eba380..45e6f9d 100644
--- a/test/t/area/test_node_ref_segment.cpp
+++ b/test/t/area/test_node_ref_segment.cpp
@@ -3,6 +3,7 @@
 #include <osmium/area/detail/node_ref_segment.hpp>
 
 using osmium::area::detail::NodeRefSegment;
+using osmium::area::detail::role_type;
 
 TEST_CASE("Default construction of NodeRefSegment") {
     NodeRefSegment s;
@@ -18,27 +19,27 @@ TEST_CASE("Construction of NodeRefSegment with NodeRefs") {
     osmium::NodeRef nr3{3, {1.2, 3.6}};
     osmium::NodeRef nr4{4, {1.2, 3.7}};
 
-    NodeRefSegment s1{nr1, nr2};
+    NodeRefSegment s1{nr1, nr2, role_type::unknown, nullptr};
     REQUIRE(s1.first().ref() == 1);
     REQUIRE(s1.second().ref() == 2);
 
-    NodeRefSegment s2{nr2, nr3};
+    NodeRefSegment s2{nr2, nr3, role_type::unknown, nullptr};
     REQUIRE(s2.first().ref() == 3);
     REQUIRE(s2.second().ref() == 2);
 
-    NodeRefSegment s3{nr3, nr4};
+    NodeRefSegment s3{nr3, nr4, role_type::unknown, nullptr};
     REQUIRE(s3.first().ref() == 3);
     REQUIRE(s3.second().ref() == 4);
 }
 
 TEST_CASE("Intersection of NodeRefSegments") {
-    NodeRefSegment s1{{ 1, {0.0, 0.0}}, { 2, {2.0, 2.0}}};
-    NodeRefSegment s2{{ 3, {0.0, 2.0}}, { 4, {2.0, 0.0}}};
-    NodeRefSegment s3{{ 5, {2.0, 0.0}}, { 6, {4.0, 2.0}}};
-    NodeRefSegment s4{{ 7, {1.0, 0.0}}, { 8, {3.0, 2.0}}};
-    NodeRefSegment s5{{ 9, {0.0, 4.0}}, {10, {4.0, 0.0}}};
-    NodeRefSegment s6{{11, {0.0, 0.0}}, {12, {1.0, 1.0}}};
-    NodeRefSegment s7{{13, {1.0, 1.0}}, {14, {3.0, 3.0}}};
+    NodeRefSegment s1{{ 1, {0.0, 0.0}}, { 2, {2.0, 2.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s2{{ 3, {0.0, 2.0}}, { 4, {2.0, 0.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s3{{ 5, {2.0, 0.0}}, { 6, {4.0, 2.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s4{{ 7, {1.0, 0.0}}, { 8, {3.0, 2.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s5{{ 9, {0.0, 4.0}}, {10, {4.0, 0.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s6{{11, {0.0, 0.0}}, {12, {1.0, 1.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s7{{13, {1.0, 1.0}}, {14, {3.0, 3.0}}, role_type::unknown, nullptr};
 
     REQUIRE(calculate_intersection(s1, s2) == osmium::Location(1.0, 1.0));
     REQUIRE(calculate_intersection(s2, s1) == osmium::Location(1.0, 1.0));
@@ -66,15 +67,15 @@ TEST_CASE("Intersection of NodeRefSegments") {
 }
 
 TEST_CASE("Intersection of collinear NodeRefSegments") {
-    NodeRefSegment s1{{ 1, {0.0, 0.0}}, { 2, {2.0, 0.0}}}; // *---*
-    NodeRefSegment s2{{ 3, {2.0, 0.0}}, { 4, {4.0, 0.0}}}; //     *---*
-    NodeRefSegment s3{{ 5, {0.0, 0.0}}, { 6, {1.0, 0.0}}}; // *-*
-    NodeRefSegment s4{{ 7, {1.0, 0.0}}, { 8, {2.0, 0.0}}}; //   *-*
-    NodeRefSegment s5{{ 9, {1.0, 0.0}}, {10, {3.0, 0.0}}}; //   *---*
-    NodeRefSegment s6{{11, {0.0, 0.0}}, {12, {4.0, 0.0}}}; // *-------*
-    NodeRefSegment s7{{13, {0.0, 0.0}}, {14, {5.0, 0.0}}}; // *---------*
-    NodeRefSegment s8{{13, {1.0, 0.0}}, {14, {5.0, 0.0}}}; //   *-------*
-    NodeRefSegment s9{{13, {3.0, 0.0}}, {14, {4.0, 0.0}}}; //       *-*
+    NodeRefSegment s1{{ 1, {0.0, 0.0}}, { 2, {2.0, 0.0}}, role_type::unknown, nullptr}; // *---*
+    NodeRefSegment s2{{ 3, {2.0, 0.0}}, { 4, {4.0, 0.0}}, role_type::unknown, nullptr}; //     *---*
+    NodeRefSegment s3{{ 5, {0.0, 0.0}}, { 6, {1.0, 0.0}}, role_type::unknown, nullptr}; // *-*
+    NodeRefSegment s4{{ 7, {1.0, 0.0}}, { 8, {2.0, 0.0}}, role_type::unknown, nullptr}; //   *-*
+    NodeRefSegment s5{{ 9, {1.0, 0.0}}, {10, {3.0, 0.0}}, role_type::unknown, nullptr}; //   *---*
+    NodeRefSegment s6{{11, {0.0, 0.0}}, {12, {4.0, 0.0}}, role_type::unknown, nullptr}; // *-------*
+    NodeRefSegment s7{{13, {0.0, 0.0}}, {14, {5.0, 0.0}}, role_type::unknown, nullptr}; // *---------*
+    NodeRefSegment s8{{13, {1.0, 0.0}}, {14, {5.0, 0.0}}, role_type::unknown, nullptr}; //   *-------*
+    NodeRefSegment s9{{13, {3.0, 0.0}}, {14, {4.0, 0.0}}, role_type::unknown, nullptr}; //       *-*
 
     REQUIRE(calculate_intersection(s1, s1) == osmium::Location());
 
@@ -110,16 +111,16 @@ TEST_CASE("Intersection of collinear NodeRefSegments") {
 }
 
 TEST_CASE("Intersection of very long NodeRefSegments") {
-    NodeRefSegment s1{{1, {90.0, 90.0}}, {2, {-90.0, -90.0}}};
-    NodeRefSegment s2{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}};
+    NodeRefSegment s1{{1, {90.0, 90.0}}, {2, {-90.0, -90.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s2{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}, role_type::unknown, nullptr};
     REQUIRE(calculate_intersection(s1, s2) == osmium::Location(0.0, 0.0));
 
-    NodeRefSegment s3{{1, {-90.0, -90.0}}, {2, {90.0, 90.0}}};
-    NodeRefSegment s4{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}};
+    NodeRefSegment s3{{1, {-90.0, -90.0}}, {2, {90.0, 90.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s4{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}, role_type::unknown, nullptr};
     REQUIRE(calculate_intersection(s3, s4) == osmium::Location(0.0, 0.0));
 
-    NodeRefSegment s5{{1, {-90.00000001, -90.0}}, {2, {90.0, 90.0}}};
-    NodeRefSegment s6{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}};
+    NodeRefSegment s5{{1, {-90.00000001, -90.0}}, {2, {90.0, 90.0}}, role_type::unknown, nullptr};
+    NodeRefSegment s6{{1, {-90.0, 90.0}}, {2, {90.0, -90.0}}, role_type::unknown, nullptr};
     REQUIRE(calculate_intersection(s5, s6) == osmium::Location(0.0, 0.0));
 }
 
@@ -151,13 +152,13 @@ TEST_CASE("More ordering of NodeRefSegments") {
     osmium::NodeRef nr6{6, {2.0, 2.0}};
     osmium::NodeRef nr7{6, {1.0, 2.0}};
 
-    NodeRefSegment s1{nr0, nr1};
-    NodeRefSegment s2{nr0, nr2};
-    NodeRefSegment s3{nr0, nr3};
-    NodeRefSegment s4{nr0, nr4};
-    NodeRefSegment s5{nr0, nr5};
-    NodeRefSegment s6{nr0, nr6};
-    NodeRefSegment s7{nr0, nr7};
+    NodeRefSegment s1{nr0, nr1, role_type::unknown, nullptr};
+    NodeRefSegment s2{nr0, nr2, role_type::unknown, nullptr};
+    NodeRefSegment s3{nr0, nr3, role_type::unknown, nullptr};
+    NodeRefSegment s4{nr0, nr4, role_type::unknown, nullptr};
+    NodeRefSegment s5{nr0, nr5, role_type::unknown, nullptr};
+    NodeRefSegment s6{nr0, nr6, role_type::unknown, nullptr};
+    NodeRefSegment s7{nr0, nr7, role_type::unknown, nullptr};
 
     // s1
     REQUIRE_FALSE(s1 < s1);
diff --git a/test/t/io/data-nonl.opl b/test/t/io/data-nonl.opl
new file mode 100644
index 0000000..db23544
--- /dev/null
+++ b/test/t/io/data-nonl.opl
@@ -0,0 +1 @@
+n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02
\ No newline at end of file
diff --git a/test/t/io/data.opl b/test/t/io/data.opl
new file mode 100644
index 0000000..2c7e2a3
--- /dev/null
+++ b/test/t/io/data.opl
@@ -0,0 +1 @@
+n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02
diff --git a/test/t/io/test_opl_parser.cpp b/test/t/io/test_opl_parser.cpp
index e5d0df2..8e2cdb7 100644
--- a/test/t/io/test_opl_parser.cpp
+++ b/test/t/io/test_opl_parser.cpp
@@ -3,8 +3,10 @@
 #include <cstring>
 
 #include "catch.hpp"
+#include "utils.hpp"
 
 #include <osmium/io/detail/opl_input_format.hpp>
+#include <osmium/io/opl_input.hpp>
 #include <osmium/opl.hpp>
 
 namespace oid = osmium::io::detail;
@@ -1040,3 +1042,23 @@ TEST_CASE("Parse line with external interface") {
 
 }
 
+TEST_CASE("Parse OPL using Reader") {
+    osmium::io::File file{with_data_dir("t/io/data.opl")};
+    osmium::io::Reader reader{file};
+
+    const auto buffer = reader.read();
+    REQUIRE(buffer);
+    const auto& node = buffer.get<osmium::Node>(0);
+    REQUIRE(node.id() == 1);
+}
+
+TEST_CASE("Parse OPL with missing newline using Reader") {
+    osmium::io::File file{with_data_dir("t/io/data-nonl.opl")};
+    osmium::io::Reader reader{file};
+
+    const auto buffer = reader.read();
+    REQUIRE(buffer);
+    const auto& node = buffer.get<osmium::Node>(0);
+    REQUIRE(node.id() == 1);
+}
+
diff --git a/test/t/io/test_reader.cpp b/test/t/io/test_reader.cpp
index 1fef874..45c087d 100644
--- a/test/t/io/test_reader.cpp
+++ b/test/t/io/test_reader.cpp
@@ -58,7 +58,13 @@ TEST_CASE("Reader should throw after eof") {
     osmium::io::File file{with_data_dir("t/io/data.osm")};
     osmium::io::Reader reader{file};
 
-    REQUIRE(!reader.eof());
+    SECTION("Get header") {
+        const auto header = reader.header();
+        REQUIRE(header.get("generator") == "testdata");
+        REQUIRE_FALSE(reader.eof());
+    }
+
+    REQUIRE_FALSE(reader.eof());
 
     while (osmium::memory::Buffer buffer = reader.read()) {
     }
@@ -66,6 +72,9 @@ TEST_CASE("Reader should throw after eof") {
     REQUIRE(reader.eof());
 
     REQUIRE_THROWS_AS(reader.read(), osmium::io_error);
+
+    reader.close();
+    REQUIRE(reader.eof());
 }
 
 TEST_CASE("Reader should not hang when apply() is called twice on reader") {
@@ -196,3 +205,44 @@ TEST_CASE("Applying rvalue handler on reader") {
     osmium::apply(reader, NullHandler{});
 }
 
+TEST_CASE("Can call read() exactly once on Reader with entity_bits nothing") {
+    osmium::io::File file{with_data_dir("t/io/data.osm")};
+    osmium::io::Reader reader{file, osmium::osm_entity_bits::nothing};
+    REQUIRE_FALSE(reader.eof());
+
+    SECTION("Get header") {
+        const auto header = reader.header();
+        REQUIRE(header.get("generator") == "testdata");
+        REQUIRE_FALSE(reader.eof());
+    }
+
+    osmium::memory::Buffer buffer = reader.read();
+    REQUIRE_FALSE(buffer);
+    REQUIRE(reader.eof());
+    REQUIRE_THROWS_AS(reader.read(), osmium::io_error);
+
+    reader.close();
+    REQUIRE(reader.eof());
+}
+
+TEST_CASE("Can not read after close") {
+    osmium::io::File file{with_data_dir("t/io/data.osm")};
+    osmium::io::Reader reader{file};
+
+    SECTION("Get header") {
+        const auto header = reader.header();
+        REQUIRE(header.get("generator") == "testdata");
+        REQUIRE_FALSE(reader.eof());
+    }
+
+    REQUIRE_FALSE(reader.eof());
+
+    osmium::memory::Buffer buffer = reader.read();
+    REQUIRE(buffer);
+    REQUIRE_FALSE(reader.eof());
+
+    reader.close();
+    REQUIRE(reader.eof());
+    REQUIRE_THROWS_AS(reader.read(), osmium::io_error);
+}
+
diff --git a/test/t/io/test_reader_with_mock_parser.cpp b/test/t/io/test_reader_with_mock_parser.cpp
index 9ae1b7f..4076964 100644
--- a/test/t/io/test_reader_with_mock_parser.cpp
+++ b/test/t/io/test_reader_with_mock_parser.cpp
@@ -21,12 +21,9 @@ class MockParser : public osmium::io::detail::Parser {
 
 public:
 
-    MockParser(osmium::io::detail::future_string_queue_type& input_queue,
-               osmium::io::detail::future_buffer_queue_type& output_queue,
-               std::promise<osmium::io::Header>& header_promise,
-               osmium::io::detail::reader_options options,
+    MockParser(osmium::io::detail::parser_arguments& args,
                const std::string& fail_in) :
-        Parser(input_queue, output_queue, header_promise, options),
+        Parser(args),
         m_fail_in(fail_in) {
     }
 
@@ -56,11 +53,8 @@ TEST_CASE("Test Reader using MockParser") {
 
     osmium::io::detail::ParserFactory::instance().register_parser(
         osmium::io::file_format::xml,
-        [&](osmium::io::detail::future_string_queue_type& input_queue,
-            osmium::io::detail::future_buffer_queue_type& output_queue,
-            std::promise<osmium::io::Header>& header_promise,
-            osmium::io::detail::reader_options options) {
-        return std::unique_ptr<osmium::io::detail::Parser>(new MockParser(input_queue, output_queue, header_promise, options, fail_in));
+        [&](osmium::io::detail::parser_arguments& args) {
+        return std::unique_ptr<osmium::io::detail::Parser>(new MockParser(args, fail_in));
     });
 
     SECTION("no failure") {
diff --git a/test/t/io/test_writer_with_mock_encoder.cpp b/test/t/io/test_writer_with_mock_encoder.cpp
index af20dbe..8a0de76 100644
--- a/test/t/io/test_writer_with_mock_encoder.cpp
+++ b/test/t/io/test_writer_with_mock_encoder.cpp
@@ -52,7 +52,7 @@ TEST_CASE("Test Writer with MockOutputFormat") {
     osmium::io::detail::OutputFormatFactory::instance().register_output_format(
         osmium::io::file_format::xml,
         [&](const osmium::io::File& file, osmium::io::detail::future_string_queue_type& output_queue) {
-            return new MockOutputFormat(file, output_queue, fail_in);
+            return new MockOutputFormat{file, output_queue, fail_in};
     });
 
     osmium::io::Header header;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git



More information about the Pkg-grass-devel mailing list