diff --git a/src/Wima/OptimisationTools.cc b/src/Wima/OptimisationTools.cc index 0a866225b3057a18e0f8dedfda1242eb9fc9ba47..9b7448934f0af1e8dc8109c2eba6ed45abe7125a 100644 --- a/src/Wima/OptimisationTools.cc +++ b/src/Wima/OptimisationTools.cc @@ -16,7 +16,7 @@ namespace OptimisationTools { * \sa QList */ template - bool dijkstraAlgorithm(const QList elements, int startIndex, int endIndex, QList &elementPath, double(*distance)(const T &t1, const T &t2)) // don't seperate parameters with new lines or documentation will break + bool dijkstraAlgorithm(const QList elements, int startIndex, int endIndex, QList &elementPath, std::function distance) // don't seperate parameters with new lines or documentation will break { if ( elements.isEmpty() || startIndex < 0 || startIndex >= elements.size() || endIndex < 0 diff --git a/src/Wima/OptimisationTools.h b/src/Wima/OptimisationTools.h index c1768c6abc5bf49e956de1febfc62e313784ad1b..d32d4a58a59bb7c91b2f302dad873182a2dc7f47 100644 --- a/src/Wima/OptimisationTools.h +++ b/src/Wima/OptimisationTools.h @@ -3,9 +3,11 @@ #include +#include + namespace OptimisationTools { template - bool dijkstraAlgorithm(const QList elements, int startIndex, int endIndex, QList &elementPath, double(*distance)(const T &t1, const T &t2)); + bool dijkstraAlgorithm(const QList elements, int startIndex, int endIndex, QList &elementPath, std::function distance); } #endif // OPTIMISATIONTOOLS_H diff --git a/src/Wima/PlanimetryCalculus.h b/src/Wima/PlanimetryCalculus.h index b649b6ce23b75a57f4e750b1fd5b2ca574def851..b0cc4bbcf352e053a3f3226bdf91c3a60ea5f205 100644 --- a/src/Wima/PlanimetryCalculus.h +++ b/src/Wima/PlanimetryCalculus.h @@ -33,9 +33,9 @@ namespace PlanimetryCalculus { void rotateReference(QLineF &line, double alpha); //void rotateReference(QPolygonF &polygon, double alpha); - QPointF rotateReturn(QPointF point, double alpha); - QPointFList rotateReturn(QPointFList points, double alpha); - QLineF rotateReturn(QLineF line, double alpha); + QPointF rotateReturn(QPointF point, double alpha); + QPointFList rotateReturn(QPointFList points, double alpha); + QLineF rotateReturn(QLineF line, double alpha); //QPolygonF rotateReturn(QPolygonF &polygon, double alpha); bool intersects(const Circle &circle1, const Circle &circle2); diff --git a/src/Wima/PolygonCalculus.cc b/src/Wima/PolygonCalculus.cc index 83b5638fb89461c6f116b1da53e02b6ad9d376fa..dc7f4a3dc3c9066153ed24cc0eee85eab82bb35a 100644 --- a/src/Wima/PolygonCalculus.cc +++ b/src/Wima/PolygonCalculus.cc @@ -175,11 +175,11 @@ namespace PolygonCalculus { QPointF currentVertex = walkerPoly->value(startIndex); QPointF startVertex = currentVertex; // possible nextVertex (if no intersection between currentVertex and protoVertex with crossPoly) - int nextVertexIndex = nextVertexIndex(walkerPoly->size(), startIndex); - QPointF protoNextVertex = walkerPoly->value(nextVertexIndex); + int nextVertexNumber = nextVertexIndex(walkerPoly->size(), startIndex); + QPointF protoNextVertex = walkerPoly->value(nextVertexNumber); bool switchHappenedPreviously = false; // means switch between crossPoly and walkerPoly while (1) { - //qDebug("nextVertexIndex: %i", nextVertexIndex); + //qDebug("nextVertexNumber: %i", nextVertexNumber); joinedPolygon.append(currentVertex); QLineF walkerPolySegment; @@ -221,7 +221,7 @@ namespace PolygonCalculus { currentVertex = protoCurrentVertex; QPair neighbours = neighbourList.value(minDistIndex); protoNextVertex = crossPoly->value(neighbours.second); - nextVertexIndex = neighbours.second; + nextVertexNumber = neighbours.second; // switch walker and cross poly const QPolygonF *temp = walkerPoly; @@ -230,17 +230,17 @@ namespace PolygonCalculus { switchHappenedPreviously = true; } else { - currentVertex = walkerPoly->value(nextVertexIndex); - nextVertexIndex = nextVertexIndex(walkerPoly->size(), nextVertexIndex); - protoNextVertex = walkerPoly->value(nextVertexIndex); + currentVertex = walkerPoly->value(nextVertexNumber); + nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); + protoNextVertex = walkerPoly->value(nextVertexNumber); switchHappenedPreviously = false; } } else { - currentVertex = walkerPoly->value(nex bool containsPath (const QPointF &c1, const QPointF &c2, QPolygonF polygon);tVertexIndex); - nextVertexIndex = nextVertexIndex(walkerPoly->size(), nextVertexIndex); - protoNextVertex = walkerPoly->value(nextVertexIndex); + currentVertex = walkerPoly->value(nextVertexNumber); + nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); + protoNextVertex = walkerPoly->value(nextVertexNumber); } if (currentVertex == startVertex) { @@ -487,7 +487,7 @@ namespace PolygonCalculus { if ( polygon.containsPoint(startVertex, Qt::FillRule::OddEvenFill) && polygon.containsPoint(endVertex, Qt::FillRule::OddEvenFill)) { // lambda - auto distance = [polygon](const QPointF &p1, const QPointF &p2){ + auto distance = [polygon](const QPointF &p1, const QPointF &p2) -> double { if (containsPath(polygon, p1, p2)){ double dx = p1.x()-p2.x(); double dy = p1.y()-p2.y(); @@ -503,10 +503,7 @@ namespace PolygonCalculus { elementList.append(polygon[i]); } - - OptimisationTools::dijkstraAlgorithm(elementList, 0, 1, shortestPath, distance); - - + return OptimisationTools::dijkstraAlgorithm(elementList, 0, 1, shortestPath, distance); } else { return false; } diff --git a/src/Wima/SphereCalculus.cc b/src/Wima/SphereCalculus.cc index bfc0db0ccfdbdb883cad58c5c4c7ba96cc3ec7ec..504d101eb10f8b0dbff91b0f97d09c11d721512c 100644 --- a/src/Wima/SphereCalculus.cc +++ b/src/Wima/SphereCalculus.cc @@ -1,144 +1,6 @@ #include "SphereCalculus.h" -SphereCalculus::SphereCalculus(const SphereCalculus &other, QObject *parent) - : QObject (parent) -{ - *this = other; -} -SphereCalculus &SphereCalculus::operator=(const SphereCalculus &other) -{ - setEpsilonMeter(other.epsilonMeter()); - - return *this; -} - -void SphereCalculus::setEpsilonMeter(double epsilon) -{ - if (epsilon > 0) { - _epsilonMeter = epsilon; - } -} - -double SphereCalculus::epsilonMeter() const -{ - return _epsilonMeter; -} - - - - - -/*! - * \fn bool SphereCalculus::dijkstraPath(const QList &polygon, const QGeoCoordinate &c1, const QGeoCoordinate &c2, QList &dijkstraPath) - * Calculates the shortest path (inside \a polygon) between \a start and \a end. - * The \l {Dijkstra Algorithm} is used to find the shorest path. - * Stores the result inside \a dijkstraPath when sucessfull. - * Stores error messages in \a errorString. - * Returns \c true if successful, \c false else. - * - * \sa QList - */ -SphereCalculus::DijkstraError SphereCalculus::dijkstraPath(const QList &polygon, const QGeoCoordinate &start, const QGeoCoordinate &end, QList &dijkstraPath) -{ - if ( isSimplePolygon(polygon) ) { - return SphereCalculus::DijkstraError::NotSimplePolygon; - } - - // Each QGeoCoordinate gets stuff into a Node - /// @param distance is the distance between the Node and it's predecessor - struct Node{ - QGeoCoordinate coordinate; - double distance = std::numeric_limits::infinity(); - Node* predecessorNode = nullptr; - }; - - // The list with all Nodes (start, end + poly.path()) - QList nodeList; - // This list will be initalized with (pointer to) all elements of nodeList. - // Elements will be successively remove during the execution of the Dijkstra Algorithm. - QList workingSet; - - // initialize nodeList_maxAltitude - // start cooridnate - Node startNode; - startNode.coordinate = start; - startNode.distance = 0; - nodeList.append(startNode); - - //poly cooridnates - for (int i = 0; i < polygon.size(); i++) { - Node node; - node.coordinate = polygon[i]; - nodeList.append(node); - } - - //end coordinate - Node endNode; - endNode.coordinate = end; - nodeList.append(endNode); - - // initialize working set - for (int i = 0; i < nodeList.size(); i++) { - Node* nodePtr = &nodeList[i]; - workingSet.append(nodePtr); - } - - - // Dijkstra Algorithm - // https://de.wikipedia.org/wiki/Dijkstra-Algorithmus - while (workingSet.size() > 0) { - // serach Node with minimal distance - double minDist = std::numeric_limits::infinity(); - int minDistIndex = 0; - for (int i = 0; i < workingSet.size(); i++) { - Node* node = workingSet.value(i); - double dist = node->distance; - if (dist < minDist) { - minDist = dist; - minDistIndex = i; - } - } - Node* u = workingSet.takeAt(minDistIndex); - - - //update distance - for (int i = 0; i < workingSet.size(); i++) { - Node* v = workingSet[i]; - - // is neighbour? dist == infinity if no neihbour - double dist = distanceInsidePolygon(u->coordinate, v->coordinate, polygon); - // is ther a alternative path which is shorter?QList - double alternative = u->distance + dist; - if (alternative < v->distance) { - v->distance = alternative; - v->predecessorNode = u; - } - } - - } - // end Djikstra Algorithm - - - - - // reverse assemble path - Node* Node = &nodeList.last(); - while (1) { - dijkstraPath.prepend(Node->coordinate); - - //Update Node - Node = Node->predecessorNode; - if (Node == nullptr) { - if (dijkstraPath[0].distanceTo(start) < _epsilonMeter)// check if starting point was reached - break; - qWarning("WimaArea::dijkstraPath(): Error, no path found!\n"); - return SphereCalculus::DijkstraError::NoPathFound; - } - } - - return SphereCalculus::DijkstraError::PathFound; -} diff --git a/src/Wima/SphereCalculus.h b/src/Wima/SphereCalculus.h index d344e9b57d096ac87a1c06c73fef49eea5232819..c595514cdcb02fc4aca1e9b493a2fc1ba3112a69 100644 --- a/src/Wima/SphereCalculus.h +++ b/src/Wima/SphereCalculus.h @@ -1,5 +1,6 @@ #ifndef SphereCalculus_H #define SphereCalculus_H +#endif // SphereCalculus_H #include #include @@ -8,46 +9,11 @@ #include "QGCGeo.h" -// Abstract class providing methods to do calculations on objects located on a sphere (e.g. earth) -class SphereCalculus : public QObject -{ - Q_OBJECT -public: - SphereCalculus(QObject *parent = nullptr); - SphereCalculus(const SphereCalculus &other, QObject *parent = nullptr); - SphereCalculus &operator=(const SphereCalculus &other); - - typedef QPair Line; - - - enum JoinPolygonError { NotSimplePolygon1, PolygonJoined, NotSimplePolygon2, Disjoint, PathSizeLow}; - enum IntersectionType { NoIntersection, EdgeIntersection, InteriorIntersection, Error}; - enum DijkstraError { NoPathFound, PathFound, NotSimplePolygon}; - - // Property setters - void setEpsilonMeter(double epsilon); - - // Property getters - double epsilonMeter() const; - - // Member Methodes - +#include "PlanimetryCalculus.h" - DijkstraError dijkstraPath (const QList &polygon, const QGeoCoordinate& start, - const QGeoCoordinate& end, QList& dijkstraPath); +namespace SphereCalculus { +} -signals: - -public slots: - -private: - - - double _epsilonMeter; // The accuracy used for distance calculations (unit: m). - -}; - -#endif // SphereCalculus_H