diff --git a/src/Wima/OptimisationTools.cc b/src/Wima/OptimisationTools.cc index 63c83186fe7a9741ac6b56b9d706e3db5a9e84e2..15ea047a70352b24489b5b2106ed9d71dc2d77d6 100644 --- a/src/Wima/OptimisationTools.cc +++ b/src/Wima/OptimisationTools.cc @@ -85,7 +85,7 @@ namespace OptimisationTools { Node* node = &nodeList[endIndex]; while (1) { if (node == nullptr) { - if (elementPath[0] == elementPath[startIndex])// check if starting point was reached + if (elementPath[0] == elements[startIndex])// check if starting point was reached break; return false; } diff --git a/src/Wima/PlanimetryCalculus.cc b/src/Wima/PlanimetryCalculus.cc index cd79c63b784926ea6959dd16f969406684c2ec48..3f94cbf8467bf17497320e7e7e241e5d7aa58755 100644 --- a/src/Wima/PlanimetryCalculus.cc +++ b/src/Wima/PlanimetryCalculus.cc @@ -318,6 +318,13 @@ angle double x2 = line2L1.x2(); double y1 = line2L1.y1(); double y2 = line2L1.y2(); + if (x1 > x2) { + x1 = x2; + x2 = line2L1.x1(); + y1 = y2; + y2 = line2L1.y1(); + } + double dx = (x2-x1); double dy = (y2-y1); double xNull = 0; // (xNull, 0) intersection point in line1 system @@ -548,6 +555,68 @@ angle return angle(line.p1(), line.p2()); } + bool contains(const QLineF &line, const QPointF &point, IntersectType &type) + { + QPointF translationVector = line.p1(); + double alpha = angle(line); + double l = line.length(); + + QPointF pointL1 = rotateReturn(point - translationVector, -alpha); + + double x = pointL1.x(); + double y = pointL1.y(); + + if ( x >= 0 && x <= l ) { + if (qFuzzyIsNull(x) || qFuzzyCompare(x, l)) { + if (qFuzzyIsNull(y)) + { + type = CornerCornerIntersection; + return true; + } + } else { + if (qFuzzyIsNull(y)) + { + type = EdgeCornerIntersection; + return true; + } + } + } + type = NoIntersection; + return false; + + } + + bool contains(const QLineF &line, const QPointF &point) + { + IntersectType dummyType; + return contains(line, point, dummyType); + } + + bool contains(const QPolygonF &polygon, const QPointF &point, IntersectType &type) + { + using namespace PolygonCalculus; + if (polygon.containsPoint(point, Qt::FillRule::OddEvenFill)) + { + type = Interior; + return true; + } + int size = polygon.size(); + for (int i = 0; i < size; i++) { + QLineF line(polygon[i], polygon[nextVertexIndex(size, i)]); + if ( contains(line, point, type) ) { + return true; + } + } + + return false; + } + + bool contains(const QPolygonF &polygon, const QPointF &point) + { + IntersectType dummyType; + return contains(polygon, point, dummyType); + } + diff --git a/src/Wima/PlanimetryCalculus.h b/src/Wima/PlanimetryCalculus.h index ac9319071bf3d76ff1c7e25d0bb0cb9da4a2922a..5c92f9adf7fdd0bd5efa004438f0f1f5c5522696 100644 --- a/src/Wima/PlanimetryCalculus.h +++ b/src/Wima/PlanimetryCalculus.h @@ -21,6 +21,8 @@ namespace PlanimetryCalculus { EdgeCornerIntersection, EdgeEdgeIntersection, CornerCornerIntersection, LinesParallel, LinesEqual, // Line Line intersection + Interior, // Polygon contains + NoIntersection, Error // general }; @@ -55,6 +57,12 @@ namespace PlanimetryCalculus { bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFList &intersectionList, NeighbourList &neighbourList); bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFList &intersectionList, NeighbourList &neighbourList, IntersectList &typeList); + bool contains(const QLineF &line, const QPointF &point); + bool contains(const QLineF &line, const QPointF &point, IntersectType &type); + bool contains(const QPolygonF &polygon, const QPointF &point); + bool contains(const QPolygonF &polygon, const QPointF &point, IntersectType &type); + + double distance(const QPointF &p1, const QPointF p2); double angle(const QPointF &p1, const QPointF p2); double angle(const QLineF &line); diff --git a/src/Wima/PolygonCalculus.cc b/src/Wima/PolygonCalculus.cc index f66d833f35be5d571abb971c02e888fc5177f7d2..fa7fd74318e8e269ff3083aba4dafbe793559da4 100644 --- a/src/Wima/PolygonCalculus.cc +++ b/src/Wima/PolygonCalculus.cc @@ -145,7 +145,7 @@ namespace PolygonCalculus { */ JoinPolygonError join(QPolygonF polygon1, QPolygonF polygon2, QPolygonF &joinedPolygon) { - using namespace PolygonCalculus; + using namespace PlanimetryCalculus; if (polygon1.size() >= 3 && polygon2.size() >= 3) { if ( !isSimplePolygon(polygon1) || !isSimplePolygon(polygon2)) { @@ -178,13 +178,12 @@ namespace PolygonCalculus { joinedPolygon.append(*crossPoly); return JoinPolygonError::PolygonJoined; } - + QPointF lastVertex = walkerPoly->last(); QPointF currentVertex = walkerPoly->value(startIndex); QPointF startVertex = currentVertex; // possible nextVertex (if no intersection between currentVertex and protoVertex with crossPoly) int nextVertexNumber = nextVertexIndex(walkerPoly->size(), startIndex); QPointF protoNextVertex = walkerPoly->value(nextVertexNumber); - bool switchHappenedPreviously = false; // means switch between crossPoly and walkerPoly while (1) { //qDebug("nextVertexNumber: %i", nextVertexNumber); joinedPolygon.append(currentVertex); @@ -200,32 +199,22 @@ namespace PolygonCalculus { //qDebug("IntersectionList.size(): %i", intersectionList.size()); - if (intersectionList.size() >= 1) { - int minDistIndex = 0; + if (intersectionList.size() > 0) { + int minDistIndex = -1; - // find the vertex with the least distance to currentVertex - if (intersectionList.size() > 1) { - double minDist = PlanimetryCalculus::distance(currentVertex, intersectionList[minDistIndex]); - for (int i = 1; i < intersectionList.size(); i++) { - double currentDist = PlanimetryCalculus::distance(currentVertex, intersectionList[i]); + double minDist = std::numeric_limits::infinity(); + for (int i = 0; i < intersectionList.size(); i++) { + double currentDist = PlanimetryCalculus::distance(currentVertex, intersectionList[i]); - if ( minDist > currentDist ) { - minDist = currentDist; - minDistIndex = i; - } + if ( minDist > currentDist && currentVertex != intersectionList[i]) { + minDist = currentDist; + minDistIndex = i; } } - //qDebug("MinDistIndex: %i", minDistIndex); - QPointF protoCurrentVertex = intersectionList.value(minDistIndex); - // If the currentVertex is a intersection point a intersection ocisSelfIntersectingcures with the - // crossPoly. This would cause unwanted switching of crossPoly and walkerPoly, thus intersections - // are only token in to account if they occur beyond a certain distance (_epsilonMeter) or no switching happend in the - // previous step. - - if (switchHappenedPreviously == false){ - //|| protoCurrentVertex.distanceTo(currentVertex) > _epsilonMeter) { - currentVertex = protoCurrentVertex; + if (minDistIndex != -1){ + lastVertex = currentVertex; + currentVertex = intersectionList.value(minDistIndex); QPair neighbours = neighbourList.value(minDistIndex); protoNextVertex = crossPoly->value(neighbours.second); nextVertexNumber = neighbours.second; @@ -234,33 +223,35 @@ namespace PolygonCalculus { const QPolygonF *temp = walkerPoly; walkerPoly = crossPoly; crossPoly = temp; - - switchHappenedPreviously = true; } else { - currentVertex = walkerPoly->value(nextVertexNumber); + lastVertex = currentVertex; + currentVertex = walkerPoly->value(nextVertexNumber); nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); - protoNextVertex = walkerPoly->value(nextVertexNumber); - - switchHappenedPreviously = false; + protoNextVertex = walkerPoly->value(nextVertexNumber); } } else { - currentVertex = walkerPoly->value(nextVertexNumber); + lastVertex = currentVertex; + currentVertex = walkerPoly->value(nextVertexNumber); nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); - protoNextVertex = walkerPoly->value(nextVertexNumber); + protoNextVertex = walkerPoly->value(nextVertexNumber); } if (currentVertex == startVertex) { if (polygon1.size() == joinedPolygon.size()) { - return JoinPolygonError::Disjoint; + for (int i = 0; i < polygon1.size(); i++) { + if (polygon1[i] != joinedPolygon[i]) + return PolygonJoined; + } + return Disjoint; } else { - return JoinPolygonError::PolygonJoined; + return PolygonJoined; } } } } else { - return JoinPolygonError::PathSizeLow; + return PathSizeLow; } } @@ -488,10 +479,12 @@ namespace PolygonCalculus { return; } - bool shortestPath(const QPolygonF &polygon, const QPointF &startVertex, const QPointF &endVertex, QList &shortestPath) + bool shortestPath(QPolygonF polygon, QPointF startVertex, const QPointF &endVertex, QList &shortestPath) { - if ( polygon.containsPoint(startVertex, Qt::FillRule::OddEvenFill) - && polygon.containsPoint(endVertex, Qt::FillRule::OddEvenFill)) { + using namespace PlanimetryCalculus; + offsetPolygon(polygon, 0.1); + if ( contains(polygon, startVertex) + && contains(polygon, endVertex)) { // lambda std::function distance = [polygon](const QPointF &p1, const QPointF &p2) -> double { if (containsPath(polygon, p1, p2)){ diff --git a/src/Wima/PolygonCalculus.h b/src/Wima/PolygonCalculus.h index 3fae8a3d2100404e1ebb9de22284917aed362ef6..5206c66c4089a2e4da0403424fd7389eb569cd77 100644 --- a/src/Wima/PolygonCalculus.h +++ b/src/Wima/PolygonCalculus.h @@ -25,7 +25,7 @@ namespace PolygonCalculus { void offsetPolygon (QPolygonF &polygon, double offset); bool containsPath (QPolygonF polygon, const QPointF &c1, const QPointF &c2); void decomposeToConvex (const QPolygonF &polygon, QList &convexPolygons); - bool shortestPath (const QPolygonF &polygon, const QPointF &startVertex, const QPointF &endVertex, QList &shortestPath); + bool shortestPath (QPolygonF polygon, QPointF startVertex, const QPointF &endVertex, QList &shortestPath); QPolygonF toQPolygonF(const QVector3DList &polygon); QPolygonF toQPolygonF(const QPointFList &polygon); diff --git a/src/Wima/WimaArea.cc b/src/Wima/WimaArea.cc index 898fe3f7945bf73e62a9c2bd740b49cecc1474d7..ebc8901ee3a4657722680a2905038b9f37e7de28 100644 --- a/src/Wima/WimaArea.cc +++ b/src/Wima/WimaArea.cc @@ -147,31 +147,31 @@ bool WimaArea::join(const WimaArea &area1, const WimaArea &area2, WimaArea &join QList GeoPolygon1 = area1.coordinateList(); QList GeoPolygon2 = area2.coordinateList(); - /*qWarning("befor joining"); + qWarning("befor joining"); qWarning() << GeoPolygon1; - qWarning() << GeoPolygon2;*/ + qWarning() << GeoPolygon2; QGeoCoordinate origin = GeoPolygon1[0]; QGeoCoordinate tset = GeoPolygon1[2]; - //qWarning() << tset;qWarning() << toGeo(toCartesian2D(tset, origin), origin); + qWarning() << tset;qWarning() << toGeo(toCartesian2D(tset, origin), origin); QPolygonF polygon1 = toQPolygonF(toCartesian2D(GeoPolygon1, origin)); QPolygonF polygon2 = toQPolygonF(toCartesian2D(GeoPolygon2, origin)); - /*qWarning("after 1 transform"); + qWarning("after 1 transform"); qWarning() << polygon1; - qWarning() << polygon2;*/ + qWarning() << polygon2; QPolygonF joinedPolygon; JoinPolygonError retValue = PolygonCalculus::join(polygon1, polygon2, joinedPolygon); - /*qWarning("after joining"); - qWarning() << joinedPolygon;*/ + qWarning("after joining"); + qWarning() << joinedPolygon; if (retValue == JoinPolygonError::Disjoint) { qWarning("Polygons are disjoint."); @@ -181,8 +181,8 @@ bool WimaArea::join(const WimaArea &area1, const WimaArea &area2, WimaArea &join qWarning("Polygon vertex count is low."); } else { QList path = toGeo(toQPointFList(joinedPolygon), origin); - //qWarning("after transform"); - //qWarning() << path; + qWarning("after transform"); + qWarning() << path; joinedArea.setPath(path); return true; } @@ -199,7 +199,7 @@ bool WimaArea::join(const WimaArea &area1, const WimaArea &area2, WimaArea &join * The algorithm will be able to join the areas, if either their edges intersect with each other, * or one area contains the other. */ -bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) +bool WimaArea::join(const WimaArea &area1, const WimaArea &area2, WimaArea &joinedArea) { QString dummy; return join(area1, area2, joinedArea, dummy); @@ -217,6 +217,8 @@ bool WimaArea::join(WimaArea &area) { WimaArea joinedArea; if ( join(*this, area, joinedArea) ) { + //qWarning("WimaArea::join(WimaArea &area)"); + //qWarning() << joinedArea.coordinateList(); this->setPath(joinedArea.path()); return true; } else { diff --git a/src/Wima/WimaArea.h b/src/Wima/WimaArea.h index 824711ae4efc02254c2b7b1e7c07b311f33a966e..f25c527c994dfe227212d0508ea4ba16d28cde07 100644 --- a/src/Wima/WimaArea.h +++ b/src/Wima/WimaArea.h @@ -50,7 +50,7 @@ public: // static Methodes static QGCMapPolygon toQGCPolygon (const WimaArea& area); static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea, QString &errorString); - static bool join (WimaArea &area1, WimaArea &area2, WimaArea& joinedArea); + static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea); bool isSimplePolygon (); // Friends diff --git a/src/Wima/WimaPlaner.cc b/src/Wima/WimaPlaner.cc index 440087b50a75184f2d7bc1da94f2cf0252d02ec7..c402e51a912f7c8743933c857e1b639584c49b2e 100644 --- a/src/Wima/WimaPlaner.cc +++ b/src/Wima/WimaPlaner.cc @@ -513,21 +513,22 @@ bool WimaPlaner::recalcJoinedArea(QString &errorString) return false; } - // join service area, op area and corridor - if (!_visualItems.contains(&_joinedArea)) - _visualItems.append(&_joinedArea); _joinedArea.setPath(_serviceArea.path()); _joinedArea.join(_corridor); if ( !_joinedArea.join(_measurementArea) ) { - errorString.append(tr("Not able to join areas. Service area and measurement are" + errorString.append(tr("Not able to join areas. Service area and measurement" " must have a overlapping section, or be connected through a corridor.")); return false; // this happens if all areas are pairwise disjoint } - else { - return true; - } + // join service area, op area and corridor + + // remove if debugging finished + WimaServiceArea *test = new WimaServiceArea(this); + test->setPath(_joinedArea.path()); + _visualItems.append(test); + return true; } /*!