Commit af07f106 authored by hengli's avatar hengli

Updated 3D imagery code. Non-working version.

parent c62170bb
This diff is collapsed.
......@@ -2,18 +2,13 @@
#define IMAGERY_H
#include <inttypes.h>
#include <string>
#include <QNetworkAccessManager>
#include <QObject>
#include "Texture.h"
#include "TextureCache.h"
class Imagery : public QObject
class Imagery
{
// Q_OBJECT
public:
explicit Imagery(QObject* parent);
Imagery();
enum ImageryType
{
......@@ -23,49 +18,56 @@ public:
void setImageryType(ImageryType type);
void setOffset(double xOffset, double yOffset);
void setUrl(std::string url);
void prefetch2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const std::string& utmZone);
const QString& utmZone);
void draw2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const std::string& utmZone);
const QString& utmZone);
void prefetch3D(double radius, double imageResolution,
double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const std::string& utmZone);
const QString& utmZone);
void draw3D(double radius, double imageResolution,
double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const std::string& utmZone);
const QString& utmZone);
bool update(void);
private slots:
void downloadFinished(QNetworkReply* reply);
private:
void UTMtoTile(double northing, double easting, const std::string& utmZone,
void imageBounds(int32_t x, int32_t y, double imageResolution,
double& x1, double& y1, double& x2, double& y2,
double& x3, double& y3, double& x4, double& y4);
double tileYToLatitude(double y);
double latitudeToTileY(double latitude);
void UTMtoTile(double northing, double easting, const QString& utmZone,
double imageResolution, int32_t& tileX, int32_t& tileY,
int32_t& zoomLevel);
char UTMLetterDesignator(double latitude);
QChar UTMLetterDesignator(double latitude);
void LLtoUTM(const double latitude, const double longitude,
double& utmNorthing, double& utmEasting,
std::string& utmZone);
QString& utmZone);
void UTMtoLL(const double utmNorthing, const double utmEasting,
const std::string& utmZone,
const QString& utmZone,
double& latitude, double& longitude);
QString getTileURL(int32_t x, int32_t y, int32_t zoomLevel);
ImageryType currentImageryType;
QScopedPointer<QNetworkAccessManager> networkManager;
QScopedPointer<TextureCache> textureCache;
double xOffset, yOffset;
};
#endif // IMAGERY_H
......@@ -5,6 +5,66 @@ Texture::Texture()
}
QString
Texture::getSourceURL(void)
{
return sourceURL;
}
void
Texture::setID(GLuint id)
{
this->id = id;
}
void
Texture::sync(const WebImagePtr& image)
{
state = static_cast<State>(image->getState());
if (image->getState() != WebImage::UNINITIALIZED &&
sourceURL != image->getSourceURL())
{
sourceURL = image->getSourceURL();
}
if (image->getState() == WebImage::READY && image->getSyncFlag())
{
image->setSyncFlag(false);
if (image->getWidth() != imageWidth ||
image->getHeight() != imageHeight)
{
imageWidth = image->getWidth();
textureWidth = 32;
while (textureWidth < imageWidth)
{
textureWidth *= 2;
}
imageHeight = image->getHeight();
textureHeight = 32;
while (textureHeight < imageHeight)
{
textureHeight *= 2;
}
maxU = static_cast<double>(imageWidth)
/ static_cast<double>(textureWidth);
maxV = static_cast<double>(imageHeight)
/ static_cast<double>(textureHeight);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight,
0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight,
GL_RGB, GL_UNSIGNED_BYTE, image->getData());
}
}
void
Texture::draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const
......@@ -22,7 +82,7 @@ Texture::draw(float x1, float y1, float x2, float y2,
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureId);
glBindTexture(GL_TEXTURE_2D, id);
float dx, dy;
if (smoothInterpolation)
......@@ -56,3 +116,56 @@ Texture::draw(float x1, float y1, float x2, float y2,
glDisable(GL_TEXTURE_2D);
}
void
Texture::draw(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
bool smoothInterpolation) const
{
if (state == REQUESTED)
{
glBegin(GL_LINE_LOOP);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
return;
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id);
float dx, dy;
if (smoothInterpolation)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
dx = 1.0f / (2.0f * textureWidth);
dy = 1.0f / (2.0f * textureHeight);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
dx = 0.0f;
dy = 0.0f;
}
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(dx, maxV - dy);
glVertex2f(x1, y1);
glTexCoord2f(maxU - dx, maxV - dy);
glVertex2f(x2, y2);
glTexCoord2f(maxU - dx, dy);
glVertex2f(x3, y3);
glTexCoord2f(dx, dy);
glVertex2f(x4, y4);
glEnd();
glDisable(GL_TEXTURE_2D);
}
......@@ -9,13 +9,24 @@
#include <inttypes.h>
#include <QSharedPointer>
#include "WebImage.h"
class Texture
{
public:
Texture();
QString getSourceURL(void);
void setID(GLuint id);
void sync(const WebImagePtr& image);
void draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const;
void draw(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
bool smoothInterpolation) const;
private:
enum State
......@@ -26,8 +37,8 @@ private:
};
State state;
GLuint textureId;
QString sourceURL;
GLuint id;
int32_t textureWidth;
int32_t textureHeight;
......@@ -39,6 +50,6 @@ private:
float maxV;
};
typedef struct QSharedPointer<Texture> TexturePtr;
typedef QSharedPointer<Texture> TexturePtr;
#endif // TEXTURE_H
#include "TextureCache.h"
TextureCache::TextureCache(uint32_t _cacheSize)
: cacheSize(_cacheSize)
, imageCache(new WebImageCache(0, cacheSize))
{
textures.resize(cacheSize);
TexturePtr t;
foreach(t, textures)
{
GLuint id;
glGenTextures(1, &id);
t->setID(id);
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
}
TexturePtr
TextureCache::get(const QString& tileURL)
{
QPair<TexturePtr, int32_t> p1 = lookup(tileURL);
if (!p1.first.isNull())
{
return p1.first;
}
QPair<WebImagePtr, int32_t> p2 = imageCache->lookup(tileURL);
if (!p2.first.isNull())
{
textures[p2.second]->sync(p2.first);
p1 = lookup(tileURL);
return p1.first;
}
return TexturePtr();
}
void
TextureCache::sync(void)
{
if (requireSync())
{
for (int32_t i = 0; i < textures.size(); ++i)
{
textures[i]->sync(imageCache->at(i));
}
}
}
QPair<TexturePtr, int32_t>
TextureCache::lookup(const QString& tileURL)
{
for (int32_t i = 0; i < textures.size(); ++i)
{
if (textures[i]->getSourceURL() == tileURL)
{
return qMakePair(textures[i], i);
}
}
return qMakePair(TexturePtr(), -1);
}
bool
TextureCache::requireSync(void) const
{
for (uint32_t i = 0; i < cacheSize; ++i)
{
if (imageCache->at(i)->getSyncFlag())
{
return true;
}
}
return false;
}
#ifndef TEXTURECACHE_H
#define TEXTURECACHE_H
#include <QVector>
#include "Texture.h"
#include "WebImageCache.h"
class TextureCache
{
public:
explicit TextureCache(uint32_t cacheSize);
TexturePtr get(const QString& tileURL);
void sync(void);
private:
QPair<TexturePtr, int32_t> lookup(const QString& tileURL);
bool requireSync(void) const;
uint32_t cacheSize;
QVector<TexturePtr> textures;
QScopedPointer<WebImageCache> imageCache;
};
#endif // TEXTURECACHE_H
#include "WebImage.h"
WebImage::WebImage()
: state(WebImage::UNINITIALIZED)
, lastReference(0)
, syncFlag(false)
{
}
void
WebImage::clear(void)
{
image.clear();
sourceURL.clear();
state = WebImage::UNINITIALIZED;
lastReference = 0;
}
WebImage::State
WebImage::getState(void) const
{
return state;
}
void
WebImage::setState(State state)
{
this->state = state;
}
QString
WebImage::getSourceURL(void) const
{
return sourceURL;
}
void
WebImage::setSourceURL(const QString& url)
{
sourceURL = url;
}
const uint8_t*
WebImage::getData(void) const
{
return image->bits();
}
int32_t
WebImage::getWidth(void) const
{
return image->width();
}
int32_t
WebImage::getHeight(void) const
{
return image->height();
}
uint64_t
WebImage::getLastReference(void) const
{
return lastReference;
}
void
WebImage::setLastReference(uint64_t value)
{
lastReference = value;
}
bool
WebImage::getSyncFlag(void) const
{
return syncFlag;
}
void
WebImage::setSyncFlag(bool onoff)
{
syncFlag = onoff;
}
#ifndef WEBIMAGE_H
#define WEBIMAGE_H
#include <inttypes.h>
#include <QImage>
#include <QSharedPointer>
class WebImage
{
public:
WebImage();
void clear(void);
enum State
{
UNINITIALIZED = 0,
REQUESTED = 1,
READY = 2
};
State getState(void) const;
void setState(State state);
QString getSourceURL(void) const;
void setSourceURL(const QString& url);
const uint8_t* getData(void) const;
int32_t getWidth(void) const;
int32_t getHeight(void) const;
uint64_t getLastReference(void) const;
void setLastReference(uint64_t value);
bool getSyncFlag(void) const;
void setSyncFlag(bool onoff);
private:
State state;
QString sourceURL;
QSharedPointer<QImage> image;
uint64_t lastReference;
bool syncFlag;
};
typedef QSharedPointer<WebImage> WebImagePtr;
#endif // WEBIMAGE_H
#include "WebImageCache.h"
#include <QNetworkReply>
#include <QPixmap>
WebImageCache::WebImageCache(QObject* parent, uint32_t _cacheSize)
: QObject(parent)
, cacheSize(_cacheSize)
, currentReference(0)
, networkManager(new QNetworkAccessManager)
{
webImages.resize(cacheSize);
connect(networkManager.data(), SIGNAL(finished(QNetworkReply*)),
this, SLOT(downloadFinished(QNetworkReply*)));
}
QPair<WebImagePtr, int32_t>
WebImageCache::lookup(const QString& url)
{
QPair<WebImagePtr, int32_t> p;
for (int32_t i = 0; i < webImages.size(); ++i)
{
if (webImages[i]->getState() != WebImage::UNINITIALIZED &&
webImages[i]->getSourceURL() == url)
{
p.first = webImages[i];
p.second = i;
break;
}
}
if (p.first.isNull())
{
for (int32_t i = 0; i < webImages.size(); ++i)
{
// get uninitialized image
if (webImages[i]->getState() == WebImage::UNINITIALIZED)
{
p.first = webImages[i];
p.second = i;
break;
}
// get oldest image
else if (webImages[i]->getState() == WebImage::READY &&
(p.first.isNull() ||
p.first->getLastReference() < p.first->getLastReference()))
{
p.first = webImages[i];
p.second = i;
}
}
if (p.first.isNull())
{
return qMakePair(WebImagePtr(), -1);
}
else
{
if (p.first->getState() == WebImage::READY)
{
p.first->clear();
}
p.first->setSourceURL(url);
p.first->setLastReference(currentReference);
++currentReference;
p.first->setState(WebImage::REQUESTED);
networkManager->get(QNetworkRequest(QUrl(url)));
return p;
}
}
else
{
if (p.first->getState() == WebImage::READY)
{
p.first->setLastReference(currentReference);
++currentReference;
return p;
}
else
{
return qMakePair(WebImagePtr(), -1);
}
}
}
WebImagePtr
WebImageCache::at(int32_t index) const
{
return webImages[index];
}
void
WebImageCache::downloadFinished(QNetworkReply* reply)
{
if (reply->error() != QNetworkReply::NoError) {
return;
}
QVariant attribute = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (attribute.isValid())
{
return;
}
QByteArray imageData = reply->readAll();
QPixmap pixmap;
pixmap.loadFromData(imageData);
// set image, needsSync to true, and state to READY
}
#ifndef WEBIMAGECACHE_H
#define WEBIMAGECACHE_H
#include <QNetworkAccessManager>
#include <QObject>
#include <QPair>
#include "WebImage.h"
class WebImageCache : public QObject
{
Q_OBJECT
public:
WebImageCache(QObject* parent, uint32_t cacheSize);
QPair<WebImagePtr, int32_t> lookup(const QString& url);
WebImagePtr at(int32_t index) const;
private Q_SLOTS:
void downloadFinished(QNetworkReply* reply);
private:
uint32_t cacheSize;
QVector<WebImagePtr> webImages;
uint64_t currentReference;
QScopedPointer<QNetworkAccessManager> networkManager;
};
#endif // WEBIMAGECACHE_H
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