diff --git a/Paths/KlingenbachTest2.wima b/Paths/KlingenbachTest2.wima new file mode 100644 index 0000000000000000000000000000000000000000..e6d74be02383fe69ba58871b412ec25ff8cbf608 --- /dev/null +++ b/Paths/KlingenbachTest2.wima @@ -0,0 +1,785 @@ +{ + "AreaItems": [ + { + "AreaType": "Service Area", + "BorderPolygonOffset": 6, + "DepotAltitude": 0, + "DepotLatitude": 47.76779586216649, + "DepotLongitude": 16.530510396830728, + "ShowBorderPolygon": 0, + "maxAltitude": 30, + "polygon": [ + [ + 47.76780094967389, + 16.530343715825353 + ], + [ + 47.76788238112663, + 16.530625096151965 + ], + [ + 47.767783696604035, + 16.530655731490725 + ], + [ + 47.76771642095403, + 16.53041704413795 + ] + ] + }, + { + "AreaType": "Measurement Area", + "BorderPolygonOffset": 6, + "MinTileAreaPercent": 30, + "ShowBorderPolygon": 0, + "ShowTiles": true, + "TileHeight": 5, + "TileWidth": 5, + "maxAltitude": 30, + "polygon": [ + [ + 47.76809580679245, + 16.530246122817612 + ], + [ + 47.76823933601322, + 16.53060087654427 + ], + [ + 47.7683711160486, + 16.530967006195464 + ], + [ + 47.7680076482754, + 16.531153949077463 + ], + [ + 47.7677855557718, + 16.530403347547246 + ], + [ + 47.76812093862815, + 16.53088714314225 + ] + ] + } + ], + "MissionItems": { + "fileType": "Plan", + "geoFence": { + "circles": [ + ], + "polygons": [ + ], + "version": 2 + }, + "groundStation": "QGroundControl", + "mission": { + "cruiseSpeed": 15, + "firmwareType": 3, + "hoverSpeed": 1, + "items": [ + { + "autoContinue": true, + "command": 22, + "doJumpId": 1, + "frame": 3, + "params": [ + 15, + 0, + 0, + null, + 47.76779586216649, + 16.530510396830728, + 10 + ], + "type": "SimpleItem" + }, + { + "Alpha": 23, + "MinLength": 5, + "NumRuns": 1, + "ReferencePointAlt": 0, + "ReferencePointLat": 47.76810433066452, + "ReferencePointLong": 16.530712738301304, + "Run": 1, + "TransectDistance": 3, + "TransectStyleComplexItem": { + "CameraCalc": { + "AdjustedFootprintFrontal": 25, + "AdjustedFootprintSide": 25, + "CameraName": "Manual (no camera specs)", + "DistanceToSurface": 10, + "DistanceToSurfaceRelative": true, + "version": 1 + }, + "CameraShots": 0, + "CameraTriggerInTurnAround": true, + "FollowTerrain": false, + "HoverAndCapture": false, + "Items": [ + { + "autoContinue": true, + "command": 16, + "doJumpId": 2, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76783728898401, + 16.530481694784847, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 3, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76802613957926, + 16.53114161450939, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 4, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768179446847086, + 16.53106276402324, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 5, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76812171672615, + 16.530861029906276, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 6, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76831125432985, + 16.530806354689858, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 7, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768358305251056, + 16.530970771201435, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 8, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76833275405663, + 16.53098391307365, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 9, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76818906969824, + 16.530481820523075, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 10, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76810775728066, + 16.530504966391423, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 11, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76825610046365, + 16.53102333861304, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 12, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768281651653936, + 16.531010196779448, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 13, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76810310388368, + 16.530386278613275, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 14, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76809845036399, + 16.530267590829624, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 15, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76830720286059, + 16.53099705493299, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 16, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76823054925376, + 16.531036480433762, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 17, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768112410554885, + 16.530623654217433, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 18, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76811706370638, + 16.530742342037925, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 19, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76820499805124, + 16.531049622228267, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 20, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76815389564133, + 16.531075905805334, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 21, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768086884966515, + 16.53084174152664, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 22, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76803696584865, + 16.530769731894658, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 23, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76812834442496, + 16.531089047574557, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 24, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76810279321597, + 16.53110218933091, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 25, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76798704669417, + 16.530697722387153, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 26, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.767937127512056, + 16.530625713070812, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 27, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76807724201434, + 16.531115331061052, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 28, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.768051690793115, + 16.531128472791657, + 10 + ], + "type": "SimpleItem" + }, + { + "autoContinue": true, + "command": 16, + "doJumpId": 29, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76788720826634, + 16.530553703838915, + 10 + ], + "type": "SimpleItem" + } + ], + "Refly90Degrees": false, + "TurnAroundDistance": 10, + "VisualTransectPoints": [ + [ + 47.76783728898401, + 16.530481694784847 + ], + [ + 47.76802613957926, + 16.53114161450939 + ], + [ + 47.768179446847086, + 16.53106276402324 + ], + [ + 47.76812171672615, + 16.530861029906276 + ], + [ + 47.76831125432985, + 16.530806354689858 + ], + [ + 47.768358305251056, + 16.530970771201435 + ], + [ + 47.76833275405663, + 16.53098391307365 + ], + [ + 47.76818906969824, + 16.530481820523075 + ], + [ + 47.76810775728066, + 16.530504966391423 + ], + [ + 47.76825610046365, + 16.53102333861304 + ], + [ + 47.768281651653936, + 16.531010196779448 + ], + [ + 47.76810310388368, + 16.530386278613275 + ], + [ + 47.76809845036399, + 16.530267590829624 + ], + [ + 47.76830720286059, + 16.53099705493299 + ], + [ + 47.76823054925376, + 16.531036480433762 + ], + [ + 47.768112410554885, + 16.530623654217433 + ], + [ + 47.76811706370638, + 16.530742342037925 + ], + [ + 47.76820499805124, + 16.531049622228267 + ], + [ + 47.76815389564133, + 16.531075905805334 + ], + [ + 47.768086884966515, + 16.53084174152664 + ], + [ + 47.76803696584865, + 16.530769731894658 + ], + [ + 47.76812834442496, + 16.531089047574557 + ], + [ + 47.76810279321597, + 16.53110218933091 + ], + [ + 47.76798704669417, + 16.530697722387153 + ], + [ + 47.767937127512056, + 16.530625713070812 + ], + [ + 47.76807724201434, + 16.531115331061052 + ], + [ + 47.768051690793115, + 16.531128472791657 + ], + [ + 47.76788720826634, + 16.530553703838915 + ] + ], + "version": 1 + }, + "Type": 1, + "Variant": 0, + "complexItemType": "CircularSurvey", + "polygon": [ + [ + 50.54939570164431, + 7.196328001507449 + ], + [ + 50.54939570164431, + 7.238775845997314 + ], + [ + 50.522416083956976, + 7.238775845997314 + ], + [ + 50.522416083956976, + 7.196328001507449 + ] + ], + "type": "ComplexItem", + "version": 1 + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 10, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 33, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76807639917751, + 16.530893624112736, + 10 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 10, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 34, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76779586216649, + 16.530510396830728, + 10 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 0, + "AltitudeMode": 1, + "autoContinue": true, + "command": 21, + "doJumpId": 35, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.76779586216649, + 16.530510396830728, + 0 + ], + "type": "SimpleItem" + } + ], + "plannedHomePosition": [ + 47.76779586216649, + 16.530510396830728, + 178 + ], + "vehicleType": 2, + "version": 2 + }, + "rallyPoints": { + "points": [ + ], + "version": 2 + }, + "version": 1 + } +} diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 8a40bde801ebdae22a414daa5372528287561796..dfcc493f4812a70142dcc076d76b2bb6a451a4e5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -418,6 +418,10 @@ HEADERS += \ src/Wima/GenericSingelton.h \ src/Wima/Geometry/GenericCircle.h \ src/Wima/RoutingThread.h \ + src/Wima/Snake/CircularGenerator.h \ + src/Wima/Snake/GeneratorBase.h \ + src/Wima/Snake/GeneratorData.h \ + src/Wima/Snake/StandardData.h \ src/Wima/Snake/clipper/clipper.hpp \ src/Wima/Snake/mapbox/feature.hpp \ src/Wima/Snake/mapbox/geometry.hpp \ @@ -510,6 +514,9 @@ SOURCES += \ src/Wima/CircularSurvey.cc \ src/Wima/GenericSingelton.cpp \ src/Wima/RoutingThread.cpp \ + src/Wima/Snake/CircularGenerator.cpp \ + src/Wima/Snake/GeneratorBase.cc \ + src/Wima/Snake/StandardData.cpp \ src/Wima/Snake/clipper/clipper.cpp \ src/Wima/Snake/snake.cpp \ src/Wima/Geometry/GeoPoint3D.cpp \ diff --git a/src/Wima/Snake/CircularGenerator.cpp b/src/Wima/Snake/CircularGenerator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d77dfafbf14d0b766e077c25d5302d0d9220b7e --- /dev/null +++ b/src/Wima/Snake/CircularGenerator.cpp @@ -0,0 +1,269 @@ +#include "CircularGenerator.h" + +#include "QGCLoggingCategory.h" + +QGC_LOGGING_CATEGORY(CircularGeneratorLog, "CircularGeneratorLog") + +namespace routing { + +bool circularTransects(const snake::FPolygon &polygon, + const std::vector &tiles, + snake::Length deltaR, snake::Angle deltaAlpha, + snake::Length minLength, snake::Transects &transects); + +CircularGenerator::CircularGenerator() : GeneratorBase() {} + +CircularGenerator::CircularGenerator(std::shared_ptr par, + QObject *parent) + : GeneratorBase(parent) { + if (qobject_cast(par.get()) != nullptr) { + data_ = data; + } else { + qCWarning(CircularGeneratorLog) + << "CircularGenerator(): CircularGenerator accepts only StandartData."; + } +} + +QString CircularGenerator::editorQML() { + return QStringLiteral("CircularGeneratorEditor.qml"); +} + +QString CircularGenerator::mapVisualQML() { + return QStringLiteral("CircularGeneratorMapVisual.qml"); +} + +QString CircularGenerator::name() { + return QStringLiteral("Circular Generator"); +} + +QString CircularGenerator::abbreviation() { return QStringLiteral("C. Gen."); } + +GeneratorBase::Generator CircularGenerator::get() {} + +bool CircularGenerator::setData(std::shared_ptr data) { + if (qobject_cast(par.get()) != nullptr) { + data_ = data; + } else { + qCWarning(CircularGeneratorLog) + << "setData(): CircularGenerator accepts only StandartData."; + } +} + +std::shared_ptr CircularGenerator::data() { return data_; } + +bool circularTransects(const snake::FPolygon &polygon, + const std::vector &tiles, + snake::Length deltaR, snake::Angle deltaAlpha, + snake::Length minLength, snake::Transects &transects) { + auto s1 = std::chrono::high_resolution_clock::now(); + + // Check preconitions + if (polygon.outer().size() >= 3) { + using namespace boost::units; + // Convert geo polygon to ENU polygon. + snake::FPoint origin{0, 0}; + std::string error; + // Check validity. + if (!bg::is_valid(polygon, error)) { + qCWarning(CircularSurveyLog) << "circularTransects(): " + "invalid polygon."; + qCWarning(CircularSurveyLog) << error.c_str(); + std::stringstream ss; + ss << bg::wkt(polygon); + qCWarning(CircularSurveyLog) << ss.str().c_str(); + } else { + // Calculate polygon distances and angles. + std::vector distances; + distances.reserve(polygon.outer().size()); + std::vector angles; + angles.reserve(polygon.outer().size()); + //#ifdef DEBUG_CIRCULAR_SURVEY + // qCWarning(CircularSurveyLog) << "circularTransects():"; + //#endif + for (const auto &p : polygon.outer()) { + snake::Length distance = bg::distance(origin, p) * si::meter; + distances.push_back(distance); + snake::Angle alpha = (std::atan2(p.get<1>(), p.get<0>())) * si::radian; + alpha = alpha < 0 * si::radian ? alpha + 2 * M_PI * si::radian : alpha; + angles.push_back(alpha); + //#ifdef DEBUG_CIRCULAR_SURVEY + // qCWarning(CircularSurveyLog) << "distances, angles, + // coordinates:"; qCWarning(CircularSurveyLog) << + // to_string(distance).c_str(); qCWarning(CircularSurveyLog) << + // to_string(snake::Degree(alpha)).c_str(); + // qCWarning(CircularSurveyLog) << "x = " << p.get<0>() << "y = " + // << p.get<1>(); + //#endif + } + + auto rMin = deltaR; // minimal circle radius + snake::Angle alpha1(0 * degree::degree); + snake::Angle alpha2(360 * degree::degree); + // Determine r_min by successive approximation + if (!bg::within(origin, polygon.outer())) { + rMin = bg::distance(origin, polygon) * si::meter; + } + + auto rMax = (*std::max_element(distances.begin(), + distances.end())); // maximal circle radius + + // Scale parameters and coordinates. + const auto rMinScaled = + ClipperLib::cInt(std::round(rMin.value() * CLIPPER_SCALE)); + const auto deltaRScaled = + ClipperLib::cInt(std::round(deltaR.value() * CLIPPER_SCALE)); + auto originScaled = + ClipperLib::IntPoint{ClipperLib::cInt(std::round(origin.get<0>())), + ClipperLib::cInt(std::round(origin.get<1>()))}; + + // Generate circle sectors. + auto rScaled = rMinScaled; + const auto nTran = long(std::ceil(((rMax - rMin) / deltaR).value())); + vector sectors(nTran, ClipperLib::Path()); + const auto nSectors = + long(std::round(((alpha2 - alpha1) / deltaAlpha).value())); + //#ifdef DEBUG_CIRCULAR_SURVEY + // qCWarning(CircularSurveyLog) << "circularTransects(): sector + // parameres:"; qCWarning(CircularSurveyLog) << "alpha1: " << + // to_string(snake::Degree(alpha1)).c_str(); + // qCWarning(CircularSurveyLog) << "alpha2: + // " + // << to_string(snake::Degree(alpha2)).c_str(); + // qCWarning(CircularSurveyLog) << "n: " + // << to_string((alpha2 - alpha1) / deltaAlpha).c_str(); + // qCWarning(CircularSurveyLog) + // << "nSectors: " << nSectors; qCWarning(CircularSurveyLog) << + // "rMin: " << to_string(rMin).c_str(); qCWarning(CircularSurveyLog) + // << "rMax: " << to_string(rMax).c_str(); + // qCWarning(CircularSurveyLog) << "nTran: " << nTran; + //#endif + using ClipperCircle = + GenericCircle; + for (auto §or : sectors) { + ClipperCircle circle(rScaled, originScaled); + approximate(circle, nSectors, sector); + rScaled += deltaRScaled; + } + // Clip sectors to polygonENU. + ClipperLib::Path polygonClipper; + snake::FPolygon shrinked; + snake::offsetPolygon(polygon, shrinked, -0.3); + auto &outer = shrinked.outer(); + polygonClipper.reserve(outer.size()); + for (auto it = outer.begin(); it < outer.end() - 1; ++it) { + auto x = ClipperLib::cInt(std::round(it->get<0>() * CLIPPER_SCALE)); + auto y = ClipperLib::cInt(std::round(it->get<1>() * CLIPPER_SCALE)); + polygonClipper.push_back(ClipperLib::IntPoint{x, y}); + } + ClipperLib::Clipper clipper; + clipper.AddPath(polygonClipper, ClipperLib::ptClip, true); + clipper.AddPaths(sectors, ClipperLib::ptSubject, false); + ClipperLib::PolyTree transectsClipper; + clipper.Execute(ClipperLib::ctIntersection, transectsClipper, + ClipperLib::pftNonZero, ClipperLib::pftNonZero); + + // Subtract holes. + if (tiles.size() > 0) { + vector processedTiles; + for (const auto &tile : tiles) { + ClipperLib::Path path; + for (const auto &v : tile.outer()) { + path.push_back(ClipperLib::IntPoint{ + static_cast(v.get<0>() * CLIPPER_SCALE), + static_cast(v.get<1>() * CLIPPER_SCALE)}); + } + processedTiles.push_back(std::move(path)); + } + + clipper.Clear(); + for (const auto &child : transectsClipper.Childs) { + clipper.AddPath(child->Contour, ClipperLib::ptSubject, false); + } + clipper.AddPaths(processedTiles, ClipperLib::ptClip, true); + transectsClipper.Clear(); + clipper.Execute(ClipperLib::ctDifference, transectsClipper, + ClipperLib::pftNonZero, ClipperLib::pftNonZero); + } + + // Extract transects from PolyTree and convert them to + // BoostLineString + for (const auto &child : transectsClipper.Childs) { + snake::FLineString transect; + transect.reserve(child->Contour.size()); + for (const auto &vertex : child->Contour) { + auto x = static_cast(vertex.X) / CLIPPER_SCALE; + auto y = static_cast(vertex.Y) / CLIPPER_SCALE; + transect.push_back(snake::FPoint(x, y)); + } + transects.push_back(transect); + } + + // Join sectors which where slit due to clipping. + const double th = 0.01; + for (auto ito = transects.begin(); ito < transects.end(); ++ito) { + for (auto iti = ito + 1; iti < transects.end(); ++iti) { + auto dist1 = bg::distance(ito->front(), iti->front()); + if (dist1 < th) { + snake::FLineString temp; + for (auto it = iti->end() - 1; it >= iti->begin(); --it) { + temp.push_back(*it); + } + temp.insert(temp.end(), ito->begin(), ito->end()); + *ito = temp; + transects.erase(iti); + break; + } + auto dist2 = bg::distance(ito->front(), iti->back()); + if (dist2 < th) { + snake::FLineString temp; + temp.insert(temp.end(), iti->begin(), iti->end()); + temp.insert(temp.end(), ito->begin(), ito->end()); + *ito = temp; + transects.erase(iti); + break; + } + auto dist3 = bg::distance(ito->back(), iti->front()); + if (dist3 < th) { + snake::FLineString temp; + temp.insert(temp.end(), ito->begin(), ito->end()); + temp.insert(temp.end(), iti->begin(), iti->end()); + *ito = temp; + transects.erase(iti); + break; + } + auto dist4 = bg::distance(ito->back(), iti->back()); + if (dist4 < th) { + snake::FLineString temp; + temp.insert(temp.end(), ito->begin(), ito->end()); + for (auto it = iti->end() - 1; it >= iti->begin(); --it) { + temp.push_back(*it); + } + *ito = temp; + transects.erase(iti); + break; + } + } + } + + // Remove short transects + for (auto it = transects.begin(); it < transects.end();) { + if (bg::length(*it) < minLength.value()) { + it = transects.erase(it); + } else { + ++it; + } + } + + qCWarning(CircularSurveyLog) + << "circularTransects(): transect gen. time: " + << std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - s1) + .count() + << " ms"; + return true; + } + } + return false; +} + +} // namespace routing diff --git a/src/Wima/Snake/CircularGenerator.h b/src/Wima/Snake/CircularGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..59810d9e200f813b007b43996ef503684d3de3c4 --- /dev/null +++ b/src/Wima/Snake/CircularGenerator.h @@ -0,0 +1,26 @@ +#include "GeneratorBase.h" +#include "StandardData.h" + +namespace routing { + +class CircularGenerator : public GeneratorBase { + Q_OBJECT +public: + CircularGenerator(); + CircularGenerator(std::shared_ptr par, + QObject *parent = nullptr); + ~CircularGenerator(); + + virtual QString editorQML(); + virtual QString mapVisualQML(); + + virtual QString name(); + virtual QString abbreviation(); + + virtual Generator get(); + +private: + std::shared_ptr _data; +}; + +} // namespace routing diff --git a/src/Wima/Snake/GeneratorBase.cc b/src/Wima/Snake/GeneratorBase.cc new file mode 100644 index 0000000000000000000000000000000000000000..32bcaeede1c93e4124003ca12beb7ab320372cb8 --- /dev/null +++ b/src/Wima/Snake/GeneratorBase.cc @@ -0,0 +1,13 @@ +#include "GeneratorBase.h" + +namespace routing { + +GeneratorBase::GeneratorBase(QObject *parent) : QObject(parent) {} + +GeneratorBase::GeneratorBase(std::shared_ptr par, + QObject *parent) + : QObject(parent) {} + +GeneratorBase::~GeneratorBase() {} + +} // namespace routing diff --git a/src/Wima/Snake/GeneratorBase.h b/src/Wima/Snake/GeneratorBase.h new file mode 100644 index 0000000000000000000000000000000000000000..9a157279df4a21195777e77bb583b57ae173afb9 --- /dev/null +++ b/src/Wima/Snake/GeneratorBase.h @@ -0,0 +1,33 @@ +#include + +#include +#include + +#include "snake.h" + +#include "GeneratorData.h" + +namespace routing { + +class GeneratorBase : public QObject { + Q_OBJECT +public: + using Generator = std::function; + + explicit GeneratorBase(QObject *parent = nullptr); + GeneratorBase(std::shared_ptr par, QObject *parent = nullptr); + ~GeneratorBase(); + + virtual QString editorQML() = 0; + virtual QString mapVisualQML() = 0; + + virtual QString name() = 0; + virtual QString abbreviation() = 0; + + virtual Generator get() = 0; + + virtual bool setData(std::shared_ptr par) = 0; + virtual std::shared_ptr data() = 0; +}; + +} // namespace routing diff --git a/src/Wima/Snake/GeneratorData.h b/src/Wima/Snake/GeneratorData.h new file mode 100644 index 0000000000000000000000000000000000000000..2d67a27b946e54468ab92a9fb627e61daa817d44 --- /dev/null +++ b/src/Wima/Snake/GeneratorData.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +class GeneratorData : public QObject { + Q_OBJECT +public: + explicit GeneratorData(QObject *parent = nullptr); +}; diff --git a/src/Wima/Snake/StandardData.cpp b/src/Wima/Snake/StandardData.cpp new file mode 100644 index 0000000000000000000000000000000000000000..171c4faa713cd4f3a8274ea1655306800891b572 --- /dev/null +++ b/src/Wima/Snake/StandardData.cpp @@ -0,0 +1,3 @@ +#include "StandardData.h" + +StandardParameter::StandardParameter() {} diff --git a/src/Wima/Snake/StandardData.h b/src/Wima/Snake/StandardData.h new file mode 100644 index 0000000000000000000000000000000000000000..b2075c6e0ae1d2b73c9da0dc8772992ecd48db85 --- /dev/null +++ b/src/Wima/Snake/StandardData.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GeneratorData.h" + +namespace routing { + +class StandardData : public GeneratorData {}; + +} // namespace routing