WimaMeasurementArea.cc 8.7 KB
Newer Older
1
#include "WimaMeasurementArea.h"
Valentin Platzgummer's avatar
Valentin Platzgummer committed
2 3 4 5
#include "SnakeTile.h"
#include "snake.h"

#include <boost/units/systems/si.hpp>
6

7
const char *WimaMeasurementArea::settingsGroup = "MeasurementArea";
Valentin Platzgummer's avatar
Valentin Platzgummer committed
8 9 10 11 12 13
const char *WimaMeasurementArea::tileHeightName = "TileHeight";
const char *WimaMeasurementArea::tileWidthName = "TileWidth";
const char *WimaMeasurementArea::minTileAreaName = "MinTileArea";
const char *WimaMeasurementArea::transectDistanceName = "TransectDistance";
const char *WimaMeasurementArea::minTransectLengthName = "MinTransectLength";
const char *WimaMeasurementArea::showTilesName = "ShowTiles";
14
const char *WimaMeasurementArea::WimaMeasurementAreaName = "Measurement Area";
Valentin Platzgummer's avatar
Valentin Platzgummer committed
15 16

WimaMeasurementArea::WimaMeasurementArea(QObject *parent)
17 18 19 20
    : WimaArea(parent),
      _metaDataMap(FactMetaData::createMapFromJsonFile(
          QStringLiteral(":/json/WimaMeasurementArea.SettingsGroup.json"),
          this /* QObject parent */)),
Valentin Platzgummer's avatar
Valentin Platzgummer committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
      _tileHeight(SettingsFact(settingsGroup, _metaDataMap[tileHeightName],
                               this /* QObject parent */)),
      _tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName],
                              this /* QObject parent */)),
      _minTileArea(SettingsFact(settingsGroup, _metaDataMap[minTileAreaName],
                                this /* QObject parent */)),
      _transectDistance(SettingsFact(settingsGroup,
                                     _metaDataMap[transectDistanceName],
                                     this /* QObject parent */)),
      _minTransectLength(SettingsFact(settingsGroup,
                                      _metaDataMap[minTransectLengthName],
                                      this /* QObject parent */)),
      _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName],
                              this /* QObject parent */)),
      _calculating(false) {
36
  init();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
37 38
}

39 40 41 42 43 44
WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other,
                                         QObject *parent)
    : WimaArea(other, parent),
      _metaDataMap(FactMetaData::createMapFromJsonFile(
          QStringLiteral(":/json/WimaMeasurementArea.SettingsGroup.json"),
          this /* QObject parent */)),
Valentin Platzgummer's avatar
Valentin Platzgummer committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
      _tileHeight(SettingsFact(settingsGroup, _metaDataMap[tileHeightName],
                               this /* QObject parent */)),
      _tileWidth(SettingsFact(settingsGroup, _metaDataMap[tileWidthName],
                              this /* QObject parent */)),
      _minTileArea(SettingsFact(settingsGroup, _metaDataMap[minTileAreaName],
                                this /* QObject parent */)),
      _transectDistance(SettingsFact(settingsGroup,
                                     _metaDataMap[transectDistanceName],
                                     this /* QObject parent */)),
      _minTransectLength(SettingsFact(settingsGroup,
                                      _metaDataMap[minTransectLengthName],
                                      this /* QObject parent */)),
      _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName],
                              this /* QObject parent */)),
      _calculating(false) {
60
  init();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
61 62
}

63 64 65 66 67
/*!
 * \overload operator=()
 *
 * Calls the inherited operator WimaArea::operator=().
 */
