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