get rid of libboost dependency

This commit is contained in:
Patrick Brosi 2018-07-15 14:13:31 +02:00
parent 4674f0f116
commit d387314715
18 changed files with 282 additions and 104 deletions

View file

@ -13,9 +13,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/build") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/build")
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories("build" ${Boost_INCLUDE_DIRS})
find_package(OpenMP) find_package(OpenMP)
if(OPENMP_FOUND) if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")

View file

@ -19,7 +19,6 @@ Precise map-matching for public transit schedules (GTFS data).
* `cmake` * `cmake`
* `gcc` >= 4.8 * `gcc` >= 4.8
* `libboost-system` >= 1.56, `libboost-filesystem` >= 1.56, `libboost-geometry` >= 1.56
## Building and Installation ## Building and Installation

@ -1 +1 @@
Subproject commit 7c395530d3c5b2d5c147fdabaaeeb0d1babceb04 Subproject commit 8d255970a97c31891277f63ba8b39a3ea2b7e133

View file

@ -118,8 +118,8 @@ double Collector::add(const Trip* t, const Shape* oldS, const Shape* newS,
gjout.flush(); gjout.flush();
fstr.close(); fstr.close();
double fac = cos(2 * atan(exp((oldSegs.front().front().get<1>() + double fac = cos(2 * atan(exp((oldSegs.front().front().getY() +
oldSegs.back().back().get<1>()) / oldSegs.back().back().getY()) /
6378137.0)) - 6378137.0)) -
1.5707965); 1.5707965);
@ -401,7 +401,7 @@ std::pair<size_t, double> Collector::getDa(const std::vector<FLine>& a,
// euclidean distance on web mercator is in meters on equator, // euclidean distance on web mercator is in meters on equator,
// and proportional to cos(lat) in both y directions // and proportional to cos(lat) in both y directions
double fac = double fac =
cos(2 * atan(exp((a.front().front().get<1>() + a.back().back().get<1>()) / cos(2 * atan(exp((a.front().front().getY() + a.back().back().getY()) /
6378137.0)) - 6378137.0)) -
1.5707965); 1.5707965);

View file

@ -31,10 +31,10 @@ bool BBoxIdx::contains(const Point<float>& p) const {
// _____________________________________________________________________________ // _____________________________________________________________________________
util::geo::Box<float> BBoxIdx::getFullWebMercBox() const { util::geo::Box<float> BBoxIdx::getFullWebMercBox() const {
return util::geo::FBox( return util::geo::FBox(
util::geo::latLngToWebMerc<float>(_root.box.min_corner().get<1>(), util::geo::latLngToWebMerc<float>(_root.box.getLowerLeft().getY(),
_root.box.min_corner().get<0>()), _root.box.getLowerLeft().getX()),
util::geo::latLngToWebMerc<float>(_root.box.max_corner().get<1>(), util::geo::latLngToWebMerc<float>(_root.box.getUpperRight().getY(),
_root.box.max_corner().get<0>())); _root.box.getUpperRight().getX()));
} }
// _____________________________________________________________________________ // _____________________________________________________________________________

View file

@ -991,7 +991,7 @@ double OsmBuilder::webMercDistFactor(const util::geo::FPoint& a) const {
// euclidean distance on web mercator is in meters on equator, // euclidean distance on web mercator is in meters on equator,
// and proportional to cos(lat) in both y directions // and proportional to cos(lat) in both y directions
double lat = 2 * atan(exp(a.get<1>() / 6378137.0)) - 1.5707965; double lat = 2 * atan(exp(a.getY() / 6378137.0)) - 1.5707965;
return cos(lat); return cos(lat);
} }

View file

@ -121,8 +121,8 @@ NDistHeur::NDistHeur(const RoutingOpts& rOpts,
size_t c = 0; size_t c = 0;
double x = 0, y = 0; double x = 0, y = 0;
for (auto to : tos) { for (auto to : tos) {
x += to->pl().getGeom()->get<0>(); x += to->pl().getGeom()->getX();
y += to->pl().getGeom()->get<1>(); y += to->pl().getGeom()->getY();
c++; c++;
} }
@ -144,8 +144,8 @@ DistHeur::DistHeur(uint8_t minLvl, const RoutingOpts& rOpts,
size_t c = 0; size_t c = 0;
double x = 0, y = 0; double x = 0, y = 0;
for (auto to : tos) { for (auto to : tos) {
x += to->getFrom()->pl().getGeom()->get<0>(); x += to->getFrom()->pl().getGeom()->getX();
y += to->getFrom()->pl().getGeom()->get<1>(); y += to->getFrom()->pl().getGeom()->getY();
c++; c++;
} }

View file

@ -313,8 +313,8 @@ ad::cppgtfs::gtfs::Shape* ShapeBuilder::getGtfsShape(
for (const auto& hop : shp.hops) { for (const auto& hop : shp.hops) {
const trgraph::Node* l = hop.start; const trgraph::Node* l = hop.start;
if (hop.edges.size() == 0) { if (hop.edges.size() == 0) {
FPoint ll = webMercToLatLng<float>(hop.start->pl().getGeom()->get<0>(), FPoint ll = webMercToLatLng<float>(hop.start->pl().getGeom()->getX(),
hop.start->pl().getGeom()->get<1>()); hop.start->pl().getGeom()->getY());
if (dist > -0.5) if (dist > -0.5)
dist += webMercMeterDist(last, *hop.start->pl().getGeom()); dist += webMercMeterDist(last, *hop.start->pl().getGeom());
@ -324,7 +324,7 @@ ad::cppgtfs::gtfs::Shape* ShapeBuilder::getGtfsShape(
last = *hop.start->pl().getGeom(); last = *hop.start->pl().getGeom();
if (dist - lastDist > 0.01) { if (dist - lastDist > 0.01) {
ret->addPoint(ShapePoint(ll.get<1>(), ll.get<0>(), dist, seq)); ret->addPoint(ShapePoint(ll.getY(), ll.getX(), dist, seq));
seq++; seq++;
lastDist = dist; lastDist = dist;
} }
@ -333,9 +333,9 @@ ad::cppgtfs::gtfs::Shape* ShapeBuilder::getGtfsShape(
last = *hop.end->pl().getGeom(); last = *hop.end->pl().getGeom();
if (dist - lastDist > 0.01) { if (dist - lastDist > 0.01) {
ll = webMercToLatLng<float>(hop.end->pl().getGeom()->get<0>(), ll = webMercToLatLng<float>(hop.end->pl().getGeom()->getX(),
hop.end->pl().getGeom()->get<1>()); hop.end->pl().getGeom()->getY());
ret->addPoint(ShapePoint(ll.get<1>(), ll.get<0>(), dist, seq)); ret->addPoint(ShapePoint(ll.getY(), ll.getX(), dist, seq));
seq++; seq++;
lastDist = dist; lastDist = dist;
} }
@ -351,8 +351,8 @@ ad::cppgtfs::gtfs::Shape* ShapeBuilder::getGtfsShape(
dist = 0; dist = 0;
last = cur; last = cur;
if (dist - lastDist > 0.01) { if (dist - lastDist > 0.01) {
FPoint ll = webMercToLatLng<float>(cur.get<0>(), cur.get<1>()); FPoint ll = webMercToLatLng<float>(cur.getX(), cur.getY());
ret->addPoint(ShapePoint(ll.get<1>(), ll.get<0>(), dist, seq)); ret->addPoint(ShapePoint(ll.getY(), ll.getX(), dist, seq));
seq++; seq++;
lastDist = dist; lastDist = dist;
} }
@ -366,8 +366,8 @@ ad::cppgtfs::gtfs::Shape* ShapeBuilder::getGtfsShape(
dist = 0; dist = 0;
last = cur; last = cur;
if (dist - lastDist > 0.01) { if (dist - lastDist > 0.01) {
FPoint ll = webMercToLatLng<float>(cur.get<0>(), cur.get<1>()); FPoint ll = webMercToLatLng<float>(cur.getX(), cur.getY());
ret->addPoint(ShapePoint(ll.get<1>(), ll.get<0>(), dist, seq)); ret->addPoint(ShapePoint(ll.getY(), ll.getX(), dist, seq));
seq++; seq++;
lastDist = dist; lastDist = dist;
} }

View file

@ -5,6 +5,7 @@
#ifndef UTIL_MISC_H_ #ifndef UTIL_MISC_H_
#define UTIL_MISC_H_ #define UTIL_MISC_H_
#include <cmath>
#include <chrono> #include <chrono>
#define UNUSED(expr) do { (void)(expr); } while (0) #define UNUSED(expr) do { (void)(expr); } while (0)

View file

@ -15,15 +15,15 @@ BezierCurve<T>::BezierCurve(const Point<T>& a, const Point<T>& b,
template <typename T> template <typename T>
void BezierCurve<T>::recalcPolynoms(const Point<T>& a, const Point<T>& b, void BezierCurve<T>::recalcPolynoms(const Point<T>& a, const Point<T>& b,
const Point<T>& c, const Point<T>& d) { const Point<T>& c, const Point<T>& d) {
_xp.a = a.template get<0>(); _xp.a = a.getX();
_xp.b = 3.0 * (b.template get<0>() - a.template get<0>()); _xp.b = 3.0 * (b.getX() - a.getX());
_xp.c = 3.0 * (c.template get<0>() - b.template get<0>()) - _xp.b; _xp.c = 3.0 * (c.getX() - b.getX()) - _xp.b;
_xp.d = d.template get<0>() - a.template get<0>() - _xp.c - _xp.b; _xp.d = d.getX() - a.getX() - _xp.c - _xp.b;
_yp.a = a.template get<1>(); _yp.a = a.getY();
_yp.b = 3.0 * (b.template get<1>() - a.template get<1>()); _yp.b = 3.0 * (b.getY() - a.getY());
_yp.c = 3.0 * (c.template get<1>() - b.template get<1>()) - _yp.b; _yp.c = 3.0 * (c.getY() - b.getY()) - _yp.b;
_yp.d = d.template get<1>() - a.template get<1>() - _yp.c - _yp.b; _yp.d = d.getY() - a.getY() - _yp.c - _yp.b;
_didRender = false; _didRender = false;
} }

View file

@ -6,11 +6,13 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <sstream>
#include <math.h> #include <math.h>
#include "util/Misc.h" #include "util/Misc.h"
#include "util/geo/Box.h" #include "util/geo/Box.h"
#include "util/geo/Line.h" #include "util/geo/Line.h"
#include "util/geo/Point.h" #include "util/geo/Point.h"
#include "util/geo/Polygon.h"
// ------------------- // -------------------
// Geometry stuff // Geometry stuff
@ -37,11 +39,11 @@ typedef Box<double> DBox;
typedef Box<float> FBox; typedef Box<float> FBox;
typedef Box<int> IBox; typedef Box<int> IBox;
const static double EPSILON = 0.0000001; typedef Polygon<double> DPolygon;
typedef Polygon<float> FPolygon;
typedef Polygon<int> IPolygon;
// typedef Polygon<double> DPolygon; const static double EPSILON = 0.0000001;
// typedef Polygon<float> FPolygon;
// typedef Polygon<int> IPolygon;
// _____________________________________________________________________________ // _____________________________________________________________________________
// template <typename T> // template <typename T>
@ -224,6 +226,32 @@ inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
((crossProd(ls2.first, ls1) < 0) ^ (crossProd(ls2.second, ls1) < 0))); ((crossProd(ls2.first, ls1) < 0) ^ (crossProd(ls2.second, ls1) < 0)));
} }
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Line<T>& ls1, const Line<T>& ls2) {
for (size_t i = 1; i < ls1.size(); i++) {
for (size_t j = 1; j < ls2.size(); j++) {
if (intersects(LineSegment<T>(ls1[i - 1], ls1[i]),
LineSegment<T>(ls2[j - 1], ls2[j])))
return true;
}
}
return false;
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Line<T>& l, const Point<T>& p) {
return contains(l, p);
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Point<T>& p, const Line<T>& l) {
return intersects(l, p);
}
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline bool intersects(const Box<T>& b1, const Box<T>& b2) { inline bool intersects(const Box<T>& b1, const Box<T>& b2) {
@ -256,6 +284,12 @@ inline bool intersects(const LineSegment<T>& ls, const Box<T>& b) {
return contains(ls, b); return contains(ls, b);
} }
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Box<T>& b, const LineSegment<T>& ls) {
return intersects(ls, b);
}
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline bool intersects(const Line<T>& l, const Box<T>& b) { inline bool intersects(const Line<T>& l, const Box<T>& b) {
@ -265,6 +299,24 @@ inline bool intersects(const Line<T>& l, const Box<T>& b) {
return false; return false;
} }
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Box<T>& b, const Line<T>& l) {
return intersects(l, b);
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Point<T>& p, const Box<T>& b) {
return contains(p, b);
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Box<T>& b, const Point<T>& p) {
return intersects(p, b);
}
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline Point<T> intersection(T p1x, T p1y, T q1x, T q1y, T p2x, T p2y, T q2x, inline Point<T> intersection(T p1x, T p1y, T q1x, T q1y, T p2x, T p2y, T q2x,
@ -378,8 +430,7 @@ inline double crossProd(const Point<T>& p, const LineSegment<T>& ls) {
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline double dist(const Point<T>& p1, const Point<T>& p2) { inline double dist(const Point<T>& p1, const Point<T>& p2) {
return sqrt((p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) + return dist(p1.getX(), p1.getY(), p2.getX(), p2.getY());
(p1.getY() - p2.getY()) * (p1.getY() - p2.getY()));
} }
// _____________________________________________________________________________ // _____________________________________________________________________________
@ -399,6 +450,34 @@ inline std::string getWKT(const Line<T>& l) {
if (i) ss << ", "; if (i) ss << ", ";
ss << l[i].getX() << " " << l[i].getY(); ss << l[i].getX() << " " << l[i].getY();
} }
ss << ")";
return ss.str();
}
// _____________________________________________________________________________
template <typename T>
inline std::string getWKT(const Box<T>& l) {
std::stringstream ss;
ss << "POLYGON ((";
ss << l.getLowerLeft().getX() << " " << l.getLowerLeft().getY();
ss << ", " << l.getUpperRight().getX() << " " << l.getLowerLeft().getY();
ss << ", " << l.getUpperRight().getX() << " " << l.getUpperRight().getY();
ss << ", " << l.getLowerLeft().getX() << " " << l.getUpperRight().getY();
ss << ", " << l.getLowerLeft().getX() << " " << l.getLowerLeft().getY();
ss << "))";
return ss.str();
}
// _____________________________________________________________________________
template <typename T>
inline std::string getWKT(const Polygon<T>& p) {
std::stringstream ss;
ss << "POLYGON ((";
for (size_t i = 0; i < p.getOuter().size(); i++) {
if (i) ss << ", ";
ss << p.getOuter()[i].getX() << " " << p.getOuter()[i].getY();
}
ss << "))";
return ss.str(); return ss.str();
} }
@ -424,10 +503,41 @@ inline Point<T> simplify(const Point<T>& g, double d) {
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline Line<T> simplify(const Line<T>& g, double d) { inline LineSegment<T> simplify(const LineSegment<T>& g, double d) {
return g; return g;
} }
// _____________________________________________________________________________
template <typename T>
inline Box<T> simplify(const Box<T>& g, double d) {
return g;
}
// _____________________________________________________________________________
template <typename T>
inline Line<T> simplify(const Line<T>& g, double d) {
// douglas peucker
double maxd = 0;
size_t maxi = 0;
for (size_t i = 1; i < g.size() - 1; i++) {
double dt = distToSegment(g.front(), g.back(), g[i]);
if (dt > maxd) {
maxi = i;
maxd = dt;
}
}
if (maxd > d) {
auto a = simplify(Line<T>(g.begin(), g.begin() + maxi + 1), d);
const auto& b = simplify(Line<T>(g.begin() + maxi, g.end()), d);
a.insert(a.end(), b.begin() + 1, b.end());
return a;
}
return Line<T>{g.front(), g.back()};
}
// _____________________________________________________________________________ // _____________________________________________________________________________
inline double distToSegment(double lax, double lay, double lbx, double lby, inline double distToSegment(double lax, double lay, double lbx, double lby,
double px, double py) { double px, double py) {
@ -453,6 +563,13 @@ inline double distToSegment(const Point<T>& la, const Point<T>& lb,
p.getY()); p.getY());
} }
// _____________________________________________________________________________
template <typename T>
inline double distToSegment(const LineSegment<T>& ls, const Point<T>& p) {
return distToSegment(ls.first.getX(), ls.first.getY(), ls.second.getX(),
ls.second.getY(), p.getX(), p.getY());
}
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename T> template <typename T>
inline Point<T> projectOn(const Point<T>& a, const Point<T>& b, inline Point<T> projectOn(const Point<T>& a, const Point<T>& b,
@ -591,7 +708,7 @@ inline Box<T> getBoundingBox(const Point<T>& p) {
template <typename T> template <typename T>
inline Box<T> getBoundingBox(const Line<T>& l) { inline Box<T> getBoundingBox(const Line<T>& l) {
Box<T> ret; Box<T> ret;
for (const auto& p : l) extendBox(p, ret); for (const auto& p : l) ret = extendBox(p, ret);
return ret; return ret;
} }

View file

@ -30,9 +30,9 @@ Grid<V, G, T>::Grid(double w, double h, const Box<T>& bbox, bool bValIdx)
_bb(bbox), _bb(bbox),
_hasValIdx(bValIdx) { _hasValIdx(bValIdx) {
_width = _width =
bbox.getUpperRight().template getX() - bbox.getLowerLeft().template getX(); bbox.getUpperRight().getX() - bbox.getLowerLeft().getX();
_height = _height =
bbox.getUpperRight().template getY() - bbox.getLowerLeft().template getY(); bbox.getUpperRight().getY() - bbox.getLowerLeft().getY();
if (_width < 0 || _height < 0) { if (_width < 0 || _height < 0) {
_width = 0; _width = 0;
@ -58,11 +58,11 @@ Grid<V, G, T>::Grid(double w, double h, const Box<T>& bbox, bool bValIdx)
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
void Grid<V, G, T>::add(G<T> geom, V val) { void Grid<V, G, T>::add(G<T> geom, V val) {
Box<T> box = getBoundingBox(geom); Box<T> box = getBoundingBox(geom);
size_t swX = getCellXFromX(box.getLowerLeft().template getX()); size_t swX = getCellXFromX(box.getLowerLeft().getX());
size_t swY = getCellYFromY(box.getLowerLeft().template getY()); size_t swY = getCellYFromY(box.getLowerLeft().getY());
size_t neX = getCellXFromX(box.getUpperRight().template getX()); size_t neX = getCellXFromX(box.getUpperRight().getX());
size_t neY = getCellYFromY(box.getUpperRight().template getY()); size_t neY = getCellYFromY(box.getUpperRight().getY());
for (size_t x = swX; x <= neX && x < _grid.size(); x++) { for (size_t x = swX; x <= neX && x < _grid.size(); x++) {
for (size_t y = swY; y <= neY && y < _grid[x].size(); y++) { for (size_t y = swY; y <= neY && y < _grid[x].size(); y++) {
@ -83,11 +83,11 @@ void Grid<V, G, T>::add(size_t x, size_t y, V val) {
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
void Grid<V, G, T>::get(const Box<T>& box, std::set<V>* s) const { void Grid<V, G, T>::get(const Box<T>& box, std::set<V>* s) const {
size_t swX = getCellXFromX(box.getLowerLeft().template getX()); size_t swX = getCellXFromX(box.getLowerLeft().getX());
size_t swY = getCellYFromY(box.getLowerLeft().template getY()); size_t swY = getCellYFromY(box.getLowerLeft().getY());
size_t neX = getCellXFromX(box.getUpperRight().template getX()); size_t neX = getCellXFromX(box.getUpperRight().getX());
size_t neY = getCellYFromY(box.getUpperRight().template getY()); size_t neY = getCellYFromY(box.getUpperRight().getY());
for (size_t x = swX; x <= neX && x >= 0 && x < _xWidth; x++) for (size_t x = swX; x <= neX && x >= 0 && x < _xWidth; x++)
for (size_t y = swY; y <= neY && y >= 0 && y < _yHeight; y++) get(x, y, s); for (size_t y = swY; y <= neY && y >= 0 && y < _yHeight; y++) get(x, y, s);
@ -97,10 +97,10 @@ void Grid<V, G, T>::get(const Box<T>& box, std::set<V>* s) const {
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
void Grid<V, G, T>::get(const G<T>& geom, double d, std::set<V>* s) const { void Grid<V, G, T>::get(const G<T>& geom, double d, std::set<V>* s) const {
Box<T> a = getBoundingBox(geom); Box<T> a = getBoundingBox(geom);
Box<T> b(Point<T>(a.getLowerLeft().template getX() - d, Box<T> b(Point<T>(a.getLowerLeft().getX() - d,
a.getLowerLeft().template getY() - d), a.getLowerLeft().getY() - d),
Point<T>(a.getUpperRight().template getX() + d, Point<T>(a.getUpperRight().getX() + d,
a.getUpperRight().template getY() + d)); a.getUpperRight().getY() + d));
return get(b, s); return get(b, s);
} }
@ -192,17 +192,17 @@ std::set<std::pair<size_t, size_t> > Grid<V, G, T>::getCells(
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
Box<T> Grid<V, G, T>::getBox(size_t x, size_t y) const { Box<T> Grid<V, G, T>::getBox(size_t x, size_t y) const {
Point<T> sw(_bb.getLowerLeft().template getX() + x * _cellWidth, Point<T> sw(_bb.getLowerLeft().getX() + x * _cellWidth,
_bb.getLowerLeft().template getY() + y * _cellHeight); _bb.getLowerLeft().getY() + y * _cellHeight);
Point<T> ne(_bb.getLowerLeft().template getX() + (x + 1) * _cellWidth, Point<T> ne(_bb.getLowerLeft().getX() + (x + 1) * _cellWidth,
_bb.getLowerLeft().template getY() + (y + 1) * _cellHeight); _bb.getLowerLeft().getY() + (y + 1) * _cellHeight);
return Box<T>(sw, ne); return Box<T>(sw, ne);
} }
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
size_t Grid<V, G, T>::getCellXFromX(double x) const { size_t Grid<V, G, T>::getCellXFromX(double x) const {
float dist = x - _bb.getLowerLeft().template getX(); float dist = x - _bb.getLowerLeft().getX();
if (dist < 0) dist = 0; if (dist < 0) dist = 0;
return floor(dist / _cellWidth); return floor(dist / _cellWidth);
} }
@ -210,7 +210,7 @@ size_t Grid<V, G, T>::getCellXFromX(double x) const {
// _____________________________________________________________________________ // _____________________________________________________________________________
template <typename V, template <typename> typename G, typename T> template <typename V, template <typename> typename G, typename T>
size_t Grid<V, G, T>::getCellYFromY(double y) const { size_t Grid<V, G, T>::getCellYFromY(double y) const {
float dist = y - _bb.getLowerLeft().template getY(); float dist = y - _bb.getLowerLeft().getY();
if (dist < 0) dist = 0; if (dist < 0) dist = 0;
return floor(dist / _cellHeight); return floor(dist / _cellHeight);
} }

View file

@ -11,6 +11,7 @@ namespace geo {
template <typename T> template <typename T>
class Point { class Point {
public: public:
Point() : _x(0), _y(0) {}
Point(T x, T y) : _x(x), _y(y) {} Point(T x, T y) : _x(x), _y(y) {}
T getX() const { return _x; } T getX() const { return _x; }
T getY() const { return _y; } T getY() const { return _y; }

View file

@ -5,6 +5,7 @@
#ifndef UTIL_GEO_POLYLINE_H_ #ifndef UTIL_GEO_POLYLINE_H_
#define UTIL_GEO_POLYLINE_H_ #define UTIL_GEO_POLYLINE_H_
#include <cfloat>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <vector> #include <vector>

View file

@ -66,11 +66,6 @@ void PolyLine<T>::offsetPerp(double units) {
* *
* there doesn't seem to be any library which reliably does that, * there doesn't seem to be any library which reliably does that,
* so we do it ourself here until we find one... * so we do it ourself here until we find one...
* boost::geometry only supports buffering a line, resulting in a
* polygon. An offsetted line is part of that polygon, but retrieving
* it reliably could result in some geometrical diffing hocus pocus which is
* bound to go wrong at /some/ point (self intersections, numerical
* instability etc)
*/ */
if (fabs(units) < 0.001) return; if (fabs(units) < 0.001) return;
@ -87,8 +82,8 @@ void PolyLine<T>::offsetPerp(double units) {
for (size_t i = 1; i < _line.size(); i++) { for (size_t i = 1; i < _line.size(); i++) {
Point<T> curP = _line[i]; Point<T> curP = _line[i];
double n1 = lastP.template get<1>() - curP.template get<1>(); double n1 = lastP.getY() - curP.getY();
double n2 = curP.template get<0>() - lastP.template get<0>(); double n2 = curP.getX() - lastP.getX();
double n = sqrt(n1 * n1 + n2 * n2); double n = sqrt(n1 * n1 + n2 * n2);
// if n == 0, the segment is effectively a point // if n == 0, the segment is effectively a point
@ -98,11 +93,11 @@ void PolyLine<T>::offsetPerp(double units) {
n1 = n1 / n; n1 = n1 / n;
n2 = n2 / n; n2 = n2 / n;
lastP.template set<0>(lastP.template get<0>() + (n1 * units)); lastP.template set<0>(lastP.getX() + (n1 * units));
lastP.template set<1>(lastP.template get<1>() + (n2 * units)); lastP.template set<1>(lastP.getY() + (n2 * units));
curP.template set<0>(curP.template get<0>() + (n1 * units)); curP.template set<0>(curP.getX() + (n1 * units));
curP.template set<1>(curP.template get<1>() + (n2 * units)); curP.template set<1>(curP.getY() + (n2 * units));
if (lastIns && befLastIns && if (lastIns && befLastIns &&
lineIntersects(*lastIns, *befLastIns, lastP, curP)) { lineIntersects(*lastIns, *befLastIns, lastP, curP)) {
@ -213,7 +208,7 @@ LinePoint<T> PolyLine<T>::getPointAtDist(double atDist) const {
for (size_t i = 1; i < _line.size(); i++) { for (size_t i = 1; i < _line.size(); i++) {
const Point<T>& cur = _line[i]; const Point<T>& cur = _line[i];
double d = geo::dist(last, cur); double d = geo::dist(*last, cur);
dist += d; dist += d;
if (dist > atDist) { if (dist > atDist) {
@ -239,13 +234,13 @@ LinePoint<T> PolyLine<T>::getPointAt(double at) const {
template <typename T> template <typename T>
Point<T> PolyLine<T>::interpolate(const Point<T>& a, const Point<T>& b, Point<T> PolyLine<T>::interpolate(const Point<T>& a, const Point<T>& b,
double p) const { double p) const {
double n1 = b.template get<0>() - a.template get<0>(); double n1 = b.getX() - a.getX();
double n2 = b.template get<1>() - a.template get<1>(); double n2 = b.getY() - a.getY();
double n = sqrt(n1 * n1 + n2 * n2); double n = sqrt(n1 * n1 + n2 * n2);
n1 = n1 / n; n1 = n1 / n;
n2 = n2 / n; n2 = n2 / n;
return Point<T>(a.template get<0>() + (n1 * p), return Point<T>(a.getX() + (n1 * p),
a.template get<1>() + (n2 * p)); a.getY() + (n2 * p));
} }
// _____________________________________________________________________________ // _____________________________________________________________________________
@ -304,11 +299,11 @@ PolyLine<T> PolyLine<T>::average(const std::vector<const PolyLine<T>*>& lines,
const PolyLine* pl = lines[i]; const PolyLine* pl = lines[i];
Point<T> p = pl->getPointAt(a).p; Point<T> p = pl->getPointAt(a).p;
if (weighted) { if (weighted) {
x += p.template get<0>() * weights[i]; x += p.getX() * weights[i];
y += p.template get<1>() * weights[i]; y += p.getY() * weights[i];
} else { } else {
x += p.template get<0>(); x += p.getX();
y += p.template get<1>(); y += p.getY();
} }
} }
ret << Point<T>(x / total, y / total); ret << Point<T>(x / total, y / total);
@ -465,8 +460,8 @@ bool PolyLine<T>::contains(const PolyLine<T>& rhs, double dmax) const {
template <typename T> template <typename T>
void PolyLine<T>::move(double vx, double vy) { void PolyLine<T>::move(double vx, double vy) {
for (size_t i = 0; i < _line.size(); i++) { for (size_t i = 0; i < _line.size(); i++) {
_line[i].set<0>(_line[i].template get<0>() + vx); _line[i].set<0>(_line[i].getX() + vx);
_line[i].set<1>(_line[i].template get<1>() + vy); _line[i].set<1>(_line[i].getY() + vy);
} }
} }
@ -624,11 +619,11 @@ PolyLine<T> PolyLine<T>::getOrthoLineAtDist(double d, double length) const {
double angle = angBetween(getPointAtDist(d - 5).p, getPointAtDist(d + 5).p); double angle = angBetween(getPointAtDist(d - 5).p, getPointAtDist(d + 5).p);
double angleX1 = avgP.template get<0>() + cos(angle + M_PI / 2) * length / 2; double angleX1 = avgP.getX() + cos(angle + M_PI / 2) * length / 2;
double angleY1 = avgP.template get<1>() + sin(angle + M_PI / 2) * length / 2; double angleY1 = avgP.getY() + sin(angle + M_PI / 2) * length / 2;
double angleX2 = avgP.template get<0>() + cos(angle + M_PI / 2) * -length / 2; double angleX2 = avgP.getX() + cos(angle + M_PI / 2) * -length / 2;
double angleY2 = avgP.template get<1>() + sin(angle + M_PI / 2) * -length / 2; double angleY2 = avgP.getY() + sin(angle + M_PI / 2) * -length / 2;
return PolyLine(Point<T>(angleX1, angleY1), Point<T>(angleX2, angleY2)); return PolyLine(Point<T>(angleX1, angleY1), Point<T>(angleX2, angleY2));
} }
@ -648,8 +643,8 @@ std::pair<double, double> PolyLine<T>::getSlopeBetween(double ad,
double d = dist(a.p, b.p); double d = dist(a.p, b.p);
double dx = (b.p.template get<0>() - a.p.template get<0>()) / d; double dx = (b.p.getX() - a.p.getX()) / d;
double dy = (b.p.template get<1>() - a.p.template get<1>()) / d; double dy = (b.p.getY() - a.p.getY()) / d;
return std::pair<double, double>(dx, dy); return std::pair<double, double>(dx, dy);
} }
@ -711,11 +706,11 @@ void PolyLine<T>::applyChaikinSmooth(size_t depth) {
Point<T> pB = _line[i]; Point<T> pB = _line[i];
smooth.push_back( smooth.push_back(
Point<T>(0.75 * pA.template get<0>() + 0.25 * pB.template get<0>(), Point<T>(0.75 * pA.getX() + 0.25 * pB.getX(),
0.75 * pA.template get<1>() + 0.25 * pB.template get<1>())); 0.75 * pA.getY() + 0.25 * pB.getY()));
smooth.push_back( smooth.push_back(
Point<T>(0.25 * pA.template get<0>() + 0.75 * pB.template get<0>(), Point<T>(0.25 * pA.getX() + 0.75 * pB.getX(),
0.25 * pA.template get<1>() + 0.75 * pB.template get<1>())); 0.25 * pA.getY() + 0.75 * pB.getY()));
} }
smooth.push_back(_line.back()); smooth.push_back(_line.back());

32
src/util/geo/Polygon.h Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2016, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Patrick Brosi <brosi@informatik.uni-freiburg.de>
#ifndef UTIL_GEO_POLYGON_H_
#define UTIL_GEO_POLYGON_H_
#include <vector>
#include "./Point.h"
#include "./Line.h"
namespace util {
namespace geo {
template <typename T>
class Polygon {
public:
// maximum inverse box as default value of box
Polygon(const Line<T>& l) : _outer(l) {}
const std::vector<Point<T>>& getOuter() const { return _outer; }
std::vector<Point<T>>& getOuter() {return _outer; }
private:
std::vector<Point<T>> _outer;
};
} // namespace geo
} // namespace util
#endif // UTIL_GEO_LINE_H_

View file

@ -13,8 +13,8 @@ void GeoJsonOutput::print(const Point<T>& p, Attrs attrs) {
_wr.keyVal("type", "Point"); _wr.keyVal("type", "Point");
_wr.key("coordinates"); _wr.key("coordinates");
_wr.arr(); _wr.arr();
_wr.val(p.template get<0>()); _wr.val(p.getX());
_wr.val(p.template get<1>()); _wr.val(p.getY());
_wr.close(); _wr.close();
_wr.close(); _wr.close();
_wr.key("properties"); _wr.key("properties");
@ -36,8 +36,8 @@ void GeoJsonOutput::print(const Line<T>& line, Attrs attrs) {
_wr.arr(); _wr.arr();
for (auto p : line) { for (auto p : line) {
_wr.arr(); _wr.arr();
_wr.val(p.template get<0>()); _wr.val(p.getX());
_wr.val(p.template get<1>()); _wr.val(p.template getY());
_wr.close(); _wr.close();
} }
_wr.close(); _wr.close();

View file

@ -129,8 +129,8 @@ CASE("grid") {
l.push_back(Point<double>(1.5, 2)); l.push_back(Point<double>(1.5, 2));
Line<double> l2; Line<double> l2;
l.push_back(Point<double>(2.5, 1)); l2.push_back(Point<double>(2.5, 1));
l.push_back(Point<double>(2.5, 2)); l2.push_back(Point<double>(2.5, 2));
g.add(l, 1); g.add(l, 1);
g.add(l2, 2); g.add(l2, 2);
@ -143,8 +143,7 @@ CASE("grid") {
ret.clear(); ret.clear();
g.getNeighbors(1, 0, &ret); g.getNeighbors(1, 0, &ret);
// TODO! EXPECT(ret.size() == (size_t)1);
//EXPECT(ret.size() == 1);
ret.clear(); ret.clear();
g.getNeighbors(1, 0.55, &ret); g.getNeighbors(1, 0.55, &ret);
@ -907,6 +906,42 @@ CASE("geometry") {
EXPECT(!geo::contains(geo::Point<double>(1, 2), l)); EXPECT(!geo::contains(geo::Point<double>(1, 2), l));
EXPECT(geo::contains(geo::Point<double>(2, 2), l)); EXPECT(geo::contains(geo::Point<double>(2, 2), l));
EXPECT(geo::contains(geo::Point<double>(2, 3), l)); EXPECT(geo::contains(geo::Point<double>(2, 3), l));
geo::Box<double> bbox(geo::Point<double>(1, 1), geo::Point<double>(3, 3));
EXPECT(geo::intersects(l, bbox));
geo::Line<double> ll{geo::Point<double>(0, 0), geo::Point<double>(4, 4)};
EXPECT(geo::intersects(ll, bbox));
geo::Line<double> lll{geo::Point<double>(0, 0), geo::Point<double>(0, 4)};
EXPECT(!geo::intersects(lll, bbox));
geo::Line<double> llll{geo::Point<double>(1.2, 0), geo::Point<double>(1, 2)};
EXPECT(geo::intersects(llll, bbox));
Line<double> l5;
l5.push_back(Point<double>(0, 0));
l5.push_back(Point<double>(1.5, 2));
Box<double> req(Point<double>(.5, 1), Point<double>(1, 1.5));
EXPECT(geo::getBoundingBox(l5[0]).getLowerLeft().getX() == approx(0));
EXPECT(geo::getBoundingBox(l5[0]).getLowerLeft().getY() == approx(0));
EXPECT(geo::getBoundingBox(l5).getLowerLeft().getX() == approx(0));
EXPECT(geo::getBoundingBox(l5).getLowerLeft().getY() == approx(0));
EXPECT(geo::getBoundingBox(l5).getUpperRight().getX() == approx(1.5));
EXPECT(geo::getBoundingBox(l5).getUpperRight().getY() == approx(2));
EXPECT(geo::intersects(geo::getBoundingBox(l5), geo::getBoundingBox(Line<double>{Point<double>(.5, 1), Point<double>(1, 1)})));
EXPECT(geo::intersects(l5, Line<double>{Point<double>(.5, 1), Point<double>(1, 1)}));
EXPECT(geo::intersects(l5, req));
Box<double> boxa(Point<double>(1, 1), Point<double>(2, 2));
EXPECT(geo::intersects(boxa, Box<double>(Point<double>(1.5, 1.5), Point<double>(1.7, 1.7))));
EXPECT(geo::intersects(boxa, Box<double>(Point<double>(0, 0), Point<double>(3, 3))));
EXPECT(geo::intersects(boxa, Box<double>(Point<double>(1.5, 1.5), Point<double>(3, 3))));
EXPECT(geo::intersects(boxa, Box<double>(Point<double>(0, 0), Point<double>(1.5, 1.5))));
EXPECT(geo::intersects(Box<double>(Point<double>(1.5, 1.5), Point<double>(1.7, 1.7)), boxa));
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(3, 3)), boxa));
EXPECT(geo::intersects(Box<double>(Point<double>(1.5, 1.5), Point<double>(3, 3)), boxa));
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(1.5, 1.5)), boxa));
} }
}; };