From 6302dedf14652f2265c2528751877457d38cd184 Mon Sep 17 00:00:00 2001 From: Lionel Heng Date: Thu, 25 Nov 2010 22:22:11 +0100 Subject: [PATCH] Restored imagery feature. Not yet running. --- src/ui/MainWindow.h | 4 -- src/ui/map3D/Imagery.cc | 92 ++++++++++++++-------------- src/ui/map3D/Imagery.h | 114 +++++++++++++++++++++++++++++++++++ src/ui/map3D/Texture.cc | 76 ++++++++++++++++------- src/ui/map3D/Texture.h | 17 +++--- src/ui/map3D/TextureCache.cc | 9 +-- 6 files changed, 224 insertions(+), 88 deletions(-) create mode 100644 src/ui/map3D/Imagery.h diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index a80d52bfb..b053cbc5b 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -63,10 +63,6 @@ This file is part of the QGROUNDCONTROL project #include "HSIDisplay.h" #include "QGCDataPlot2D.h" #include "QGCRemoteControlView.h" -#ifdef QGC_OSG_ENABLED -//#include "Q3DWidget.h" -#include "QMap3D.h" -#endif #include "LogCompressor.h" diff --git a/src/ui/map3D/Imagery.cc b/src/ui/map3D/Imagery.cc index 1b7bacbe7..7e972b5cf 100644 --- a/src/ui/map3D/Imagery.cc +++ b/src/ui/map3D/Imagery.cc @@ -38,7 +38,7 @@ This file is part of the QGROUNDCONTROL project const double WGS84_A = 6378137.0; const double WGS84_ECCSQ = 0.00669437999013; -const int32_t MAX_ZOOM_LEVEL = 20; +const int MAX_ZOOM_LEVEL = 20; Imagery::Imagery() : textureCache(new TextureCache(1000)) @@ -84,8 +84,8 @@ Imagery::prefetch2D(double windowWidth, double windowHeight, tileResolution = 0.25; } - int32_t minTileX, minTileY, maxTileX, maxTileY; - int32_t zoomLevel; + int minTileX, minTileY, maxTileX, maxTileY; + int zoomLevel; tileBounds(tileResolution, xOrigin + viewXOffset - windowWidth / 2.0 / zoom, @@ -94,9 +94,9 @@ Imagery::prefetch2D(double windowWidth, double windowHeight, yOrigin + viewYOffset + windowHeight / 2.0 / zoom, utmZone, minTileX, minTileY, maxTileX, maxTileY, zoomLevel); - for (int32_t r = minTileY; r <= maxTileY; ++r) + for (int r = minTileY; r <= maxTileY; ++r) { - for (int32_t c = minTileX; c <= maxTileX; ++c) + for (int c = minTileX; c <= maxTileX; ++c) { QString url = getTileLocation(c, r, zoomLevel, tileResolution); @@ -130,8 +130,8 @@ Imagery::draw2D(double windowWidth, double windowHeight, tileResolution = 0.25; } - int32_t minTileX, minTileY, maxTileX, maxTileY; - int32_t zoomLevel; + int minTileX, minTileY, maxTileX, maxTileY; + int zoomLevel; tileBounds(tileResolution, xOrigin + viewXOffset - windowWidth / 2.0 / zoom * 1.5, @@ -140,9 +140,9 @@ Imagery::draw2D(double windowWidth, double windowHeight, yOrigin + viewYOffset + windowHeight / 2.0 / zoom * 1.5, utmZone, minTileX, minTileY, maxTileX, maxTileY, zoomLevel); - for (int32_t r = minTileY; r <= maxTileY; ++r) + for (int r = minTileY; r <= maxTileY; ++r) { - for (int32_t c = minTileX; c <= maxTileX; ++c) + for (int c = minTileX; c <= maxTileX; ++c) { QString tileURL = getTileLocation(c, r, zoomLevel, tileResolution); @@ -167,8 +167,8 @@ Imagery::prefetch3D(double radius, double tileResolution, double viewXOffset, double viewYOffset, const QString& utmZone, bool useHeightModel) { - int32_t minTileX, minTileY, maxTileX, maxTileY; - int32_t zoomLevel; + int minTileX, minTileY, maxTileX, maxTileY; + int zoomLevel; tileBounds(tileResolution, xOrigin + viewXOffset - radius, @@ -177,9 +177,9 @@ Imagery::prefetch3D(double radius, double tileResolution, yOrigin + viewYOffset + radius, utmZone, minTileX, minTileY, maxTileX, maxTileY, zoomLevel); - for (int32_t r = minTileY; r <= maxTileY; ++r) + for (int r = minTileY; r <= maxTileY; ++r) { - for (int32_t c = minTileX; c <= maxTileX; ++c) + for (int c = minTileX; c <= maxTileX; ++c) { QString url = getTileLocation(c, r, zoomLevel, tileResolution); @@ -194,8 +194,8 @@ Imagery::draw3D(double radius, double tileResolution, double viewXOffset, double viewYOffset, const QString& utmZone, bool useHeightModel) { - int32_t minTileX, minTileY, maxTileX, maxTileY; - int32_t zoomLevel; + int minTileX, minTileY, maxTileX, maxTileY; + int zoomLevel; tileBounds(tileResolution, xOrigin + viewXOffset - radius, @@ -204,9 +204,9 @@ Imagery::draw3D(double radius, double tileResolution, yOrigin + viewYOffset + radius, utmZone, minTileX, minTileY, maxTileX, maxTileY, zoomLevel); - for (int32_t r = minTileY; r <= maxTileY; ++r) + for (int r = minTileY; r <= maxTileY; ++r) { - for (int32_t c = minTileX; c <= maxTileX; ++c) + for (int c = minTileX; c <= maxTileX; ++c) { QString tileURL = getTileLocation(c, r, zoomLevel, tileResolution); @@ -235,15 +235,15 @@ Imagery::update(void) } void -Imagery::imageBounds(int32_t tileX, int32_t tileY, double tileResolution, +Imagery::imageBounds(int tileX, int tileY, double tileResolution, double& x1, double& y1, double& x2, double& y2, double& x3, double& y3, double& x4, double& y4) const { if (currentImageryType == GOOGLE_MAP || currentImageryType == GOOGLE_SATELLITE) { - int32_t zoomLevel = MAX_ZOOM_LEVEL - static_cast(rint(log2(tileResolution))); - int32_t numTiles = static_cast(exp2(static_cast(zoomLevel))); + int zoomLevel = MAX_ZOOM_LEVEL - static_cast(rint(log2(tileResolution))); + int numTiles = static_cast(exp2(static_cast(zoomLevel))); double lon1 = tileXToLongitude(tileX, numTiles); double lon2 = tileXToLongitude(tileX + 1, numTiles); @@ -277,13 +277,13 @@ void Imagery::tileBounds(double tileResolution, double minUtmX, double minUtmY, double maxUtmX, double maxUtmY, const QString& utmZone, - int32_t& minTileX, int32_t& minTileY, - int32_t& maxTileX, int32_t& maxTileY, - int32_t& zoomLevel) const + int& minTileX, int& minTileY, + int& maxTileX, int& maxTileY, + int& zoomLevel) const { double centerUtmX = (maxUtmX - minUtmX) / 2.0 + minUtmX; double centerUtmY = (maxUtmY - minUtmY) / 2.0 + minUtmY; - int32_t centerTileX, centerTileY; + int centerTileX, centerTileY; if (currentImageryType == GOOGLE_MAP || currentImageryType == GOOGLE_SATELLITE) @@ -300,12 +300,12 @@ Imagery::tileBounds(double tileResolution, { double utmMultiplier = tileResolution * 200; - minTileX = static_cast(rint(minUtmX / utmMultiplier)); - minTileY = static_cast(rint(minUtmY / utmMultiplier)); - centerTileX = static_cast(rint(centerUtmX / utmMultiplier)); - centerTileY = static_cast(rint(centerUtmY / utmMultiplier)); - maxTileX = static_cast(rint(maxUtmX / utmMultiplier)); - maxTileY = static_cast(rint(maxUtmY / utmMultiplier)); + minTileX = static_cast(rint(minUtmX / utmMultiplier)); + minTileY = static_cast(rint(minUtmY / utmMultiplier)); + centerTileX = static_cast(rint(centerUtmX / utmMultiplier)); + centerTileY = static_cast(rint(centerUtmY / utmMultiplier)); + maxTileX = static_cast(rint(maxUtmX / utmMultiplier)); + maxTileY = static_cast(rint(maxUtmY / utmMultiplier)); } if (maxTileX - minTileX + 1 > 14) @@ -321,14 +321,14 @@ Imagery::tileBounds(double tileResolution, } double -Imagery::tileXToLongitude(int32_t tileX, int32_t numTiles) const +Imagery::tileXToLongitude(int tileX, int numTiles) const { return 360.0 * (static_cast(tileX) / static_cast(numTiles)) - 180.0; } double -Imagery::tileYToLatitude(int32_t tileY, int32_t numTiles) const +Imagery::tileYToLatitude(int tileY, int numTiles) const { double unnormalizedRad = (static_cast(tileY) / static_cast(numTiles)) @@ -337,32 +337,32 @@ Imagery::tileYToLatitude(int32_t tileY, int32_t numTiles) const return -rad * 180.0 / M_PI; } -int32_t -Imagery::longitudeToTileX(double longitude, int32_t numTiles) const +int +Imagery::longitudeToTileX(double longitude, int numTiles) const { - return static_cast((longitude / 180.0 + 1.0) / 2.0 * numTiles); + return static_cast((longitude / 180.0 + 1.0) / 2.0 * numTiles); } -int32_t -Imagery::latitudeToTileY(double latitude, int32_t numTiles) const +int +Imagery::latitudeToTileY(double latitude, int numTiles) const { double rad = latitude * M_PI / 180.0; double normalizedRad = -log(tan(rad) + 1.0 / cos(rad)); - return static_cast((normalizedRad + M_PI) + return static_cast((normalizedRad + M_PI) / (2.0 * M_PI) * numTiles); } void Imagery::UTMtoTile(double northing, double easting, const QString& utmZone, - double tileResolution, int32_t& tileX, int32_t& tileY, - int32_t& zoomLevel) const + double tileResolution, int& tileX, int& tileY, + int& zoomLevel) const { double latitude, longitude; UTMtoLL(northing, easting, utmZone, latitude, longitude); - zoomLevel = MAX_ZOOM_LEVEL - static_cast(rint(log2(tileResolution))); - int32_t numTiles = static_cast(exp2(static_cast(zoomLevel))); + zoomLevel = MAX_ZOOM_LEVEL - static_cast(rint(log2(tileResolution))); + int numTiles = static_cast(exp2(static_cast(zoomLevel))); tileX = longitudeToTileX(longitude, numTiles); tileY = latitudeToTileY(latitude, numTiles); @@ -422,7 +422,7 @@ Imagery::LLtoUTM(double latitude, double longitude, double LongRad = longitude * M_PI / 180.0; double LongOriginRad; - int32_t ZoneNumber = static_cast((longitude + 180.0) / 6.0) + 1; + int ZoneNumber = static_cast((longitude + 180.0) / 6.0) + 1; if (latitude >= 56.0 && latitude < 64.0 && longitude >= 3.0 && longitude < 12.0) @@ -500,7 +500,7 @@ Imagery::UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone, double LongOrigin; double mu, phi1, phi1Rad; double x, y; - int32_t ZoneNumber; + int ZoneNumber; char ZoneLetter; bool NorthernHemisphere; @@ -557,7 +557,7 @@ Imagery::UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone, } QString -Imagery::getTileLocation(int32_t tileX, int32_t tileY, int32_t zoomLevel, +Imagery::getTileLocation(int tileX, int tileY, int zoomLevel, double tileResolution) const { std::ostringstream oss; @@ -581,7 +581,7 @@ Imagery::getTileLocation(int32_t tileX, int32_t tileY, int32_t zoomLevel, } else { - oss << static_cast(rint(tileResolution)); + oss << static_cast(rint(tileResolution)); } oss << "-" << tileY << "-" << tileX << ".jpg"; default: diff --git a/src/ui/map3D/Imagery.h b/src/ui/map3D/Imagery.h new file mode 100644 index 000000000..157bd5479 --- /dev/null +++ b/src/ui/map3D/Imagery.h @@ -0,0 +1,114 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Definition of the class Imagery. + * + * @author Lionel Heng + * + */ + +#ifndef IMAGERY_H +#define IMAGERY_H + +#include +#include + +#include "TextureCache.h" + +class Imagery +{ +public: + enum ImageryType + { + GOOGLE_MAP = 0, + GOOGLE_SATELLITE = 1, + SWISSTOPO_SATELLITE = 2, + SWISSTOPO_SATELLITE_3D = 3 + }; + + Imagery(); + + void setImageryType(ImageryType type); + void setOffset(double xOffset, double yOffset); + + void prefetch2D(double windowWidth, double windowHeight, + double zoom, double xOrigin, double yOrigin, + double viewXOffset, double viewYOffset, + const QString& utmZone); + void draw2D(double windowWidth, double windowHeight, + double zoom, double xOrigin, double yOrigin, + double viewXOffset, double viewYOffset, + const QString& utmZone); + + void prefetch3D(double radius, double tileResolution, + double xOrigin, double yOrigin, + double viewXOffset, double viewYOffset, + const QString& utmZone, bool useHeightModel); + void draw3D(double radius, double tileResolution, + double xOrigin, double yOrigin, + double viewXOffset, double viewYOffset, + const QString& utmZone, bool useHeightModel); + + bool update(void); + +private: + void imageBounds(int tileX, int tileY, double tileResolution, + double& x1, double& y1, double& x2, double& y2, + double& x3, double& y3, double& x4, double& y4) const; + void tileBounds(double tileResolution, + double minUtmX, double minUtmY, + double maxUtmX, double maxUtmY, const QString& utmZone, + int& minTileX, int& minTileY, + int& maxTileX, int& maxTileY, + int& zoomLevel) const; + + double tileXToLongitude(int tileX, int numTiles) const; + double tileYToLatitude(int tileY, int numTiles) const; + int longitudeToTileX(double longitude, int numTiles) const; + int latitudeToTileY(double latitude, int numTiles) const; + + void UTMtoTile(double northing, double easting, const QString& utmZone, + double tileResolution, int& tileX, int& tileY, + int& zoomLevel) const; + QChar UTMLetterDesignator(double latitude) const; + + void LLtoUTM(double latitude, double longitude, + double& utmNorthing, double& utmEasting, + QString& utmZone) const; + void UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone, + double& latitude, double& longitude) const; + + QString getTileLocation(int tileX, int tileY, int zoomLevel, + double tileResolution) const; + + QScopedPointer textureCache; + + ImageryType currentImageryType; + + double xOffset; + double yOffset; +}; + +#endif // IMAGERY_H diff --git a/src/ui/map3D/Texture.cc b/src/ui/map3D/Texture.cc index 8efaa5858..43703e892 100644 --- a/src/ui/map3D/Texture.cc +++ b/src/ui/map3D/Texture.cc @@ -29,12 +29,22 @@ This file is part of the QGROUNDCONTROL project * */ +#include + #include "Texture.h" Texture::Texture() : _is3D(false) { - + texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); + texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); + 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); } const QString& @@ -44,9 +54,9 @@ Texture::getSourceURL(void) const } void -Texture::setID(GLuint id) +Texture::setId(unsigned int _id) { - this->id = id; + id = _id; } void @@ -87,6 +97,10 @@ Texture::sync(const WebImagePtr& image) maxV = static_cast(imageHeight) / static_cast(textureHeight); + osg::ref_ptr image; + image->setImage(textureWidth, textureHeight, 8, 3, GL_RGBA, GL_UNSIGNED_BYTES, NULL, osg::Image::USE_NEW_DELETE); + + texture2D-> glBindTexture(GL_TEXTURE_2D, id); glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); @@ -100,46 +114,56 @@ Texture::sync(const WebImagePtr& image) } } -void +osg::ref_ptr Texture::draw(float x1, float y1, float x2, float y2, bool smoothInterpolation) const { - draw(x1, y1, x2, y1, x2, y2, x1, y2, smoothInterpolation); + return draw(x1, y1, x2, y1, x2, y2, x1, y2, smoothInterpolation); } -void +osg::ref_ptr Texture::draw(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, bool smoothInterpolation) const { + osg::ref_ptr geometry(new osg::Geometry); + osg::ref_ptr stateset(new osg::StateSet); + 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; + osg::ref_ptr vertices(new osg::Vec2Array); + vertices->push_back(osg::Vec2(x1, y1)); + vertices->push_back(osg::Vec2(x2, y2)); + vertices->push_back(osg::Vec2(x3, y3)); + vertices->push_back(osg::Vec2(x4, y4)); + + geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, + 0, vertices->size())); + + geometry->setVertexArray(vertices); + + osg::ref_ptr color(new osg::Vec4Array); + color->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); + geometry->setColorArray(color); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + return geometry; } - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, id); + stateset->setTextureAttributeAndModes(id, texture2D); 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); + texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::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); + texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); + texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); dx = 0.0f; dy = 0.0f; } @@ -147,6 +171,14 @@ Texture::draw(float x1, float y1, float x2, float y2, glColor3f(1.0f, 1.0f, 1.0f); if (!_is3D) { + osg::ref_ptr tc = new osg::Vec2Array; + + geometry->setTexCoordArray(id, tc); + tc->push_back(osg::Vec2(dx, maxV - dy)); + tc->push_back(osg::Vec2(maxU - dx, maxV - dy)); + tc->push_back(osg::Vec2(maxU - dx, dy)); + tc->push_back(osg::Vec2(dx, dy)); + glBegin(GL_QUADS); glTexCoord2f(dx, maxV - dy); glVertex3f(x1, y1, 0.0f); @@ -210,8 +242,6 @@ Texture::draw(float x1, float y1, float x2, float y2, } } } - - glDisable(GL_TEXTURE_2D); } bool diff --git a/src/ui/map3D/Texture.h b/src/ui/map3D/Texture.h index 79dc7355c..6907c831d 100644 --- a/src/ui/map3D/Texture.h +++ b/src/ui/map3D/Texture.h @@ -38,6 +38,8 @@ This file is part of the QGROUNDCONTROL project #include #endif #include +#include +#include #include #include "WebImage.h" @@ -49,15 +51,15 @@ public: const QString& getSourceURL(void) const; - void setID(GLuint id); + void setId(unsigned int _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; + osg::ref_ptr draw(float x1, float y1, float x2, float y2, + bool smoothInterpolation) const; + osg::ref_ptr draw(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + bool smoothInterpolation) const; bool is3D(void) const; @@ -71,7 +73,8 @@ private: State state; QString sourceURL; - GLuint id; + unsigned int id; + osg::ref_ptr texture2D; int32_t textureWidth; int32_t textureHeight; diff --git a/src/ui/map3D/TextureCache.cc b/src/ui/map3D/TextureCache.cc index 8449f7404..3337f5235 100644 --- a/src/ui/map3D/TextureCache.cc +++ b/src/ui/map3D/TextureCache.cc @@ -38,14 +38,7 @@ TextureCache::TextureCache(uint32_t _cacheSize) for (uint32_t i = 0; i < cacheSize; ++i) { TexturePtr t(new Texture); - - 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); + t->setId(i); textures.push_back(t); } -- 2.22.0