Revert "fixing line endings"

This reverts commit dc75469e78.
This commit is contained in:
Dennis Luxen
2014-08-15 18:53:00 +02:00
parent dc75469e78
commit 5efa9664db
131 changed files with 0 additions and 21457 deletions
-242
View File
@@ -1,242 +0,0 @@
#ifndef OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
#define OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2014 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <iosfwd>
#include <utility>
#include <osmium/osm/location.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/util/operators.hpp>
namespace osmium {
class Way;
namespace area {
/**
* @brief Namespace for Osmium internal use
*/
namespace detail {
/**
* This helper class for the Assembler class models a segment.
* Segments are the connection between
* two nodes and they all have their smaller coordinate at the
* beginning of the segment. Smaller, in this case, means smaller x
* coordinate, and if they are the same smaller y coordinate.
*/
class NodeRefSegment : osmium::totally_ordered<NodeRefSegment> {
osmium::NodeRef m_first;
osmium::NodeRef m_second;
/// Role of the member this segment was from.
const char* m_role;
/// Way this segment was from.
const osmium::Way* m_way;
public:
void swap_locations() {
using std::swap;
swap(m_first, m_second);
}
explicit NodeRefSegment() :
m_first(),
m_second(),
m_role(nullptr),
m_way(nullptr) {
}
explicit NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, const char* role, const osmium::Way* way) :
m_first(nr1),
m_second(nr2),
m_role(role),
m_way(way) {
if (nr2.location() < nr1.location()) {
swap_locations();
}
}
NodeRefSegment(const NodeRefSegment&) = default;
NodeRefSegment(NodeRefSegment&&) = default;
NodeRefSegment& operator=(const NodeRefSegment&) = default;
NodeRefSegment& operator=(NodeRefSegment&&) = default;
~NodeRefSegment() = default;
/// Return first NodeRef of Segment according to sorting order (bottom left to top right).
const osmium::NodeRef& first() const {
return m_first;
}
/// Return second NodeRef of Segment according to sorting order (bottom left to top right).
const osmium::NodeRef& second() const {
return m_second;
}
bool to_left_of(const osmium::Location location) const {
// std::cerr << "segment " << first() << "--" << second() << " to_left_of(" << location << "\n";
if (first().location() == location || second().location() == location) {
return false;
}
const std::pair<osmium::Location, osmium::Location> mm = std::minmax(first().location(), second().location(), [](const osmium::Location a, const osmium::Location b) {
return a.y() < b.y();
});
if (mm.first.y() >= location.y() || mm.second.y() < location.y() || first().location().x() > location.x()) {
// std::cerr << " false\n";
return false;
}
int64_t ax = mm.first.x();
int64_t bx = mm.second.x();
int64_t lx = location.x();
int64_t ay = mm.first.y();
int64_t by = mm.second.y();
int64_t ly = location.y();
return ((bx - ax)*(ly - ay) - (by - ay)*(lx - ax)) <= 0;
}
bool role_outer() const {
return !strcmp(m_role, "outer");
}
bool role_inner() const {
return !strcmp(m_role, "inner");
}
const osmium::Way* way() const {
return m_way;
}
}; // class NodeRefSegment
/// NodeRefSegments are equal if both their locations are equal
inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) {
return lhs.first().location() == rhs.first().location() && lhs.second().location() == rhs.second().location();
}
/**
* NodeRefSegments are "smaller" if they are to the left and down of another
* segment. The first() location is checked first() and only if they have the
* same first() location the second() location is taken into account.
*/
inline bool operator<(const NodeRefSegment& lhs, const NodeRefSegment& rhs) {
return (lhs.first().location() == rhs.first().location() && lhs.second().location() < rhs.second().location()) || lhs.first().location() < rhs.first().location();
}
template <typename TChar, typename TTraits>
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const NodeRefSegment& segment) {
return out << segment.first() << "--" << segment.second();
}
inline bool outside_x_range(const NodeRefSegment& s1, const NodeRefSegment& s2) {
if (s1.first().location().x() > s2.second().location().x()) {
return true;
}
return false;
}
inline bool y_range_overlap(const NodeRefSegment& s1, const NodeRefSegment& s2) {
auto m1 = std::minmax(s1.first().location().y(), s1.second().location().y());
auto m2 = std::minmax(s2.first().location().y(), s2.second().location().y());
if (m1.first > m2.second || m2.first > m1.second) {
return false;
}
return true;
}
/**
* Calculate the intersection between to NodeRefSegments. The result is returned
* as a Location. Note that because the Location uses integers with limited
* precision internally, the result might be slightly different than the
* numerically correct location.
*
* If the segments touch in one of their endpoints, it doesn't count as an
* intersection.
*
* If the segments intersect not in a single point but in multiple points, ie
* if they overlap, this is NOT detected.
*
* @returns Undefined osmium::Location if there is no intersection or a defined
* Location if the segments intersect.
*/
inline osmium::Location calculate_intersection(const NodeRefSegment& s1, const NodeRefSegment& s2) {
if (s1.first().location() == s2.first().location() ||
s1.first().location() == s2.second().location() ||
s1.second().location() == s2.first().location() ||
s1.second().location() == s2.second().location()) {
return osmium::Location();
}
double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) -
((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat()));
if (denom != 0) {
double nume_a = ((s2.second().lon() - s2.first().lon())*(s1.first().lat() - s2.first().lat())) -
((s2.second().lat() - s2.first().lat())*(s1.first().lon() - s2.first().lon()));
double nume_b = ((s1.second().lon() - s1.first().lon())*(s1.first().lat() - s2.first().lat())) -
((s1.second().lat() - s1.first().lat())*(s1.first().lon() - s2.first().lon()));
if ((denom > 0 && nume_a >= 0 && nume_a <= denom && nume_b >= 0 && nume_b <= denom) ||
(denom < 0 && nume_a <= 0 && nume_a >= denom && nume_b <= 0 && nume_b >= denom)) {
double ua = nume_a / denom;
double ix = s1.first().lon() + ua*(s1.second().lon() - s1.first().lon());
double iy = s1.first().lat() + ua*(s1.second().lat() - s1.first().lat());
return osmium::Location(ix, iy);
}
}
return osmium::Location();
}
} // namespace detail
} // namespace area
} // namespace osmium
#endif // OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
-274
View File
@@ -1,274 +0,0 @@
#ifndef OSMIUM_AREA_DETAIL_PROTO_RING_HPP
#define OSMIUM_AREA_DETAIL_PROTO_RING_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2014 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <cassert>
#include <iostream>
#include <list>
#include <set>
#include <vector>
#include <osmium/osm/node_ref.hpp>
#include <osmium/area/detail/node_ref_segment.hpp>
namespace osmium {
namespace area {
namespace detail {
/**
* A ring in the process of being built by the Assembler object.
*/
class ProtoRing {
public:
typedef std::vector<NodeRefSegment> segments_type;
private:
// segments in this ring
segments_type m_segments;
bool m_outer {true};
// if this is an outer ring, these point to it's inner rings (if any)
std::vector<ProtoRing*> m_inner {};
public:
explicit ProtoRing(const NodeRefSegment& segment) :
m_segments() {
add_segment_back(segment);
}
explicit ProtoRing(segments_type::const_iterator sbegin, segments_type::const_iterator send) :
m_segments(static_cast<size_t>(std::distance(sbegin, send))) {
std::copy(sbegin, send, m_segments.begin());
}
bool outer() const {
return m_outer;
}
void set_inner() {
m_outer = false;
}
segments_type& segments() {
return m_segments;
}
const segments_type& segments() const {
return m_segments;
}
void remove_segments(segments_type::iterator sbegin, segments_type::iterator send) {
m_segments.erase(sbegin, send);
}
void add_segment_front(const NodeRefSegment& segment) {
m_segments.insert(m_segments.begin(), segment);
}
void add_segment_back(const NodeRefSegment& segment) {
m_segments.push_back(segment);
}
const NodeRefSegment& get_segment_front() const {
return m_segments.front();
}
NodeRefSegment& get_segment_front() {
return m_segments.front();
}
const NodeRefSegment& get_segment_back() const {
return m_segments.back();
}
NodeRefSegment& get_segment_back() {
return m_segments.back();
}
bool closed() const {
return m_segments.front().first().location() == m_segments.back().second().location();
}
int64_t sum() const {
int64_t sum = 0;
for (const auto& segment : m_segments) {
sum += static_cast<int64_t>(segment.first().location().x()) * static_cast<int64_t>(segment.second().location().y()) -
static_cast<int64_t>(segment.second().location().x()) * static_cast<int64_t>(segment.first().location().y());
}
return sum;
}
bool is_cw() const {
return sum() <= 0;
}
int64_t area() const {
return std::abs(sum()) / 2;
}
void swap_segments(ProtoRing& other) {
std::swap(m_segments, other.m_segments);
}
void add_inner_ring(ProtoRing* ring) {
m_inner.push_back(ring);
}
const std::vector<ProtoRing*> inner_rings() const {
return m_inner;
}
void print(std::ostream& out) const {
out << "[";
bool first = true;
for (const auto& segment : m_segments) {
if (first) {
out << segment.first().ref();
}
out << ',' << segment.second().ref();
first = false;
}
out << "]";
}
void reverse() {
std::for_each(m_segments.begin(), m_segments.end(), [](NodeRefSegment& segment) {
segment.swap_locations();
});
std::reverse(m_segments.begin(), m_segments.end());
}
/**
* Merge other ring to end of this ring.
*/
void merge_ring(const ProtoRing& other, bool debug) {
if (debug) {
std::cerr << " MERGE rings ";
print(std::cerr);
std::cerr << " to ";
other.print(std::cerr);
std::cerr << "\n";
}
m_segments.insert(m_segments.end(), other.m_segments.begin(), other.m_segments.end());
if (debug) {
std::cerr << " result ring: ";
print(std::cerr);
std::cerr << "\n";
}
}
void merge_ring_reverse(const ProtoRing& other, bool debug) {
if (debug) {
std::cerr << " MERGE rings (reverse) ";
print(std::cerr);
std::cerr << " to ";
other.print(std::cerr);
std::cerr << "\n";
}
size_t n = m_segments.size();
m_segments.resize(n + other.m_segments.size());
std::transform(other.m_segments.rbegin(), other.m_segments.rend(), m_segments.begin() + static_cast<segments_type::difference_type>(n), [](NodeRefSegment segment) {
segment.swap_locations();
return segment;
});
if (debug) {
std::cerr << " result ring: ";
print(std::cerr);
std::cerr << "\n";
}
}
const NodeRef& min_node() const {
auto it = std::min_element(m_segments.begin(), m_segments.end());
if (location_less()(it->first(), it->second())) {
return it->first();
} else {
return it->second();
}
}
bool is_in(ProtoRing* outer) {
osmium::Location testpoint = segments().front().first().location();
bool is_in = false;
for (size_t i = 0, j = outer->segments().size()-1; i < outer->segments().size(); j = i++) {
if (((outer->segments()[i].first().location().y() > testpoint.y()) != (outer->segments()[j].first().location().y() > testpoint.y())) &&
(testpoint.x() < (outer->segments()[j].first().location().x() - outer->segments()[i].first().location().x()) * (testpoint.y() - outer->segments()[i].first().location().y()) / (outer->segments()[j].first().location().y() - outer->segments()[i].first().location().y()) + outer->segments()[i].first().location().x()) ) {
is_in = !is_in;
}
}
return is_in;
}
void get_ways(std::set<const osmium::Way*>& ways) {
for (const auto& segment : m_segments) {
ways.insert(segment.way());
}
}
bool contains(const NodeRefSegment& segment) const {
for (const auto& s : m_segments) {
if (s == segment || (s.first() == segment.second() && s.second() == segment.first())) {
return true;
}
}
return false;
}
}; // class ProtoRing
template <typename TChar, typename TTraits>
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const ProtoRing& ring) {
ring.print(out);
return out;
}
} // namespace detail
} // namespace area
} // namespace osmium
#endif // OSMIUM_AREA_DETAIL_PROTO_RING_HPP
-216
View File
@@ -1,216 +0,0 @@
#ifndef OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
#define OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2014 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#include <osmium/area/problem_reporter.hpp>
#include <osmium/area/detail/node_ref_segment.hpp>
#include <osmium/memory/buffer.hpp>
#include <osmium/osm/relation.hpp>
#include <osmium/osm/way.hpp>
namespace osmium {
namespace area {
namespace detail {
/**
* This is a helper class for the area assembler. It models
* a list of segments.
*/
class SegmentList {
typedef std::vector<NodeRefSegment> slist_type;
slist_type m_segments {};
bool m_debug;
public:
explicit SegmentList(bool debug) :
m_debug(debug) {
}
~SegmentList() = default;
SegmentList(const SegmentList& other) = delete;
SegmentList(SegmentList&& other) = delete;
SegmentList& operator=(const SegmentList& other) = delete;
SegmentList& operator=(SegmentList&& other) = delete;
/// The number of segments in the list.
size_t size() const {
return m_segments.size();
}
bool empty() const {
return m_segments.empty();
}
typedef slist_type::const_iterator const_iterator;
const_iterator begin() const {
return m_segments.begin();
}
const_iterator end() const {
return m_segments.end();
}
/**
* Enable or disable debug output to stderr. This is for Osmium
* developers only.
*/
void enable_debug_output(bool debug=true) {
m_debug = debug;
}
/// Clear the list of segments. All segments are removed.
void clear() {
m_segments.clear();
}
/// Sort the list of segments.
void sort() {
std::sort(m_segments.begin(), m_segments.end());
}
/**
* Extract segments from given way and add them to the list.
*
* Segments connecting two nodes with the same location (ie same
* node or different node with same location) are removed.
*
* XXX should two nodes with same location be reported?
*/
void extract_segments_from_way(const osmium::Way& way, const char* role) {
osmium::NodeRef last_nr;
for (const osmium::NodeRef& nr : way.nodes()) {
if (last_nr.location() && last_nr.location() != nr.location()) {
m_segments.emplace_back(last_nr, nr, role, &way);
}
last_nr = nr;
}
}
/**
* Extract all segments from all ways that make up this
* multipolygon relation and add them to the list.
*/
void extract_segments_from_ways(const osmium::Relation& relation, const std::vector<size_t>& members, const osmium::memory::Buffer& in_buffer) {
auto member_it = relation.members().begin();
for (size_t offset : members) {
const osmium::Way& way = in_buffer.get<const osmium::Way>(offset);
extract_segments_from_way(way, member_it->role());
++member_it;
}
}
/**
* Find duplicate segments (ie same start and end point) in the
* list and remove them. This will always remove pairs of the same
* segment. So if there are three, for instance, two will be
* removed and one will be left.
*/
void erase_duplicate_segments() {
while (true) {
auto it = std::adjacent_find(m_segments.begin(), m_segments.end());
if (it == m_segments.end()) {
return;
}
if (m_debug) {
std::cerr << " erase duplicate segment: " << *it << "\n";
}
m_segments.erase(it, it+2);
}
}
/**
* Find intersection between segments.
*
* @param problem_reporter Any intersections found are reported to this object.
* @returns true if there are intersections.
*/
bool find_intersections(osmium::area::ProblemReporter* problem_reporter) const {
if (m_segments.empty()) {
return false;
}
bool found_intersections = false;
for (auto it1 = m_segments.begin(); it1 != m_segments.end()-1; ++it1) {
const NodeRefSegment& s1 = *it1;
for (auto it2 = it1+1; it2 != m_segments.end(); ++it2) {
const NodeRefSegment& s2 = *it2;
assert(s1 != s2); // erase_duplicate_segments() should have made sure of that
if (outside_x_range(s2, s1)) {
break;
}
if (y_range_overlap(s1, s2)) {
osmium::Location intersection = calculate_intersection(s1, s2);
if (intersection) {
found_intersections = true;
if (m_debug) {
std::cerr << " segments " << s1 << " and " << s2 << " intersecting at " << intersection << "\n";
}
if (problem_reporter) {
problem_reporter->report_intersection(s1.way()->id(), s1.first().location(), s1.second().location(), s2.way()->id(), s2.first().location(), s2.second().location(), intersection);
}
}
}
}
}
return found_intersections;
}
}; // class SegmentList
} // namespace detail
} // namespace area
} // namespace osmium
#endif // OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP