Commit 6bb01ff3 authored by Andreas Bircher's avatar Andreas Bircher

make offline caching working serialized as well

parent 5c72de31
......@@ -19,6 +19,7 @@
#include "QGCMapEngine.h"
#include "QGCMapTileSet.h"
#include "QGCMapEngineManager.h"
#include "TerrainTile.h"
#include <QSettings>
#include <math.h>
......@@ -282,6 +283,9 @@ QGCCachedTileSet::_networkReplyFinished()
qCDebug(QGCCachedTileSetLog) << "Tile fetched" << hash;
QByteArray image = reply->readAll();
UrlFactory::MapType type = getQGCMapEngine()->hashToType(hash);
if (type == UrlFactory::MapType::AirmapElevation) {
image = TerrainTile::serialize(image);
}
QString format = getQGCMapEngine()->urlFactory()->getImageFormat(type, image);
if(!format.isEmpty()) {
//-- Cache tile
......
......@@ -36,7 +36,6 @@
static const unsigned char pngSignature[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00};
static const unsigned char jpegSignature[] = {0xFF, 0xD8, 0xFF, 0x00};
static const unsigned char gifSignature[] = {0x47, 0x49, 0x46, 0x38, 0x00};
static const unsigned char jsonSignature[] = {0x7B, 0x22, 0x00}; // two characters '{"'
//-----------------------------------------------------------------------------
UrlFactory::UrlFactory()
......@@ -86,8 +85,6 @@ UrlFactory::getImageFormat(MapType type, const QByteArray& image)
format = "jpg";
else if (image.startsWith(reinterpret_cast<const char*>(gifSignature)))
format = "gif";
else if (image.startsWith(reinterpret_cast<const char*>(jsonSignature)))
format = "json";
else {
switch (type) {
case GoogleMap:
......@@ -126,7 +123,7 @@ UrlFactory::getImageFormat(MapType type, const QByteArray& image)
format = "jpg";
break;
case AirmapElevation:
format = "json";
format = "bin";
break;
default:
qWarning("UrlFactory::getImageFormat() Unknown map id %d", type);
......@@ -563,7 +560,7 @@ UrlFactory::_tryCorrectGoogleVersions(QNetworkAccessManager* networkManager)
#define AVERAGE_MAPBOX_SAT_MAP 15739
#define AVERAGE_MAPBOX_STREET_MAP 5648
#define AVERAGE_TILE_SIZE 13652
#define AVERAGE_AIRMAP_ELEV_SIZE 5360
#define AVERAGE_AIRMAP_ELEV_SIZE 2786
//-----------------------------------------------------------------------------
quint32
......
......@@ -398,6 +398,8 @@ void TerrainTileManager::_fetchedTile()
// parse received data and insert into hash table
QByteArray responseBytes = reply->mapImageData();
qWarning() << "Received some bytes of terrain data: " << responseBytes.size();
TerrainTile* terrainTile = new TerrainTile(responseBytes);
if (terrainTile->isValid()) {
_tilesMutex.lock();
......
......@@ -87,7 +87,7 @@ private:
bool _carpetStatsOnly;
};
/// AirMap online implementation of terrain queries
/// AirMap offline cachable implementation of terrain queries
class TerrainOfflineAirMapQuery : public TerrainQueryInterface {
Q_OBJECT
......@@ -99,12 +99,10 @@ public:
void requestPathHeights(const QGeoCoordinate& fromCoord, const QGeoCoordinate& toCoord) final;
void requestCarpetHeights(const QGeoCoordinate& swCoord, const QGeoCoordinate& neCoord, bool statsOnly) final;
// Internal method
// Internal methods
void _signalCoordinateHeights(bool success, QList<double> heights);
void _signalPathHeights(bool success, double latStep, double lonStep, const QList<double>& heights);
void _signalCarpetHeights(bool success, double minHeight, double maxHeight, const QList<QList<double>>& carpet);
bool _carpetStatsOnly;
};
/// Used internally by TerrainOfflineAirMapQuery to manage terrain tiles
......
......@@ -55,31 +55,38 @@ TerrainTile::TerrainTile(QByteArray byteArray)
{
QDataStream stream(byteArray);
double lat,lon;
float lat,lon;
stream >> lat
>> lon;
>> lon;
_southWest.setLatitude(lat);
_southWest.setLongitude(lon);
stream >> lat
>> lon;
>> lon;
_northEast.setLatitude(lat);
_northEast.setLongitude(lon);
stream >> _minElevation
>> _maxElevation
>> _avgElevation
>> _gridSizeLat
>> _gridSizeLon;
>> _maxElevation
>> _avgElevation
>> _gridSizeLat
>> _gridSizeLon;
qCDebug(TerrainTileLog) << "Loading terrain tile: " << _southWest << " - " << _northEast;
qCDebug(TerrainTileLog) << "min:max:avg:sizeLat:sizeLon" << _minElevation << _maxElevation << _avgElevation << _gridSizeLat << _gridSizeLon;
for (int i = 0; i < _gridSizeLat; i++) {
if (i == 0) {
_data = new double*[_gridSizeLat];
_data = new int16_t*[_gridSizeLat];
for (int k = 0; k < _gridSizeLat; k++) {
_data[k] = new double[_gridSizeLon];
_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];
}
}
......@@ -108,7 +115,7 @@ double TerrainTile::elevation(const QGeoCoordinate& coordinate) const
int indexLat = _latToDataIndex(coordinate.latitude());
int indexLon = _lonToDataIndex(coordinate.longitude());
qCDebug(TerrainTileLog) << "indexLat:indexLon" << indexLat << indexLon << "elevation" << _data[indexLat][indexLon];
return _data[indexLat][indexLon];
return static_cast<double>(_data[indexLat][indexLon]);
} else {
qCDebug(TerrainTileLog) << "Asking for elevation, but no valid data.";
return -1.0;
......@@ -141,7 +148,7 @@ QByteArray TerrainTile::serialize(QByteArray input)
QString errorString;
QList<JsonHelper::KeyValidateInfo> rootVersionKeyInfoList = {
{ _jsonStatusKey, QJsonValue::String, true },
{ _jsonDataKey, QJsonValue::Object, true },
{ _jsonDataKey, QJsonValue::Object, true },
};
if (!JsonHelper::validateKeys(rootObject, rootVersionKeyInfoList, errorString)) {
qCDebug(TerrainTileLog) << "Error in reading json: " << errorString;
......@@ -157,7 +164,7 @@ QByteArray TerrainTile::serialize(QByteArray input)
const QJsonObject& dataObject = rootObject[_jsonDataKey].toObject();
QList<JsonHelper::KeyValidateInfo> dataVersionKeyInfoList = {
{ _jsonBoundsKey, QJsonValue::Object, true },
{ _jsonStatsKey, QJsonValue::Object, true },
{ _jsonStatsKey, QJsonValue::Object, true },
{ _jsonCarpetKey, QJsonValue::Array, true },
};
if (!JsonHelper::validateKeys(dataObject, dataVersionKeyInfoList, errorString)) {
......@@ -184,16 +191,16 @@ QByteArray TerrainTile::serialize(QByteArray input)
QByteArray emptyArray;
return emptyArray;
}
stream << swArray[0].toDouble();
stream << swArray[1].toDouble();
stream << neArray[0].toDouble();
stream << neArray[1].toDouble();
stream << static_cast<float>(swArray[0].toDouble());
stream << static_cast<float>(swArray[1].toDouble());
stream << static_cast<float>(neArray[0].toDouble());
stream << static_cast<float>(neArray[1].toDouble());
// Stats
const QJsonObject& statsObject = dataObject[_jsonStatsKey].toObject();
QList<JsonHelper::KeyValidateInfo> statsVersionKeyInfoList = {
{ _jsonMaxElevationKey, QJsonValue::Double, true },
{ _jsonMinElevationKey, QJsonValue::Double, true },
{ _jsonMaxElevationKey, QJsonValue::Double, true },
{ _jsonAvgElevationKey, QJsonValue::Double, true },
};
if (!JsonHelper::validateKeys(statsObject, statsVersionKeyInfoList, errorString)) {
......@@ -201,21 +208,21 @@ QByteArray TerrainTile::serialize(QByteArray input)
QByteArray emptyArray;
return emptyArray;
}
stream << statsObject[_jsonMaxElevationKey].toInt();
stream << statsObject[_jsonMinElevationKey].toInt();
stream << statsObject[_jsonAvgElevationKey].toDouble();
stream << static_cast<int16_t>(statsObject[_jsonMinElevationKey].toInt());
stream << static_cast<int16_t>(statsObject[_jsonMaxElevationKey].toInt());
stream << static_cast<float>(statsObject[_jsonAvgElevationKey].toDouble());
// Carpet
const QJsonArray& carpetArray = dataObject[_jsonCarpetKey].toArray();
int gridSizeLat = carpetArray.count();
stream << gridSizeLat;
stream << static_cast<int16_t>(gridSizeLat);
int gridSizeLon = 0;
qCDebug(TerrainTileLog) << "Received tile has size in latitude direction: " << carpetArray.count();
for (int i = 0; i < gridSizeLat; i++) {
const QJsonArray& row = carpetArray[i].toArray();
if (i == 0) {
gridSizeLon = row.count();
stream << gridSizeLon;
stream << static_cast<int16_t>(gridSizeLon);
qCDebug(TerrainTileLog) << "Received tile has size in longitued direction: " << row.count();
}
if (row.count() < gridSizeLon) {
......@@ -224,7 +231,7 @@ QByteArray TerrainTile::serialize(QByteArray input)
return emptyArray;
}
for (int j = 0; j < gridSizeLon; j++) {
stream << row[j].toDouble();
stream << static_cast<int16_t>(row[j].toDouble());
}
}
......
......@@ -101,13 +101,13 @@ private:
QGeoCoordinate _southWest; /// South west corner of the tile
QGeoCoordinate _northEast; /// North east corner of the tile
int _minElevation; /// Minimum elevation in tile
int _maxElevation; /// Maximum elevation in tile
double _avgElevation; /// Average elevation of the tile
int16_t _minElevation; /// Minimum elevation in tile
int16_t _maxElevation; /// Maximum elevation in tile
float _avgElevation; /// Average elevation of the tile
double** _data; /// 2D elevation data array
int _gridSizeLat; /// data grid size in latitude direction
int _gridSizeLon; /// data grid size in longitude direction
int16_t** _data; /// 2D elevation data array
int16_t _gridSizeLat; /// data grid size in latitude direction
int16_t _gridSizeLon; /// data grid size in longitude direction
bool _isValid; /// data loaded is valid
// Json keys
......
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