Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
5fb4a54f
Commit
5fb4a54f
authored
Nov 23, 2017
by
Andreas Bircher
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
load tiles from cache if available
parent
83643d68
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
122 deletions
+60
-122
QGeoMapReplyQGC.cpp
src/QtLocationPlugin/QGeoMapReplyQGC.cpp
+3
-0
Terrain.cc
src/Terrain.cc
+49
-106
Terrain.h
src/Terrain.h
+4
-12
TerrainTile.cc
src/TerrainTile.cc
+4
-4
No files found.
src/QtLocationPlugin/QGeoMapReplyQGC.cpp
View file @
5fb4a54f
...
...
@@ -112,9 +112,11 @@ QGeoTiledMapReplyQGC::networkReplyFinished()
{
_timer
.
stop
();
if
(
!
_reply
)
{
abort
();
return
;
}
if
(
_reply
->
error
()
!=
QNetworkReply
::
NoError
)
{
abort
();
return
;
}
QByteArray
a
=
_reply
->
readAll
();
...
...
@@ -195,4 +197,5 @@ QGeoTiledMapReplyQGC::timeout()
if
(
_reply
)
{
_reply
->
abort
();
}
abort
();
}
src/Terrain.cc
View file @
5fb4a54f
...
...
@@ -9,6 +9,8 @@
#include "Terrain.h"
#include "QGCMapEngine.h"
#include "QGeoMapReplyQGC.h"
#include <QtLocation/private/qgeotilespec_p.h>
#include <QUrl>
#include <QUrlQuery>
...
...
@@ -75,16 +77,31 @@ bool ElevationProvider::queryTerrainData(const QList<QGeoCoordinate>& coordinate
QList
<
float
>
altitudes
;
bool
needToDownload
=
false
;
foreach
(
QGeoCoordinate
coordinate
,
coordinates
)
{
QString
uniqueTileId
=
_uniqueTileId
(
coordinate
);
QString
tileHash
=
_getTileHash
(
coordinate
);
_tilesMutex
.
lock
();
if
(
!
_tiles
.
contains
(
uniqueTileId
))
{
qCDebug
(
TerrainLog
)
<<
"Need to download tile "
<<
uniqueTileId
;
_downloadQueue
.
append
(
uniqueTileId
);
if
(
!
_tiles
.
contains
(
tileHash
))
{
qCDebug
(
TerrainLog
)
<<
"Need to download tile "
<<
tileHash
;
if
(
!
_downloadQueue
.
contains
(
tileHash
))
{
// Schedule the fetch task
QNetworkRequest
request
=
getQGCMapEngine
()
->
urlFactory
()
->
getTileURL
(
UrlFactory
::
AirmapElevation
,
QGCMapEngine
::
long2elevationTileX
(
coordinate
.
longitude
(),
1
),
QGCMapEngine
::
lat2elevationTileY
(
coordinate
.
latitude
(),
1
),
1
,
&
_networkManager
);
QGeoTileSpec
spec
;
spec
.
setX
(
QGCMapEngine
::
long2elevationTileX
(
coordinate
.
longitude
(),
1
));
spec
.
setY
(
QGCMapEngine
::
lat2elevationTileY
(
coordinate
.
latitude
(),
1
));
spec
.
setZoom
(
1
);
spec
.
setMapId
(
UrlFactory
::
AirmapElevation
);
QGeoTiledMapReplyQGC
*
reply
=
new
QGeoTiledMapReplyQGC
(
&
_networkManager
,
request
,
spec
);
connect
(
reply
,
&
QGeoTiledMapReplyQGC
::
finished
,
this
,
&
ElevationProvider
::
_fetchedTile
);
connect
(
reply
,
&
QGeoTiledMapReplyQGC
::
aborted
,
this
,
&
ElevationProvider
::
_fetchedTile
);
_downloadQueue
.
append
(
tileHash
);
}
needToDownload
=
true
;
}
else
{
if
(
!
needToDownload
)
{
if
(
_tiles
[
uniqueTileId
].
isIn
(
coordinate
))
{
altitudes
.
push_back
(
_tiles
[
uniqueTileId
].
elevation
(
coordinate
));
if
(
_tiles
[
tileHash
].
isIn
(
coordinate
))
{
altitudes
.
push_back
(
_tiles
[
tileHash
].
elevation
(
coordinate
));
}
else
{
qCDebug
(
TerrainLog
)
<<
"Error: coordinate not in tile region"
;
altitudes
.
push_back
(
-
1.0
);
...
...
@@ -103,39 +120,7 @@ bool ElevationProvider::queryTerrainData(const QList<QGeoCoordinate>& coordinate
_coordinates
=
coordinates
;
_downloadTiles
();
return
true
;
}
bool
ElevationProvider
::
cacheTerrainTiles
(
const
QGeoCoordinate
&
southWest
,
const
QGeoCoordinate
&
northEast
)
{
qCDebug
(
TerrainLog
)
<<
"Cache terrain tiles southWest:northEast"
<<
southWest
<<
northEast
;
// Correct corners of the tile to fixed grid
QGeoCoordinate
southWestCorrected
;
southWestCorrected
.
setLatitude
(
floor
(
southWest
.
latitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
southWestCorrected
.
setLongitude
(
floor
(
southWest
.
longitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
QGeoCoordinate
northEastCorrected
;
northEastCorrected
.
setLatitude
(
ceil
(
northEast
.
latitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
northEastCorrected
.
setLongitude
(
ceil
(
northEast
.
longitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
// Add all tiles to download queue
for
(
double
lat
=
southWestCorrected
.
latitude
()
+
QGCMapEngine
::
srtm1TileSize
/
2.0
;
lat
<
northEastCorrected
.
latitude
();
lat
+=
QGCMapEngine
::
srtm1TileSize
)
{
for
(
double
lon
=
southWestCorrected
.
longitude
()
+
QGCMapEngine
::
srtm1TileSize
/
2.0
;
lon
<
northEastCorrected
.
longitude
();
lon
+=
QGCMapEngine
::
srtm1TileSize
)
{
QString
uniqueTileId
=
_uniqueTileId
(
QGeoCoordinate
(
lat
,
lon
));
_tilesMutex
.
lock
();
if
(
_downloadQueue
.
contains
(
uniqueTileId
)
||
_tiles
.
contains
(
uniqueTileId
))
{
_tilesMutex
.
unlock
();
continue
;
}
_downloadQueue
.
append
(
uniqueTileId
);
_tilesMutex
.
unlock
();
qCDebug
(
TerrainLog
)
<<
"Adding tile to download queue: "
<<
uniqueTileId
;
}
}
_downloadTiles
();
return
true
;
return
false
;
}
void
ElevationProvider
::
_requestFinished
()
...
...
@@ -176,93 +161,51 @@ void ElevationProvider::_requestFinished()
emit
terrainData
(
false
,
altitudes
);
}
void
ElevationProvider
::
_
requestFinis
hedTile
()
void
ElevationProvider
::
_
fetc
hedTile
()
{
QNetworkReply
*
reply
=
qobject_cast
<
QNetworkReply
*>
(
QObject
::
sender
());
_state
=
State
::
Idle
;
QGeoTiledMapReplyQGC
*
reply
=
qobject_cast
<
QGeoTiledMapReplyQGC
*>
(
QObject
::
sender
());
// When an error occurs we still end up here
if
(
reply
->
error
()
!=
QNetworkReply
::
NoError
)
{
QByteArray
responseBytes
=
reply
->
readAll
();
QJsonParseError
parseError
;
QJsonDocument
responseJson
=
QJsonDocument
::
fromJson
(
responseBytes
,
&
parseError
);
qCDebug
(
TerrainLog
)
<<
"ERROR: Received "
<<
responseJson
;
// TODO (birchera): Handle error in downloading data
_downloadTiles
();
if
(
!
reply
||
!
reply
->
isFinished
())
{
if
(
reply
)
{
qCDebug
(
TerrainLog
)
<<
"Error in fetching elevation tile: "
<<
reply
->
errorString
();
reply
->
deleteLater
();
}
else
{
qCDebug
(
TerrainLog
)
<<
"Elevation tile fetched but invalid reply data type."
;
}
return
;
}
QByteArray
responseBytes
=
reply
->
readAll
();
QByteArray
responseBytes
=
reply
->
mapImageData
();
QJsonParseError
parseError
;
QJsonDocument
responseJson
=
QJsonDocument
::
fromJson
(
responseBytes
,
&
parseError
);
if
(
parseError
.
error
!=
QJsonParseError
::
NoError
)
{
// TODO (birchera): Handle error in downloading data
_downloadTiles
();
qCDebug
(
TerrainLog
)
<<
"Could not parse terrain tile "
<<
parseError
.
errorString
();
qCDebug
(
TerrainLog
)
<<
responseBytes
;
reply
->
deleteLater
();
return
;
}
TerrainTile
*
tile
=
new
TerrainTile
(
responseJson
);
if
(
tile
->
isValid
())
{
TerrainTile
*
t
errainT
ile
=
new
TerrainTile
(
responseJson
);
if
(
t
errainT
ile
->
isValid
())
{
_tilesMutex
.
lock
();
if
(
!
_tiles
.
contains
(
_
uniqueTileId
(
t
ile
->
centerCoordinate
())))
{
_tiles
.
insert
(
_
uniqueTileId
(
tile
->
centerCoordinate
()),
*
t
ile
);
if
(
!
_tiles
.
contains
(
_
getTileHash
(
terrainT
ile
->
centerCoordinate
())))
{
_tiles
.
insert
(
_
getTileHash
(
terrainTile
->
centerCoordinate
()),
*
terrainT
ile
);
}
else
{
delete
tile
;
delete
t
errainT
ile
;
}
_tilesMutex
.
unlock
();
}
_downloadTiles
();
}
void
ElevationProvider
::
_downloadTiles
(
void
)
{
if
(
_state
==
State
::
Idle
&&
_downloadQueue
.
count
()
>
0
)
{
QUrlQuery
query
;
_tilesMutex
.
lock
();
qCDebug
(
TerrainLog
)
<<
"Starting download for "
<<
_downloadQueue
.
first
();
query
.
addQueryItem
(
QStringLiteral
(
"points"
),
_downloadQueue
.
first
().
replace
(
"_"
,
","
));
_downloadQueue
.
pop_front
();
_tilesMutex
.
unlock
();
QUrl
url
(
QStringLiteral
(
"https://api.airmap.com/elevation/stage/srtm1/ele/carpet"
));
url
.
setQuery
(
query
);
qWarning
()
<<
"url"
<<
url
;
QNetworkRequest
request
(
url
);
QNetworkProxy
tProxy
;
tProxy
.
setType
(
QNetworkProxy
::
DefaultProxy
);
_networkManager
.
setProxy
(
tProxy
);
QNetworkReply
*
networkReply
=
_networkManager
.
get
(
request
);
if
(
!
networkReply
)
{
return
;
if
(
_downloadQueue
.
contains
(
_getTileHash
(
terrainTile
->
centerCoordinate
())))
{
_downloadQueue
.
removeOne
(
_getTileHash
(
terrainTile
->
centerCoordinate
()));
}
connect
(
networkReply
,
&
QNetworkReply
::
finished
,
this
,
&
ElevationProvider
::
_requestFinishedTile
);
_state
=
State
::
Downloading
;
}
else
if
(
_state
==
State
::
Idle
&&
_coordinates
.
length
()
>
0
)
{
queryTerrainData
(
_coordinates
);
_tilesMutex
.
unlock
();
}
reply
->
deleteLater
();
}
QString
ElevationProvider
::
_
uniqueTileId
(
const
QGeoCoordinate
&
coordinate
)
QString
ElevationProvider
::
_
getTileHash
(
const
QGeoCoordinate
&
coordinate
)
{
// Compute corners of the tile
QGeoCoordinate
southWest
;
southWest
.
setLatitude
(
floor
(
coordinate
.
latitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
southWest
.
setLongitude
(
floor
(
coordinate
.
longitude
()
/
QGCMapEngine
::
srtm1TileSize
)
*
QGCMapEngine
::
srtm1TileSize
);
QGeoCoordinate
northEast
;
northEast
.
setLatitude
(
floor
(
coordinate
.
latitude
()
/
QGCMapEngine
::
srtm1TileSize
+
1
)
*
QGCMapEngine
::
srtm1TileSize
);
northEast
.
setLongitude
(
floor
(
coordinate
.
longitude
()
/
QGCMapEngine
::
srtm1TileSize
+
1
)
*
QGCMapEngine
::
srtm1TileSize
);
// Generate uniquely identifying string
QString
ret
=
QString
::
number
(
southWest
.
latitude
(),
'f'
,
6
)
+
"_"
+
QString
::
number
(
southWest
.
longitude
(),
'f'
,
6
)
+
"_"
+
QString
::
number
(
northEast
.
latitude
(),
'f'
,
6
)
+
"_"
+
QString
::
number
(
northEast
.
longitude
(),
'f'
,
6
);
qCDebug
(
TerrainLog
)
<<
"Computing unique tile id for "
<<
coordinate
<<
ret
;
QString
ret
=
QGCMapEngine
::
getTileHash
(
UrlFactory
::
AirmapElevation
,
QGCMapEngine
::
long2elevationTileX
(
coordinate
.
longitude
(),
1
),
QGCMapEngine
::
lat2elevationTileY
(
coordinate
.
latitude
(),
1
),
1
);
qCDebug
(
TerrainLog
)
<<
"Computing unique tile hash for "
<<
coordinate
<<
ret
;
return
ret
;
}
src/Terrain.h
View file @
5fb4a54f
...
...
@@ -10,6 +10,7 @@
#pragma once
#include "TerrainTile.h"
#include "QGCMapEngineData.h"
#include "QGCLoggingCategory.h"
#include <QObject>
...
...
@@ -17,6 +18,7 @@
#include <QNetworkAccessManager>
#include <QHash>
#include <QMutex>
#include <QtLocation/private/qgeotiledmapreply_p.h>
/* usage example:
ElevationProvider *p = new ElevationProvider();
...
...
@@ -52,27 +54,17 @@ public:
*/
bool
queryTerrainData
(
const
QList
<
QGeoCoordinate
>&
coordinates
);
/**
* Cache all data in rectangular region given by south west and north east corner.
*
* @param southWest
* @param northEast
* @return true on successful scheduling for download
*/
bool
cacheTerrainTiles
(
const
QGeoCoordinate
&
southWest
,
const
QGeoCoordinate
&
northEast
);
signals:
/// signal returning requested elevation data
void
terrainData
(
bool
success
,
QList
<
float
>
altitudes
);
private
slots
:
void
_requestFinished
();
/// slot to handle download of elevation of list of coordinates
void
_
requestFinishedTile
();
/// slot to handle download of
elevation tiles
void
_
fetchedTile
();
/// slot to handle fetched
elevation tiles
private:
QString
_uniqueTileId
(
const
QGeoCoordinate
&
coordinate
);
/// Method to create a unique string for each tile. Format: south_west_north_east as floats.
void
_downloadTiles
(
void
);
/// Method to trigger download of queued tiles, eventually emitting the requested altitudes (if any).
QString
_getTileHash
(
const
QGeoCoordinate
&
coordinate
);
/// Method to create a unique string for each tile. Format: south_west_north_east as floats.
enum
class
State
{
Idle
,
...
...
src/TerrainTile.cc
View file @
5fb4a54f
...
...
@@ -85,10 +85,10 @@ TerrainTile::TerrainTile(QJsonDocument document)
qCDebug
(
TerrainTileLog
)
<<
"Incomplete bounding location"
;
return
;
}
_southWest
.
setLatitude
(
swArray
[
0
].
toDouble
());
_southWest
.
setLongitude
(
swArray
[
1
].
toDouble
());
_northEast
.
setLatitude
(
neArray
[
0
].
toDouble
());
_northEast
.
setLongitude
(
neArray
[
1
].
toDouble
());
_southWest
.
setLatitude
(
swArray
[
1
].
toDouble
());
_southWest
.
setLongitude
(
swArray
[
0
].
toDouble
());
_northEast
.
setLatitude
(
neArray
[
1
].
toDouble
());
_northEast
.
setLongitude
(
neArray
[
0
].
toDouble
());
// Stats
const
QJsonObject
&
statsObject
=
dataObject
[
_jsonStatsKey
].
toObject
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment