Commit fdc8d522 authored by hengli's avatar hengli

Added support to read in imagery data from disk storage.

parent 5f119ac9
......@@ -32,6 +32,7 @@ This file is part of the QGROUNDCONTROL project
#include "Imagery.h"
#include <cmath>
#include <iomanip>
#include <sstream>
const double WGS84_A = 6378137.0;
......@@ -65,7 +66,8 @@ Imagery::prefetch2D(double windowWidth, double windowHeight,
const QString& utmZone)
{
double tileResolution;
if (currentImageryType == SATELLITE)
if (currentImageryType == GOOGLE_SATELLITE ||
currentImageryType == GOOGLE_MAP)
{
tileResolution = 1.0;
while (tileResolution * 3.0 / 2.0 < 1.0 / zoom)
......@@ -77,6 +79,10 @@ Imagery::prefetch2D(double windowWidth, double windowHeight,
tileResolution = 512.0;
}
}
else if (currentImageryType == SWISSTOPO_SATELLITE)
{
tileResolution = 0.25;
}
int32_t minTileX, minTileY, maxTileX, maxTileY;
int32_t zoomLevel;
......@@ -92,7 +98,7 @@ Imagery::prefetch2D(double windowWidth, double windowHeight,
{
for (int32_t c = minTileX; c <= maxTileX; ++c)
{
QString url = getTileURL(c, r, zoomLevel);
QString url = getTileLocation(c, r, zoomLevel, tileResolution);
TexturePtr t = textureCache->get(url);
}
......@@ -106,7 +112,8 @@ Imagery::draw2D(double windowWidth, double windowHeight,
const QString& utmZone)
{
double tileResolution;
if (currentImageryType == SATELLITE)
if (currentImageryType == GOOGLE_SATELLITE ||
currentImageryType == GOOGLE_MAP)
{
tileResolution = 1.0;
while (tileResolution * 3.0 / 2.0 < 1.0 / zoom)
......@@ -118,6 +125,10 @@ Imagery::draw2D(double windowWidth, double windowHeight,
tileResolution = 512.0;
}
}
else if (currentImageryType == SWISSTOPO_SATELLITE)
{
tileResolution = 0.25;
}
int32_t minTileX, minTileY, maxTileX, maxTileY;
int32_t zoomLevel;
......@@ -133,7 +144,7 @@ Imagery::draw2D(double windowWidth, double windowHeight,
{
for (int32_t c = minTileX; c <= maxTileX; ++c)
{
QString tileURL = getTileURL(c, r, zoomLevel);
QString tileURL = getTileLocation(c, r, zoomLevel, tileResolution);
double x1, y1, x2, y2, x3, y3, x4, y4;
imageBounds(c, r, tileResolution, x1, y1, x2, y2, x3, y3, x4, y4);
......@@ -170,7 +181,7 @@ Imagery::prefetch3D(double radius, double tileResolution,
{
for (int32_t c = minTileX; c <= maxTileX; ++c)
{
QString url = getTileURL(c, r, zoomLevel);
QString url = getTileLocation(c, r, zoomLevel, tileResolution);
TexturePtr t = textureCache->get(url);
}
......@@ -197,7 +208,7 @@ Imagery::draw3D(double radius, double tileResolution,
{
for (int32_t c = minTileX; c <= maxTileX; ++c)
{
QString tileURL = getTileURL(c, r, zoomLevel);
QString tileURL = getTileLocation(c, r, zoomLevel, tileResolution);
double x1, y1, x2, y2, x3, y3, x4, y4;
imageBounds(c, r, tileResolution, x1, y1, x2, y2, x3, y3, x4, y4);
......@@ -228,20 +239,37 @@ Imagery::imageBounds(int32_t tileX, int32_t tileY, double tileResolution,
double& x1, double& y1, double& x2, double& y2,
double& x3, double& y3, double& x4, double& y4) const
{
int32_t zoomLevel = MAX_ZOOM_LEVEL - static_cast<int32_t>(rint(log2(tileResolution)));
int32_t numTiles = static_cast<int32_t>(exp2(static_cast<double>(zoomLevel)));
if (currentImageryType == GOOGLE_MAP ||
currentImageryType == GOOGLE_SATELLITE)
{
int32_t zoomLevel = MAX_ZOOM_LEVEL - static_cast<int32_t>(rint(log2(tileResolution)));
int32_t numTiles = static_cast<int32_t>(exp2(static_cast<double>(zoomLevel)));
double lon1 = tileXToLongitude(tileX, numTiles);
double lon2 = tileXToLongitude(tileX + 1, numTiles);
double lon1 = tileXToLongitude(tileX, numTiles);
double lon2 = tileXToLongitude(tileX + 1, numTiles);
double lat1 = tileYToLatitude(tileY, numTiles);
double lat2 = tileYToLatitude(tileY + 1, numTiles);
double lat1 = tileYToLatitude(tileY, numTiles);
double lat2 = tileYToLatitude(tileY + 1, numTiles);
QString utmZone;
LLtoUTM(lat1, lon1, x1, y1, utmZone);
LLtoUTM(lat1, lon2, x2, y2, utmZone);
LLtoUTM(lat2, lon2, x3, y3, utmZone);
LLtoUTM(lat2, lon1, x4, y4, utmZone);
QString utmZone;
LLtoUTM(lat1, lon1, x1, y1, utmZone);
LLtoUTM(lat1, lon2, x2, y2, utmZone);
LLtoUTM(lat2, lon2, x3, y3, utmZone);
LLtoUTM(lat2, lon1, x4, y4, utmZone);
}
else if (currentImageryType == SWISSTOPO_SATELLITE)
{
double utmMultiplier = tileResolution * 200.0;
double minX = tileX * utmMultiplier;
double maxX = minX + utmMultiplier;
double minY = tileY * utmMultiplier;
double maxY = minY + utmMultiplier;
x1 = maxX; y1 = minY;
x2 = maxX; y2 = maxY;
x3 = minX; y3 = maxY;
x4 = minX; y4 = minY;
}
}
void
......@@ -254,15 +282,29 @@ Imagery::tileBounds(double tileResolution,
{
double centerUtmX = (maxUtmX - minUtmX) / 2.0 + minUtmX;
double centerUtmY = (maxUtmY - minUtmY) / 2.0 + minUtmY;
int32_t centerTileX, centerTileY;
UTMtoTile(minUtmX, minUtmY, utmZone, tileResolution,
minTileX, maxTileY, zoomLevel);
UTMtoTile(centerUtmX, centerUtmY, utmZone, tileResolution,
centerTileX, centerTileY, zoomLevel);
UTMtoTile(maxUtmX, maxUtmY, utmZone, tileResolution,
maxTileX, minTileY, zoomLevel);
if (currentImageryType == GOOGLE_MAP ||
currentImageryType == GOOGLE_SATELLITE)
{
UTMtoTile(minUtmX, minUtmY, utmZone, tileResolution,
minTileX, maxTileY, zoomLevel);
UTMtoTile(centerUtmX, centerUtmY, utmZone, tileResolution,
centerTileX, centerTileY, zoomLevel);
UTMtoTile(maxUtmX, maxUtmY, utmZone, tileResolution,
maxTileX, minTileY, zoomLevel);
}
else if (currentImageryType == SWISSTOPO_SATELLITE)
{
double utmMultiplier = tileResolution * 200;
minTileX = static_cast<int32_t>(floor(minUtmX / utmMultiplier));
minTileY = static_cast<int32_t>(floor(minUtmY / utmMultiplier));
centerTileX = static_cast<int32_t>(floor(centerUtmX / utmMultiplier));
centerTileY = static_cast<int32_t>(floor(centerUtmY / utmMultiplier));
maxTileX = static_cast<int32_t>(floor(maxUtmX / utmMultiplier));
maxTileY = static_cast<int32_t>(floor(maxUtmY / utmMultiplier));
}
if (maxTileX - minTileX + 1 > 14)
{
......@@ -513,20 +555,33 @@ Imagery::UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone,
}
QString
Imagery::getTileURL(int32_t tileX, int32_t tileY, int32_t zoomLevel) const
Imagery::getTileLocation(int32_t tileX, int32_t tileY, int32_t zoomLevel,
double tileResolution) const
{
std::ostringstream oss;
switch (currentImageryType)
{
case MAP:
case GOOGLE_MAP:
oss << "http://mt0.google.com/vt/lyrs=m@120&x=" << tileX
<< "&y=" << tileY << "&z=" << zoomLevel;
break;
case SATELLITE:
case GOOGLE_SATELLITE:
oss << "http://khm.google.com/vt/lbw/lyrs=y&x=" << tileX
<< "&y=" << tileY << "&z=" << zoomLevel;
break;
case SWISSTOPO_SATELLITE:
oss << "../map/eth_zurich_swissimage_025/200/color/" << tileX
<< "/tile-";
if (tileResolution < 1.0)
{
oss << std::fixed << std::setprecision(2) << tileResolution;
}
else
{
oss << static_cast<int32_t>(rint(tileResolution));
}
oss << "-" << tileX << "-" << tileY << ".jpg";
default:
{};
}
......
......@@ -43,8 +43,9 @@ public:
enum ImageryType
{
MAP = 0,
SATELLITE = 1
GOOGLE_MAP = 0,
GOOGLE_SATELLITE = 1,
SWISSTOPO_SATELLITE = 2
};
void setImageryType(ImageryType type);
......@@ -100,7 +101,8 @@ private:
void UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone,
double& latitude, double& longitude) const;
QString getTileURL(int32_t tileX, int32_t tileY, int32_t zoomLevel) const;
QString getTileLocation(int32_t tileX, int32_t tileY, int32_t zoomLevel,
double tileResolution) const;
ImageryType currentImageryType;
......
......@@ -95,6 +95,7 @@ QMap3DWidget::buildLayout(void)
imageryComboBox->addItem("None");
imageryComboBox->addItem("Map (Google)");
imageryComboBox->addItem("Satellite (Google)");
imageryComboBox->addItem("Satellite (Swisstopo)");
QPushButton* recenterButton = new QPushButton(this);
recenterButton->setText("Recenter Camera");
......@@ -536,11 +537,15 @@ QMap3DWidget::showImagery(const QString& text)
{
if (text.compare("Map (Google)") == 0)
{
imagery->setImageryType(Imagery::MAP);
imagery->setImageryType(Imagery::GOOGLE_MAP);
}
else if (text.compare("Satellite (Google)") == 0)
{
imagery->setImageryType(Imagery::SATELLITE);
imagery->setImageryType(Imagery::GOOGLE_SATELLITE);
}
else if (text.compare("Satellite (Swisstopo)") == 0)
{
imagery->setImageryType(Imagery::SWISSTOPO_SATELLITE);
}
displayImagery = true;
}
......@@ -682,6 +687,11 @@ QMap3DWidget::drawImagery(double originX, double originY, double originZ,
{
minResolution = 0.5;
}
else if (imageryComboBox->currentText().compare("Satellite (Swisstopo)") == 0)
{
minResolution = 0.25;
maxResolution = 0.25;
}
double resolution = minResolution;
while (resolution * 2.0 < centerResolution)
......
......@@ -83,7 +83,7 @@ WebImage::getData(void) const
return image->scanLine(0);
}
void
bool
WebImage::setData(const QByteArray& data)
{
QImage tempImage;
......@@ -94,10 +94,36 @@ WebImage::setData(const QByteArray& data)
image.reset(new QImage);
}
*image = QGLWidget::convertToGLFormat(tempImage);
return true;
}
else
{
qDebug() << "# WARNING: cannot load image data for" << sourceURL;
return false;
}
}
bool
WebImage::setData(const QString& filename)
{
QImage tempImage;
if (tempImage.load(filename))
{
if (image.isNull())
{
image.reset(new QImage);
}
*image = QGLWidget::convertToGLFormat(tempImage);
return true;
}
else
{
qDebug() << "# WARNING: cannot load image data for" << filename;
return false;
}
}
......
......@@ -58,7 +58,8 @@ public:
void setSourceURL(const QString& url);
const uint8_t* getData(void) const;
void setData(const QByteArray& data);
bool setData(const QByteArray& data);
bool setData(const QString& filename);
int32_t getWidth(void) const;
int32_t getHeight(void) const;
......
......@@ -104,7 +104,22 @@ WebImageCache::lookup(const QString& url)
++currentReference;
cacheEntry.first->setState(WebImage::REQUESTED);
networkManager->get(QNetworkRequest(QUrl(url)));
if (url.left(4).compare("http") == 0)
{
networkManager->get(QNetworkRequest(QUrl(url)));
}
else
{
if (cacheEntry.first->setData(url))
{
cacheEntry.first->setSyncFlag(true);
cacheEntry.first->setState(WebImage::READY);
}
else
{
cacheEntry.first->setState(WebImage::UNINITIALIZED);
}
}
return cacheEntry;
}
......
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