68 69 70 71 72 73 74
WimaMeasurementArea &WimaMeasurementArea::
operator=(const WimaMeasurementArea &other) {
  WimaArea::operator=(other);

  return *this;
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
75 76 77 78
WimaMeasurementArea::~WimaMeasurementArea() {
  this->_tiles.clearAndDeleteContents();
}

79 80 81
QString WimaMeasurementArea::mapVisualQML() const {
  return "WimaMeasurementAreaMapVisual.qml";
}
82

83 84
QString WimaMeasurementArea::editorQML() const {
  return "WimaMeasurementAreaEditor.qml";
85 86
}

87 88
Fact *WimaMeasurementArea::tileHeight() { return &_tileHeight; }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
89 90 91 92 93 94 95 96 97 98
Fact *WimaMeasurementArea::tileWidth() { return &_tileWidth; }

Fact *WimaMeasurementArea::minTileArea() { return &_minTileArea; }

Fact *WimaMeasurementArea::transectDistance() { return &_transectDistance; }

Fact *WimaMeasurementArea::minTransectLength() { return &_minTransectLength; }

Fact *WimaMeasurementArea::showTiles() { return &_showTiles; }

99 100
void WimaMeasurementArea::saveToJson(QJsonObject &json) {
  this->WimaArea::saveToJson(json);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
101 102 103 104 105 106
  json[tileHeightName] = _tileHeight.rawValue().toDouble();
  json[tileWidthName] = _tileWidth.rawValue().toDouble();
  json[minTileAreaName] = _minTileArea.rawValue().toDouble();
  json[transectDistanceName] = _transectDistance.rawValue().toDouble();
  json[minTransectLengthName] = _minTransectLength.rawValue().toDouble();
  json[showTilesName] = _showTiles.rawValue().toBool();
107
  json[areaTypeName] = WimaMeasurementAreaName;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
108 109
}

110 111 112 113 114
bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
                                       QString &errorString) {
  if (this->WimaArea::loadFromJson(json, errorString)) {
    bool retVal = true;

Valentin Platzgummer's avatar
Valentin Platzgummer committed
115 116
    if (json.contains(tileHeightName) && json[tileHeightName].isDouble()) {
      _tileHeight.setRawValue(json[tileHeightName].toDouble());
Valentin Platzgummer's avatar
Valentin Platzgummer committed
117
    } else {
Valentin Platzgummer's avatar
Valentin Platzgummer committed
118
      errorString.append(tr("Could not load tile height!\n"));
119
      retVal = false;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
120 121
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
122 123
    if (json.contains(tileWidthName) && json[tileWidthName].isDouble()) {
      _tileHeight.setRawValue(json[tileWidthName].toDouble());
124
    } else {
Valentin Platzgummer's avatar
Valentin Platzgummer committed
125
      errorString.append(tr("Could not load tile width!\n"));
126 127
      retVal = false;
    }
128

Valentin Platzgummer's avatar
Valentin Platzgummer committed
129 130
    if (json.contains(minTileAreaName) && json[minTileAreaName].isDouble()) {
      _tileHeight.setRawValue(json[minTileAreaName].toDouble());
131
    } else {
Valentin Platzgummer's avatar
Valentin Platzgummer committed
132
      errorString.append(tr("Could not load minimal tile area!\n"));
133
      retVal = false;
134
    }
135

Valentin Platzgummer's avatar
Valentin Platzgummer committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    if (json.contains(transectDistanceName) &&
        json[transectDistanceName].isDouble()) {
      _tileHeight.setRawValue(json[transectDistanceName].toDouble());
    } else {
      errorString.append(tr("Could not load transect distance!\n"));
      retVal = false;
    }

    if (json.contains(minTransectLengthName) &&
        json[minTransectLengthName].isDouble()) {
      _tileHeight.setRawValue(json[minTransectLengthName].toDouble());
    } else {
      errorString.append(tr("Could not load minimal transect length!\n"));
      retVal = false;
    }

    if (json.contains(showTilesName) && json[showTilesName].isBool()) {
      _tileHeight.setRawValue(json[showTilesName].toDouble());
    } else {
      errorString.append(tr("Could not load show tiles !\n"));
      retVal = false;
    }
158 159 160 161
    return retVal;
  } else {
    return false;
  }
162 163
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
164 165 166 167 168 169 170 171 172
void WimaMeasurementArea::doUpdate() {
  using namespace snake;
  using namespace boost::units;
#ifdef SNAKE_SHOW_TIME
  auto start = std::chrono::high_resolution_clock::now();
#endif
  auto polygon = this->coordinateList();
  for (auto &v : polygon) {
    v.setAltitude(0);
173
  }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
  if (polygon.size() > 3) {
    QGeoCoordinate origin = polygon.first();
    BoostPolygon polygonENU;
    areaToEnu(origin, polygon, polygonENU);
    Length height = this->_tileHeight.rawValue().toDouble() * si::meter;
    Length width = this->_tileWidth.rawValue().toDouble() * si::meter;
    Area minArea =
        this->_minTileArea.rawValue().toDouble() * si::meter * si::meter;
    std::vector<BoostPolygon> tilesENU;
    BoundingBox bbox;
    std::string errorString;
    if (snake::tiles(polygonENU, height, width, minArea, tilesENU, bbox,
                     errorString)) {
      this->_tiles.clearAndDeleteContents();
      for (const auto &t : tilesENU) {
        auto geoTile = new SnakeTile(&this->_tiles);
        for (const auto &v : t.outer()) {
          QGeoCoordinate geoVertex;
          fromENU(origin, v, geoVertex);
          geoTile->push_back(geoVertex);
        }
        this->_tiles.append(geoTile);
      }
    }
198
  }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
199 200 201 202 203 204 205
#ifdef SNAKE_SHOW_TIME
  qDebug() << "WimaMeasurementArea::doUpdate execution time: "
           << std::chrono::duration_cast<std::chrono::milliseconds>(
                  std::chrono::high_resolution_clock::now() - start)
                  .count()
           << " ms";
#endif
Valentin Platzgummer's avatar
Valentin Platzgummer committed
206 207
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
208 209 210
void WimaMeasurementArea::deferUpdate() {
  if (this->_timer.isActive()) {
    this->_timer.stop();
211
  }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
212
  this->_timer.start(100);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
213 214
}

215 216
void WimaMeasurementArea::init() {
  this->setObjectName(WimaMeasurementAreaName);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
217 218 219 220 221 222 223 224 225 226 227
  connect(&this->_tileHeight, &Fact::rawValueChanged, this,
          &WimaMeasurementArea::deferUpdate);
  connect(&this->_tileWidth, &Fact::rawValueChanged, this,
          &WimaMeasurementArea::deferUpdate);
  connect(&this->_minTileArea, &Fact::rawValueChanged, this,
          &WimaMeasurementArea::deferUpdate);
  connect(this, &WimaArea::pathChanged, this,
          &WimaMeasurementArea::deferUpdate);
  this->_timer.setSingleShot(true);
  connect(&this->_timer, &QTimer::timeout, this,
          &WimaMeasurementArea::doUpdate);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
228 229
}

230 231
/*!
 * \class WimaMeasurementArea
232 233
 * \brief Class defining the area inside which the actual drone measurements are
 * performed.
234 235 236
 *
 * \sa WimaArea, WimaController, WimaPlaner
 */