diff --git a/src/TerrainTile.cc b/src/TerrainTile.cc index 539ae9d008211e41d548595a931cef2895852f3f..5c04e5e1a313ef7644c496de6771f2aa6831a6dd 100644 --- a/src/TerrainTile.cc +++ b/src/TerrainTile.cc @@ -53,81 +53,50 @@ TerrainTile::TerrainTile(QByteArray byteArray) , _gridSizeLon(-1) , _isValid(false) { - QDataStream stream(byteArray); + int cTileHeaderBytes = static_cast(sizeof(TileInfo_t)); + int cTileBytesAvailable = byteArray.size(); - float lat,lon; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; + if (cTileBytesAvailable < cTileHeaderBytes) { + qWarning() << "Terrain tile binary data too small for TileInfo_s header"; return; } - stream >> lat; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> lon; - _southWest.setLatitude(lat); - _southWest.setLongitude(lon); - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> lat; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> lon; - _northEast.setLatitude(lat); - _northEast.setLongitude(lon); + const TileInfo_t* tileInfo = reinterpret_cast(byteArray.constData()); + _southWest.setLatitude(tileInfo->swLat); + _southWest.setLongitude(tileInfo->swLon); + _northEast.setLatitude(tileInfo->neLat); + _northEast.setLongitude(tileInfo->neLon); + _minElevation = tileInfo->minElevation; + _maxElevation = tileInfo->maxElevation; + _avgElevation = tileInfo->avgElevation; + _gridSizeLat = tileInfo->gridSizeLat; + _gridSizeLon = tileInfo->gridSizeLon; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> _minElevation; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> _maxElevation; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> _avgElevation; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> _gridSizeLat; - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; + qCDebug(TerrainTileLog) << "Loading terrain tile: " << _southWest << " - " << _northEast; + qCDebug(TerrainTileLog) << "min:max:avg:sizeLat:sizeLon" << _minElevation << _maxElevation << _avgElevation << _gridSizeLat << _gridSizeLon; + + int cTileDataBytes = static_cast(sizeof(int16_t)) * _gridSizeLat * _gridSizeLon; + if (cTileBytesAvailable < cTileHeaderBytes + cTileDataBytes) { + qWarning() << "Terrain tile binary data too small for tile data"; return; } - stream >> _gridSizeLon; - qCDebug(TerrainTileLog) << "Loading terrain tile: " << _southWest << " - " << _northEast; - qCDebug(TerrainTileLog) << "min:max:avg:sizeLat:sizeLon" << _minElevation << _maxElevation << _avgElevation << _gridSizeLat << _gridSizeLon; + _data = new int16_t*[_gridSizeLat]; + for (int k = 0; k < _gridSizeLat; k++) { + _data[k] = new int16_t[_gridSizeLon]; + } + int valueIndex = 0; + const int16_t* pTileData = reinterpret_cast(&reinterpret_cast(byteArray.constData())[cTileHeaderBytes]); for (int i = 0; i < _gridSizeLat; i++) { - if (i == 0) { - _data = new int16_t*[_gridSizeLat]; - for (int k = 0; k < _gridSizeLat; k++) { - _data[k] = new int16_t[_gridSizeLon]; - } - } for (int j = 0; j < _gridSizeLon; j++) { - if (stream.atEnd()) { - qWarning() << "Terrain tile binary data does not contain all data"; - return; - } - stream >> _data[i][j]; + _data[i][j] = pTileData[valueIndex++]; } } _isValid = true; + + return; } @@ -176,8 +145,6 @@ QByteArray TerrainTile::serialize(QByteArray input) return emptyArray; } - QByteArray byteArray; - QDataStream stream(&byteArray, QIODevice::WriteOnly); if (!document.isObject()) { qCDebug(TerrainTileLog) << "Terrain tile json doc is no object"; QByteArray emptyArray; @@ -231,10 +198,6 @@ QByteArray TerrainTile::serialize(QByteArray input) QByteArray emptyArray; return emptyArray; } - stream << static_cast(swArray[0].toDouble()); - stream << static_cast(swArray[1].toDouble()); - stream << static_cast(neArray[0].toDouble()); - stream << static_cast(neArray[1].toDouble()); // Stats const QJsonObject& statsObject = dataObject[_jsonStatsKey].toObject(); @@ -248,30 +211,46 @@ QByteArray TerrainTile::serialize(QByteArray input) QByteArray emptyArray; return emptyArray; } - stream << static_cast(statsObject[_jsonMinElevationKey].toInt()); - stream << static_cast(statsObject[_jsonMaxElevationKey].toInt()); - stream << static_cast(statsObject[_jsonAvgElevationKey].toDouble()); // Carpet const QJsonArray& carpetArray = dataObject[_jsonCarpetKey].toArray(); int gridSizeLat = carpetArray.count(); - stream << static_cast(gridSizeLat); - int gridSizeLon = 0; - qCDebug(TerrainTileLog) << "Received tile has size in latitude direction: " << carpetArray.count(); + int gridSizeLon = carpetArray[0].toArray().count(); + qCDebug(TerrainTileLog) << "Received tile has size in latitude direction: " << gridSizeLat; + qCDebug(TerrainTileLog) << "Received tile has size in longitued direction: " << gridSizeLon; + + TileInfo_t tileInfo; + + tileInfo.swLat = swArray[0].toDouble(); + tileInfo.swLon = swArray[1].toDouble(); + tileInfo.neLat = neArray[0].toDouble(); + tileInfo.neLon = neArray[1].toDouble(); + tileInfo.minElevation = static_cast(statsObject[_jsonMinElevationKey].toInt()); + tileInfo.maxElevation = static_cast(statsObject[_jsonMaxElevationKey].toInt()); + tileInfo.avgElevation = statsObject[_jsonAvgElevationKey].toDouble(); + tileInfo.gridSizeLat = static_cast(gridSizeLat); + tileInfo.gridSizeLon = static_cast(gridSizeLon); + + int cTileHeaderBytes = static_cast(sizeof(TileInfo_t)); + int cTileDataBytes = static_cast(sizeof(int16_t)) * gridSizeLat * gridSizeLon; + + QByteArray byteArray(cTileHeaderBytes + cTileDataBytes, 0); + + TileInfo_t* pTileInfo = reinterpret_cast(byteArray.data()); + int16_t* pTileData = reinterpret_cast(&reinterpret_cast(byteArray.data())[cTileHeaderBytes]); + + *pTileInfo = tileInfo; + + int valueIndex = 0; for (int i = 0; i < gridSizeLat; i++) { const QJsonArray& row = carpetArray[i].toArray(); - if (i == 0) { - gridSizeLon = row.count(); - stream << static_cast(gridSizeLon); - qCDebug(TerrainTileLog) << "Received tile has size in longitued direction: " << row.count(); - } if (row.count() < gridSizeLon) { qCDebug(TerrainTileLog) << "Expected row array of " << gridSizeLon << ", instead got " << row.count(); QByteArray emptyArray; return emptyArray; } for (int j = 0; j < gridSizeLon; j++) { - stream << static_cast(row[j].toDouble()); + pTileData[valueIndex++] = static_cast(row[j].toDouble()); } } diff --git a/src/TerrainTile.h b/src/TerrainTile.h index adf217df8574e6f8f601d43aa3a3c6a6905ef4e4..3de3565f2c63bb58203992a99a1bccafb1185150 100644 --- a/src/TerrainTile.h +++ b/src/TerrainTile.h @@ -95,6 +95,15 @@ public: static constexpr double terrainAltitudeSpacing = 30.0; private: + typedef struct { + double swLat,swLon, neLat, neLon; + int16_t minElevation; + int16_t maxElevation; + double avgElevation; + int16_t gridSizeLat; + int16_t gridSizeLon; + } TileInfo_t; + inline int _latToDataIndex(double latitude) const; inline int _lonToDataIndex(double longitude) const; @@ -103,7 +112,7 @@ private: int16_t _minElevation; /// Minimum elevation in tile int16_t _maxElevation; /// Maximum elevation in tile - float _avgElevation; /// Average elevation of the tile + double _avgElevation; /// Average elevation of the tile int16_t** _data; /// 2D elevation data array int16_t _gridSizeLat; /// data grid size in latitude direction