Commit 2823f6dd authored by Valentin Platzgummer's avatar Valentin Platzgummer

min tile area -> percent

parent 5d91598d
...@@ -57,12 +57,10 @@ size_t TileData::size() const { ...@@ -57,12 +57,10 @@ size_t TileData::size() const {
const char *WimaMeasurementArea::settingsGroup = "MeasurementArea"; const char *WimaMeasurementArea::settingsGroup = "MeasurementArea";
const char *WimaMeasurementArea::tileHeightName = "TileHeight"; const char *WimaMeasurementArea::tileHeightName = "TileHeight";
const char *WimaMeasurementArea::tileWidthName = "TileWidth"; const char *WimaMeasurementArea::tileWidthName = "TileWidth";
const char *WimaMeasurementArea::minTileAreaName = "MinTileArea"; const char *WimaMeasurementArea::minTileAreaName = "MinTileAreaPercent";
const char *WimaMeasurementArea::showTilesName = "ShowTiles"; const char *WimaMeasurementArea::showTilesName = "ShowTiles";
const char *WimaMeasurementArea::WimaMeasurementAreaName = "Measurement Area"; const char *WimaMeasurementArea::WimaMeasurementAreaName = "Measurement Area";
void tileDeleter(QmlObjectListModel *tiles) { tiles->clearAndDeleteContents(); }
WimaMeasurementArea::WimaMeasurementArea(QObject *parent) WimaMeasurementArea::WimaMeasurementArea(QObject *parent)
: WimaArea(parent), : WimaArea(parent),
_metaDataMap(FactMetaData::createMapFromJsonFile( _metaDataMap(FactMetaData::createMapFromJsonFile(
...@@ -72,8 +70,9 @@ WimaMeasurementArea::WimaMeasurementArea(QObject *parent) ...@@ -72,8 +70,9 @@ WimaMeasurementArea::WimaMeasurementArea(QObject *parent)
this /* QObject parent */)), this /* QObject parent */)),
_tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName], _tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName],
this /* QObject parent */)), this /* QObject parent */)),
_minTileArea(SettingsFact(settingsGroup, _metaDataMap[minTileAreaName], _minTileAreaPercent(SettingsFact(settingsGroup,
this /* QObject parent */)), _metaDataMap[minTileAreaName],
this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName], _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName],
this /* QObject parent */)), this /* QObject parent */)),
_state(STATE::IDLE) { _state(STATE::IDLE) {
...@@ -90,8 +89,9 @@ WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other, ...@@ -90,8 +89,9 @@ WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other,
this /* QObject parent */)), this /* QObject parent */)),
_tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName], _tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName],
this /* QObject parent */)), this /* QObject parent */)),
_minTileArea(SettingsFact(settingsGroup, _metaDataMap[minTileAreaName], _minTileAreaPercent(SettingsFact(settingsGroup,
this /* QObject parent */)), _metaDataMap[minTileAreaName],
this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName], _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName],
this /* QObject parent */)), this /* QObject parent */)),
_state(STATE::IDLE) { _state(STATE::IDLE) {
...@@ -123,7 +123,7 @@ Fact *WimaMeasurementArea::tileHeight() { return &_tileHeight; } ...@@ -123,7 +123,7 @@ Fact *WimaMeasurementArea::tileHeight() { return &_tileHeight; }
Fact *WimaMeasurementArea::tileWidth() { return &_tileWidth; } Fact *WimaMeasurementArea::tileWidth() { return &_tileWidth; }
Fact *WimaMeasurementArea::minTileArea() { return &_minTileArea; } Fact *WimaMeasurementArea::minTileArea() { return &_minTileAreaPercent; }
Fact *WimaMeasurementArea::showTiles() { return &_showTiles; } Fact *WimaMeasurementArea::showTiles() { return &_showTiles; }
...@@ -156,46 +156,56 @@ int WimaMeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; } ...@@ -156,46 +156,56 @@ int WimaMeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; }
bool WimaMeasurementArea::ready() const { return this->_state == STATE::IDLE; } bool WimaMeasurementArea::ready() const { return this->_state == STATE::IDLE; }
void WimaMeasurementArea::saveToJson(QJsonObject &json) { void WimaMeasurementArea::saveToJson(QJsonObject &json) {
this->WimaArea::saveToJson(json); if (ready()) {
json[tileHeightName] = _tileHeight.rawValue().toDouble(); this->WimaArea::saveToJson(json);
json[tileWidthName] = _tileWidth.rawValue().toDouble(); json[tileHeightName] = _tileHeight.rawValue().toDouble();
json[minTileAreaName] = _minTileArea.rawValue().toDouble(); json[tileWidthName] = _tileWidth.rawValue().toDouble();
json[showTilesName] = _showTiles.rawValue().toBool(); json[minTileAreaName] = _minTileAreaPercent.rawValue().toDouble();
json[areaTypeName] = WimaMeasurementAreaName; json[showTilesName] = _showTiles.rawValue().toBool();
json[areaTypeName] = WimaMeasurementAreaName;
} else {
qCDebug(WimaMeasurementAreaLog) << "saveToJson(): not ready for saveing.";
}
} }
bool WimaMeasurementArea::loadFromJson(const QJsonObject &json, bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
QString &errorString) { QString &errorString) {
if (this->WimaArea::loadFromJson(json, errorString)) { if (this->WimaArea::loadFromJson(json, errorString)) {
disableUpdates();
bool retVal = true; bool retVal = true;
if (json.contains(tileHeightName) && json[tileHeightName].isDouble()) { if (!json.contains(tileHeightName) || !json[tileHeightName].isDouble()) {
_tileHeight.setRawValue(json[tileHeightName].toDouble());
} else {
errorString.append(tr("Could not load tile height!\n")); errorString.append(tr("Could not load tile height!\n"));
retVal = false; retVal = false;
} }
if (json.contains(tileWidthName) && json[tileWidthName].isDouble()) { if (!json.contains(tileWidthName) || !json[tileWidthName].isDouble()) {
_tileWidth.setRawValue(json[tileWidthName].toDouble());
} else {
errorString.append(tr("Could not load tile width!\n")); errorString.append(tr("Could not load tile width!\n"));
retVal = false; retVal = false;
} }
if (json.contains(minTileAreaName) && json[minTileAreaName].isDouble()) { if (!json.contains(minTileAreaName) || !json[minTileAreaName].isDouble()) {
_minTileArea.setRawValue(json[minTileAreaName].toDouble());
} else {
errorString.append(tr("Could not load minimal tile area!\n")); errorString.append(tr("Could not load minimal tile area!\n"));
retVal = false; retVal = false;
} }
if (json.contains(showTilesName) && json[showTilesName].isBool()) { if (!json.contains(showTilesName) || !json[showTilesName].isBool()) {
_showTiles.setRawValue(json[showTilesName].toBool());
} else {
errorString.append(tr("Could not load show tiles !\n")); errorString.append(tr("Could not load show tiles !\n"));
retVal = false; retVal = false;
} }
if (retVal) {
_tileHeight.setRawValue(json[tileHeightName].toDouble());
_tileWidth.setRawValue(json[tileWidthName].toDouble());
_minTileAreaPercent.setRawValue(json[minTileAreaName].toDouble());
_showTiles.setRawValue(json[showTilesName].toBool());
enableUpdates();
doUpdate();
} else {
enableUpdates();
}
return retVal; return retVal;
} else { } else {
return false; return false;
...@@ -222,69 +232,71 @@ void WimaMeasurementArea::doUpdate() { ...@@ -222,69 +232,71 @@ void WimaMeasurementArea::doUpdate() {
using namespace boost::units; using namespace boost::units;
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
// Check state.
const auto height = this->_tileHeight.rawValue().toDouble() * si::meter; if (this->_state != STATE::UPDATEING && !this->_state == STATE::STOP) {
const auto width = this->_tileWidth.rawValue().toDouble() * si::meter; const auto height = this->_tileHeight.rawValue().toDouble() * si::meter;
const auto tileArea = width * height; const auto width = this->_tileWidth.rawValue().toDouble() * si::meter;
const auto totalArea = this->area() * si::meter * si::meter; const auto tileArea = width * height;
const auto estNumTiles = totalArea / tileArea; const auto totalArea = this->area() * si::meter * si::meter;
if (this->_state != STATE::UPDATE && const auto estNumTiles = totalArea / tileArea;
long(std::ceil(estNumTiles.value())) <= SNAKE_MAX_TILES && // Check some conditions.
this->count() >= 3 && this->isSimplePolygon()) { if (long(std::ceil(estNumTiles.value())) <= SNAKE_MAX_TILES &&
setState(STATE::UPDATE); this->count() >= 3 && this->isSimplePolygon()) {
auto polygon = this->coordinateList(); setState(STATE::UPDATEING);
for (auto &v : polygon) {
v.setAltitude(0); auto polygon = this->coordinateList();
} for (auto &v : polygon) {
const auto minArea = v.setAltitude(0);
this->_minTileArea.rawValue().toDouble() * si::meter * si::meter; }
auto *th = this->thread(); const auto minArea =
auto future = QtConcurrent::run([polygon, th, height, width, minArea] { this->_minTileAreaPercent.rawValue().toDouble() / 100 * tileArea;
auto start = std::chrono::high_resolution_clock::now(); auto *th = this->thread();
auto future = QtConcurrent::run([polygon, th, height, width, minArea] {
DataPtr pData(new TileData()); auto start = std::chrono::high_resolution_clock::now();
// Convert to ENU system.
QGeoCoordinate origin = polygon.first(); DataPtr pData(new TileData());
FPolygon polygonENU; // Convert to ENU system.
areaToEnu(origin, polygon, polygonENU); QGeoCoordinate origin = polygon.first();
std::vector<FPolygon> tilesENU; FPolygon polygonENU;
BoundingBox bbox; areaToEnu(origin, polygon, polygonENU);
std::string errorString; std::vector<FPolygon> tilesENU;
// Generate tiles. BoundingBox bbox;
if (snake::tiles(polygonENU, height, width, minArea, tilesENU, bbox, std::string errorString;
errorString)) { // Generate tiles.
// Convert to geo system. if (snake::tiles(polygonENU, height, width, minArea, tilesENU, bbox,
for (const auto &t : tilesENU) { errorString)) {
auto geoTile = new SnakeTile(pData.get()); // Convert to geo system.
for (const auto &v : t.outer()) { for (const auto &t : tilesENU) {
QGeoCoordinate geoVertex; auto geoTile = new SnakeTile(pData.get());
fromENU(origin, v, geoVertex); for (const auto &v : t.outer()) {
geoTile->push_back(geoVertex); QGeoCoordinate geoVertex;
fromENU(origin, v, geoVertex);
geoTile->push_back(geoVertex);
}
pData->tiles.append(geoTile);
// Calculate center.
snake::FPoint center;
snake::polygonCenter(t, center);
QGeoCoordinate geoCenter;
fromENU(origin, center, geoCenter);
pData->tileCenterPoints.append(QVariant::fromValue(geoCenter));
} }
pData->tiles.append(geoTile);
// Calculate center.
snake::FPoint center;
snake::polygonCenter(t, center);
QGeoCoordinate geoCenter;
fromENU(origin, center, geoCenter);
pData->tileCenterPoints.append(QVariant::fromValue(geoCenter));
} }
} pData->moveToThread(th);
pData->moveToThread(th);
qCDebug(WimaMeasurementAreaLog) qCDebug(WimaMeasurementAreaLog)
<< "doUpdate(): update time: " << "doUpdate(): update time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>( << std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start) std::chrono::high_resolution_clock::now() - start)
.count() .count()
<< " ms"; << " ms";
return pData; return pData;
}); // QtConcurrent::run() }); // QtConcurrent::run()
this->_watcher.setFuture(future); this->_watcher.setFuture(future);
}
} }
qCDebug(WimaMeasurementAreaLog) qCDebug(WimaMeasurementAreaLog)
<< "doUpdate(): execution time: " << "doUpdate(): execution time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>( << std::chrono::duration_cast<std::chrono::milliseconds>(
...@@ -295,6 +307,7 @@ void WimaMeasurementArea::doUpdate() { ...@@ -295,6 +307,7 @@ void WimaMeasurementArea::doUpdate() {
void WimaMeasurementArea::deferUpdate() { void WimaMeasurementArea::deferUpdate() {
if (this->_state == STATE::IDLE || this->_state == STATE::DEFERED) { if (this->_state == STATE::IDLE || this->_state == STATE::DEFERED) {
qCDebug(WimaMeasurementAreaLog) << "defereUpdate(): defer update.";
if (this->_state == STATE::IDLE) { if (this->_state == STATE::IDLE) {
this->_progress.clear(); this->_progress.clear();
this->_tileData.clear(); this->_tileData.clear();
...@@ -303,16 +316,16 @@ void WimaMeasurementArea::deferUpdate() { ...@@ -303,16 +316,16 @@ void WimaMeasurementArea::deferUpdate() {
} }
this->setState(STATE::DEFERED); this->setState(STATE::DEFERED);
this->_timer.start(100); this->_timer.start(100);
} else if (this->_state == STATE::UPDATE) { } else if (this->_state == STATE::UPDATEING) {
setState(STATE::RESTART); qCDebug(WimaMeasurementAreaLog) << "defereUpdate(): restart.";
setState(STATE::RESTARTING);
} }
} }
void WimaMeasurementArea::storeTiles() { void WimaMeasurementArea::storeTiles() {
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
if (this->_state == STATE::UPDATE) { if (this->_state == STATE::UPDATEING) {
qCDebug(WimaMeasurementAreaLog) << "storeTiles(): update."; qCDebug(WimaMeasurementAreaLog) << "storeTiles(): update.";
this->_tileData = *this->_watcher.result(); this->_tileData = *this->_watcher.result();
...@@ -321,10 +334,11 @@ void WimaMeasurementArea::storeTiles() { ...@@ -321,10 +334,11 @@ void WimaMeasurementArea::storeTiles() {
this->progressChanged(); this->progressChanged();
emit this->tilesChanged(); emit this->tilesChanged();
setState(STATE::IDLE); setState(STATE::IDLE);
} else if (this->_state == STATE::RESTART) { } else if (this->_state == STATE::RESTARTING) {
qCDebug(WimaMeasurementAreaLog) << "storeTiles(): restart."; qCDebug(WimaMeasurementAreaLog) << "storeTiles(): restart.";
doUpdate(); doUpdate();
} else if (this->_state == STATE::STOP) {
qCDebug(WimaMeasurementAreaLog) << "storeTiles(): stop.";
} }
qCDebug(WimaMeasurementAreaLog) qCDebug(WimaMeasurementAreaLog)
<< "storeTiles() execution time: " << "storeTiles() execution time: "
...@@ -334,13 +348,24 @@ void WimaMeasurementArea::storeTiles() { ...@@ -334,13 +348,24 @@ void WimaMeasurementArea::storeTiles() {
<< " ms"; << " ms";
} }
void WimaMeasurementArea::disableUpdates() {
setState(STATE::IDLE);
this->_timer.stop();
}
void WimaMeasurementArea::enableUpdates() {
if (this->_state == STATE::STOP) {
setState(STATE::IDLE);
}
}
void WimaMeasurementArea::init() { void WimaMeasurementArea::init() {
this->setObjectName(WimaMeasurementAreaName); this->setObjectName(WimaMeasurementAreaName);
connect(&this->_tileHeight, &Fact::rawValueChanged, this, connect(&this->_tileHeight, &Fact::rawValueChanged, this,
&WimaMeasurementArea::deferUpdate); &WimaMeasurementArea::deferUpdate);
connect(&this->_tileWidth, &Fact::rawValueChanged, this, connect(&this->_tileWidth, &Fact::rawValueChanged, this,
&WimaMeasurementArea::deferUpdate); &WimaMeasurementArea::deferUpdate);
connect(&this->_minTileArea, &Fact::rawValueChanged, this, connect(&this->_minTileAreaPercent, &Fact::rawValueChanged, this,
&WimaMeasurementArea::deferUpdate); &WimaMeasurementArea::deferUpdate);
connect(this, &WimaArea::pathChanged, this, connect(this, &WimaArea::pathChanged, this,
&WimaMeasurementArea::deferUpdate); &WimaMeasurementArea::deferUpdate);
......
...@@ -27,12 +27,7 @@ public: ...@@ -27,12 +27,7 @@ public:
class WimaMeasurementArea : public WimaArea { class WimaMeasurementArea : public WimaArea {
Q_OBJECT Q_OBJECT
enum class STATE { enum class STATE { IDLE, DEFERED, UPDATEING, RESTARTING, STOP };
IDLE,
DEFERED,
UPDATE,
RESTART,
};
public: public:
WimaMeasurementArea(QObject *parent = nullptr); WimaMeasurementArea(QObject *parent = nullptr);
...@@ -71,10 +66,6 @@ public: ...@@ -71,10 +66,6 @@ public:
void saveToJson(QJsonObject &json); void saveToJson(QJsonObject &json);
bool loadFromJson(const QJsonObject &json, QString &errorString); bool loadFromJson(const QJsonObject &json, QString &errorString);
// Friends
friend void print(const WimaMeasurementArea &area, QString outputStr);
friend void print(const WimaMeasurementArea &area);
// Static Variables // Static Variables
static const char *settingsGroup; static const char *settingsGroup;
static const char *tileHeightName; static const char *tileHeightName;
...@@ -98,6 +89,8 @@ private slots: ...@@ -98,6 +89,8 @@ private slots:
void doUpdate(); void doUpdate();
void deferUpdate(); void deferUpdate();
void storeTiles(); void storeTiles();
void disableUpdates();
void enableUpdates();
private: private:
// Member Methodes // Member Methodes
...@@ -109,15 +102,15 @@ private: ...@@ -109,15 +102,15 @@ private:
SettingsFact _tileHeight; SettingsFact _tileHeight;
SettingsFact _tileWidth; SettingsFact _tileWidth;
SettingsFact _minTileArea; SettingsFact _minTileAreaPercent; // 0..100
SettingsFact _showTiles; SettingsFact _showTiles;
QVector<int> _progress;
// Tile stuff. // Tile stuff.
mutable QTimer _timer; mutable QTimer _timer;
using DataPtr = std::shared_ptr<TileData>; using DataPtr = std::shared_ptr<TileData>;
mutable STATE _state;
mutable TileData _tileData; mutable TileData _tileData;
mutable QFutureWatcher<DataPtr> _watcher; mutable QFutureWatcher<DataPtr> _watcher;
mutable STATE _state;
QVector<int> _progress;
}; };
...@@ -18,31 +18,14 @@ ...@@ -18,31 +18,14 @@
"defaultValue": 5 "defaultValue": 5
}, },
{ {
"name": "MinTileArea", "name": "MinTileAreaPercent",
"shortDescription": "The minimal allowed area of a tile", "shortDescription": "The minimal allowed area in percent (of width*height).",
"type": "double", "type": "double",
"units": "m^2", "units": "%",
"min": 0, "min": 0,
"max": 100,
"decimalPlaces": 2, "decimalPlaces": 2,
"defaultValue": 5 "defaultValue": 20
},
{
"name": "TransectDistance",
"shortDescription": "The transect distance",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 2,
"defaultValue": 2
},
{
"name": "MinTransectLength",
"shortDescription": "The minimal transect length",
"type": "double",
"units": "m",
"min": 0,
"decimalPlaces": 2,
"defaultValue": 1
}, },
{ {
"name": "ShowTiles", "name": "ShowTiles",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment