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 @@ ...@@ -2,18 +2,13 @@
#define IMAGERY_H #define IMAGERY_H
#include <inttypes.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: public:
explicit Imagery(QObject* parent); Imagery();
enum ImageryType enum ImageryType
{ {
...@@ -23,49 +18,56 @@ public: ...@@ -23,49 +18,56 @@ public:
void setImageryType(ImageryType type); void setImageryType(ImageryType type);
void setOffset(double xOffset, double yOffset); void setOffset(double xOffset, double yOffset);
void setUrl(std::string url);
void prefetch2D(double windowWidth, double windowHeight, void prefetch2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin, double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset, double viewXOffset, double viewYOffset,
const std::string& utmZone); const QString& utmZone);
void draw2D(double windowWidth, double windowHeight, void draw2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin, double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset, double viewXOffset, double viewYOffset,
const std::string& utmZone); const QString& utmZone);
void prefetch3D(double radius, double imageResolution, void prefetch3D(double radius, double imageResolution,
double xOrigin, double yOrigin, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset, double viewXOffset, double viewYOffset,
const std::string& utmZone); const QString& utmZone);
void draw3D(double radius, double imageResolution, void draw3D(double radius, double imageResolution,
double xOrigin, double yOrigin, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset, double viewXOffset, double viewYOffset,
const std::string& utmZone); const QString& utmZone);
bool update(void); bool update(void);
private slots:
void downloadFinished(QNetworkReply* reply);
private: 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, double imageResolution, int32_t& tileX, int32_t& tileY,
int32_t& zoomLevel); int32_t& zoomLevel);
char UTMLetterDesignator(double latitude); QChar UTMLetterDesignator(double latitude);
void LLtoUTM(const double latitude, const double longitude, void LLtoUTM(const double latitude, const double longitude,
double& utmNorthing, double& utmEasting, double& utmNorthing, double& utmEasting,
std::string& utmZone); QString& utmZone);
void UTMtoLL(const double utmNorthing, const double utmEasting, void UTMtoLL(const double utmNorthing, const double utmEasting,
const std::string& utmZone, const QString& utmZone,
double& latitude, double& longitude); double& latitude, double& longitude);
QString getTileURL(int32_t x, int32_t y, int32_t zoomLevel);
ImageryType currentImageryType; ImageryType currentImageryType;
QScopedPointer<QNetworkAccessManager> networkManager; QScopedPointer<TextureCache> textureCache;
double xOffset, yOffset;
}; };
#endif // IMAGERY_H #endif // IMAGERY_H
...@@ -5,6 +5,66 @@ Texture::Texture() ...@@ -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 void
Texture::draw(float x1, float y1, float x2, float y2, Texture::draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const bool smoothInterpolation) const
...@@ -22,7 +82,7 @@ Texture::draw(float x1, float y1, float x2, float y2, ...@@ -22,7 +82,7 @@ Texture::draw(float x1, float y1, float x2, float y2,
} }
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureId); glBindTexture(GL_TEXTURE_2D, id);
float dx, dy; float dx, dy;
if (smoothInterpolation) if (smoothInterpolation)
...@@ -56,3 +116,56 @@ Texture::draw(float x1, float y1, float x2, float y2, ...@@ -56,3 +116,56 @@ Texture::draw(float x1, float y1, float x2, float y2,
glDisable(GL_TEXTURE_2D); 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 @@ ...@@ -9,13 +9,24 @@
#include <inttypes.h> #include <inttypes.h>
#include <QSharedPointer> #include <QSharedPointer>
#include "WebImage.h"
class Texture class Texture
{ {
public: public:
Texture(); Texture();
QString getSourceURL(void);
void setID(GLuint id);
void sync(const WebImagePtr& image);
void draw(float x1, float y1, float x2, float y2, void draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const; 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: private:
enum State enum State
...@@ -26,8 +37,8 @@ private: ...@@ -26,8 +37,8 @@ private:
}; };
State state; State state;
QString sourceURL;
GLuint textureId; GLuint id;
int32_t textureWidth; int32_t textureWidth;
int32_t textureHeight; int32_t textureHeight;
...@@ -39,6 +50,6 @@ private: ...@@ -39,6 +50,6 @@ private:
float maxV; float maxV;
}; };
typedef struct QSharedPointer<Texture> TexturePtr; typedef QSharedPointer<Texture> TexturePtr;
#endif // TEXTURE_H #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