Allow source raster *subpixel* positioning on map canvasses. This allows zooming in on coarse rasters to be accurate (i.e. when 1 source pixel covers more than one screen pixel). This has only been proof-of-concept tested, therefore the author will not be offended if further refinements are committed. This addresses CVS bug 895502.

git-svn-id: http://svn.osgeo.org/qgis/trunk@3396 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
morb_au 2005-05-15 00:10:35 +00:00
parent de40711d7e
commit 001049be3e
7 changed files with 397 additions and 82 deletions

View File

@ -3,6 +3,14 @@
Version 0.6 'Simon' .... development version
QGIS Change Log
2005-05-15 [morb_au] 0.6devel21
** Fixed a memory leak in the postgres provider when retrieving features
** Raster layers now align to the map canvas with subpixel source accuracy
(most useful when zooming in very close and the source pixels cover many
screen pixels)
0.6devel20 ?
2005-05-13 [didge] 0.6devel19
** Tweaked makefile stuff and prepared for a release
2005-04-17 [mcoletti] 0.6devel18

View File

@ -25,7 +25,7 @@ dnl ---------------------------------------------------------------------------
MAJOR_VERSION=0
MINOR_VERSION=6
MICRO_VERSION=0
EXTRA_VERSION=20
EXTRA_VERSION=21
if test $EXTRA_VERSION -eq 0; then
VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}
else

View File

@ -175,6 +175,14 @@
<tree>
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
<hidenonprojectfiles>false</hidenonprojectfiles>
<showvcsfields>false</showvcsfields>
</tree>
</kdevfileview>
<kdevcvsservice>
<recursivewhenupdate>true</recursivewhenupdate>
<prunedirswhenupdate>true</prunedirswhenupdate>
<createdirswhenupdate>true</createdirswhenupdate>
<recursivewhencommitremove>true</recursivewhencommitremove>
<revertoptions>-C</revertoptions>
</kdevcvsservice>
</kdevelop>

View File

@ -22,8 +22,8 @@
QgsPoint QgsMapToPixel::toMapPoint(int x, int y)
{
double mx = x * mapUnitsPerPixel + xMin;
double my = -1 * ((y - yMax) * mapUnitsPerPixel - yMin);
double mx = x * mMapUnitsPerPixel + xMin;
double my = -1 * ((y - yMax) * mMapUnitsPerPixel - yMin);
return QgsPoint(mx, my);
}
@ -40,7 +40,12 @@ QgsPoint QgsMapToPixel::toMapCoordinates(int x, int y)
void QgsMapToPixel::setMapUnitsPerPixel(double mupp)
{
mapUnitsPerPixel = mupp;
mMapUnitsPerPixel = mupp;
}
double QgsMapToPixel::mapUnitsPerPixel()
{
return mMapUnitsPerPixel;
}
void QgsMapToPixel::setYmax(double ymax)
@ -60,7 +65,7 @@ void QgsMapToPixel::setXmin(double xmin)
void QgsMapToPixel::setParameters(double mupp, double xmin, double ymin, double ymax)
{
mapUnitsPerPixel = mupp;
mMapUnitsPerPixel = mupp;
xMin = xmin;
yMin = ymin;
yMax = ymax;
@ -70,7 +75,7 @@ void QgsMapToPixel::setParameters(double mupp, double xmin, double ymin, double
QString QgsMapToPixel::showParameters()
{
QString rep;
QTextOStream(&rep) << "Map units/pixel: " << mapUnitsPerPixel
QTextOStream(&rep) << "Map units/pixel: " << mMapUnitsPerPixel
<< " X minimum: " << xMin << " Y minimum: " << yMin << " Y maximum: " << yMax;
return rep;

View File

@ -85,6 +85,10 @@ class QgsMapToPixel{
* @param mupp Map units per pixel
*/
void setMapUnitsPerPixel(double mupp);
//! Return current map units per pixel
double mapUnitsPerPixel();
//! Set maximum y value
void setYmax(double ymax);
//! Set minimum y value
@ -102,7 +106,7 @@ class QgsMapToPixel{
QString showParameters();
private:
double mapUnitsPerPixel;
double mMapUnitsPerPixel;
double yMax;
double yMin;
double xMin;
@ -114,7 +118,7 @@ inline QgsMapToPixel::QgsMapToPixel(double mupp,
double ymax,
double ymin,
double xmin)
: mapUnitsPerPixel(mupp),
: mMapUnitsPerPixel(mupp),
yMax(ymax),
yMin(ymin),
xMin(xmin),
@ -156,8 +160,8 @@ inline void QgsMapToPixel::transform(QgsPoint* p)
inline void QgsMapToPixel::transformInPlace(double& x, double& y)
{
x = (x - xMin) / mapUnitsPerPixel;
y = yMax - (y - yMin) / mapUnitsPerPixel;
x = (x - xMin) / mMapUnitsPerPixel;
y = yMax - (y - yMin) / mMapUnitsPerPixel;
}
inline void QgsMapToPixel::transformInPlace(std::vector<double>& x,

View File

@ -1001,19 +1001,26 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
//the contents of the rasterViewPort will change
RasterViewPort *myRasterViewPort = new RasterViewPort();
// calculate raster pixel offsets from origin to clipped rect
// we're only interested in positive offsets where the origin of the raster
// is northwest of the origin of the view
myRasterViewPort->rectXOffsetInt = static_cast < int >((theViewExtent->xMin() - layerExtent.xMin()) / fabs(adfGeoTransform[1]));
if (myRasterViewPort->rectXOffsetInt < 0 )
myRasterViewPort->rectXOffsetFloat = (theViewExtent->xMin() - layerExtent.xMin()) / fabs(adfGeoTransform[1]);
myRasterViewPort->rectYOffsetFloat = (layerExtent.yMax() - theViewExtent->yMax()) / fabs(adfGeoTransform[5]);
if (myRasterViewPort->rectXOffsetFloat < 0 )
{
myRasterViewPort->rectXOffsetInt = 0;
myRasterViewPort->rectXOffsetFloat = 0;
}
myRasterViewPort->rectYOffsetInt = static_cast < int >((layerExtent.yMax() - theViewExtent->yMax()) / fabs(adfGeoTransform[5]));
if (myRasterViewPort->rectYOffsetInt < 0)
if (myRasterViewPort->rectYOffsetFloat < 0 )
{
myRasterViewPort->rectYOffsetInt = 0;
myRasterViewPort->rectYOffsetFloat = 0;
}
myRasterViewPort->rectXOffsetInt = static_cast < int >(myRasterViewPort->rectXOffsetFloat);
myRasterViewPort->rectYOffsetInt = static_cast < int >(myRasterViewPort->rectYOffsetFloat);
// get dimensions of clipped raster image in raster pixel space/ RasterIO will do the scaling for us.
// So for example, if the user is zoomed in a long way, there may only be e.g. 5x5 pixels retrieved from
@ -1027,6 +1034,12 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
abs(static_cast < int >(myRasterViewPort->clippedXMaxDouble - myRasterViewPort->clippedXMinDouble));
myRasterViewPort->clippedHeightInt =
abs(static_cast < int >(myRasterViewPort->clippedYMaxDouble - myRasterViewPort->clippedYMinDouble));
// Add one to the raster dimensions to guard against the integer truncation
// effects of static_cast<int>
myRasterViewPort->clippedWidthInt++;
myRasterViewPort->clippedHeightInt++;
// make sure we don't exceed size of raster
if (myRasterViewPort->clippedWidthInt > rasterXDimInt)
{
@ -1041,16 +1054,55 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
myRasterViewPort->topLeftPoint = theQgsMapToPixel->transform(myRasterExtent.xMin(), myRasterExtent.yMax());
myRasterViewPort->bottomRightPoint = theQgsMapToPixel->transform(myRasterExtent.xMax(), myRasterExtent.yMin());
myRasterViewPort->drawableAreaXDimInt = static_cast<int>(myRasterViewPort->bottomRightPoint.x()) - static_cast<int>(myRasterViewPort->topLeftPoint.x());
myRasterViewPort->drawableAreaYDimInt = static_cast<int>(myRasterViewPort->bottomRightPoint.y()) - static_cast<int>(myRasterViewPort->topLeftPoint.y());
myRasterViewPort->drawableAreaXDimInt =
static_cast<int>( myRasterViewPort->clippedWidthInt
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1]) );
myRasterViewPort->drawableAreaYDimInt =
static_cast<int>( myRasterViewPort->clippedHeightInt
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5]) );
draw(theQPainter,myRasterViewPort);
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::draw: mapUnitsPerPixel = " << theQgsMapToPixel->mapUnitsPerPixel() << std::endl;
std::cout << "QgsRasterLayer::draw: rectXOffsetFloat = " << myRasterViewPort->rectXOffsetFloat << std::endl;
std::cout << "QgsRasterLayer::draw: rectXOffsetInt = " << myRasterViewPort->rectXOffsetInt << std::endl;
std::cout << "QgsRasterLayer::draw: rectYOffsetFloat = " << myRasterViewPort->rectYOffsetFloat << std::endl;
std::cout << "QgsRasterLayer::draw: rectYOffsetInt = " << myRasterViewPort->rectYOffsetInt << std::endl;
std::cout << "QgsRasterLayer::draw: myRasterExtent.xMin() = " << myRasterExtent.xMin() << std::endl;
std::cout << "QgsRasterLayer::draw: myRasterExtent.xMax() = " << myRasterExtent.xMax() << std::endl;
std::cout << "QgsRasterLayer::draw: myRasterExtent.yMin() = " << myRasterExtent.yMin() << std::endl;
std::cout << "QgsRasterLayer::draw: myRasterExtent.yMax() = " << myRasterExtent.yMax() << std::endl;
std::cout << "QgsRasterLayer::draw: topLeftPoint.x() = " << myRasterViewPort->topLeftPoint.x() << std::endl;
std::cout << "QgsRasterLayer::draw: bottomRightPoint.x() = " << myRasterViewPort->bottomRightPoint.x() << std::endl;
std::cout << "QgsRasterLayer::draw: topLeftPoint.y() = " << myRasterViewPort->topLeftPoint.y() << std::endl;
std::cout << "QgsRasterLayer::draw: bottomRightPoint.y() = " << myRasterViewPort->bottomRightPoint.y() << std::endl;
std::cout << "QgsRasterLayer::draw: clippedXMinDouble = " << myRasterViewPort->clippedXMinDouble << std::endl;
std::cout << "QgsRasterLayer::draw: clippedXMaxDouble = " << myRasterViewPort->clippedXMaxDouble << std::endl;
std::cout << "QgsRasterLayer::draw: clippedYMinDouble = " << myRasterViewPort->clippedYMinDouble << std::endl;
std::cout << "QgsRasterLayer::draw: clippedYMaxDouble = " << myRasterViewPort->clippedYMaxDouble << std::endl;
std::cout << "QgsRasterLayer::draw: clippedWidthInt = " << myRasterViewPort->clippedWidthInt << std::endl;
std::cout << "QgsRasterLayer::draw: clippedHeightInt = " << myRasterViewPort->clippedHeightInt << std::endl;
std::cout << "QgsRasterLayer::draw: drawableAreaXDimInt = " << myRasterViewPort->drawableAreaXDimInt << std::endl;
std::cout << "QgsRasterLayer::draw: drawableAreaYDimInt = " << myRasterViewPort->drawableAreaYDimInt << std::endl;
#endif
draw(theQPainter, myRasterViewPort, theQgsMapToPixel);
delete myRasterViewPort;
}
void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterViewPort)
void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterViewPort,
QgsMapToPixel * theQgsMapToPixel)
{
#ifdef QGISDEBUG
std::cerr << "QgsRasterLayer::draw" << std::endl;
#endif
//
//
// The goal here is to make as many decisions as possible early on (outside of the rendering loop)
@ -1068,7 +1120,8 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
}
else
{
drawSingleBandGray(theQPainter, myRasterViewPort, getRasterBandNumber(grayBandNameQString));
drawSingleBandGray(theQPainter, myRasterViewPort,
theQgsMapToPixel, getRasterBandNumber(grayBandNameQString));
break;
}
// a "Gray" or "Undefined" layer drawn using a pseudocolor algorithm
@ -1080,7 +1133,8 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
}
else
{
drawSingleBandPseudoColor(theQPainter, myRasterViewPort, getRasterBandNumber(grayBandNameQString));
drawSingleBandPseudoColor(theQPainter, myRasterViewPort,
theQgsMapToPixel, getRasterBandNumber(grayBandNameQString));
break;
}
// a "Palette" layer drawn in gray scale (using only one of the color components)
@ -1097,7 +1151,8 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
#endif
int myBandNoInt = 1;
drawPalettedSingleBandGray(theQPainter, myRasterViewPort, myBandNoInt, grayBandNameQString);
drawPalettedSingleBandGray(theQPainter, myRasterViewPort,
theQgsMapToPixel, myBandNoInt, grayBandNameQString);
break;
}
@ -1112,12 +1167,14 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
{
int myBandNoInt = 1;
drawPalettedSingleBandPseudoColor(theQPainter, myRasterViewPort, myBandNoInt, grayBandNameQString);
drawPalettedSingleBandPseudoColor(theQPainter, myRasterViewPort,
theQgsMapToPixel, myBandNoInt, grayBandNameQString);
break;
}
//a "Palette" image where the bands contains 24bit color info and 8 bits is pulled out per color
case PALETTED_MULTI_BAND_COLOR:
drawPalettedMultiBandColor(theQPainter, myRasterViewPort, 1);
drawPalettedMultiBandColor(theQPainter, myRasterViewPort,
theQgsMapToPixel, 1);
break;
// a layer containing 2 or more bands, but using only one band to produce a grayscale image
case MULTI_BAND_SINGLE_BAND_GRAY:
@ -1138,7 +1195,8 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
{
//get the band number for the mapped gray band
drawMultiBandSingleBandGray(theQPainter, myRasterViewPort, getRasterBandNumber(grayBandNameQString));
drawMultiBandSingleBandGray(theQPainter, myRasterViewPort,
theQgsMapToPixel, getRasterBandNumber(grayBandNameQString));
break;
}
//a layer containing 2 or more bands, but using only one band to produce a pseudocolor image
@ -1151,13 +1209,15 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
else
{
drawMultiBandSingleBandPseudoColor(theQPainter, myRasterViewPort, getRasterBandNumber(grayBandNameQString));
drawMultiBandSingleBandPseudoColor(theQPainter, myRasterViewPort,
theQgsMapToPixel, getRasterBandNumber(grayBandNameQString));
break;
}
//a layer containing 2 or more bands, mapped to the three RGBcolors.
//In the case of a multiband with only two bands, one band will have to be mapped to more than one color
case MULTI_BAND_COLOR:
drawMultiBandColor(theQPainter, myRasterViewPort);
drawMultiBandColor(theQPainter, myRasterViewPort,
theQgsMapToPixel);
break;
default:
@ -1174,7 +1234,7 @@ void QgsRasterLayer::draw (QPainter * theQPainter, RasterViewPort * myRasterView
} //end of draw method
void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
#ifdef QGISDEBUG
std::cerr << "QgsRasterLayer::drawSingleBandGray called for layer " << theBandNoInt << std::endl;
@ -1214,15 +1274,44 @@ void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, RasterViewPort *
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
} // QgsRasterLayer::drawSingleBandGray
void QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawSingleBandPseudoColor called" << std::endl;
@ -1398,10 +1487,41 @@ void QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter, RasterVie
//render any inline filters
filterLayer(&myQImage);
//draw with the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
}
/**
@ -1410,7 +1530,7 @@ void QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter, RasterVie
* @param theRasterViewPort - pointer to the ViewPort struct containing dimensions of viewable area and subset area to be extracted from data file.
* @param theGdalBand - pointer to the GDALRasterBand which should be rendered.
*/
void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawPalettedSingleBandColor called" << std::endl;
@ -1450,10 +1570,41 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, RasterV
}
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
CPLFree(myGdalScanData);
}
@ -1465,8 +1616,9 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, RasterV
* @param theGdalBand - pointer to the GDALRasterBand which should be rendered.
* @param theColorQString - QString containing either 'Red' 'Green' or 'Blue' indicating which part of the rgb triplet will be used to render gray.
*/
void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter,
RasterViewPort * theRasterViewPort, int theBandNoInt, QString theColorQString)
void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel, int theBandNoInt,
QString theColorQString)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawPalettedSingleBandGray called" << std::endl;
@ -1523,10 +1675,40 @@ void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter,
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
}
@ -1537,8 +1719,9 @@ void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter,
* @param theGdalBand - pointer to the GDALRasterBand which should be rendered.
* @param theColorQString - QString containing either 'Red' 'Green' or 'Blue' indicating which part of the rgb triplet will be used to render gray.
*/
void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort, int theBandNoInt, QString theColorQString)
void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel, int theBandNoInt,
QString theColorQString)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawPalettedSingleBandPseudoColor called" << std::endl;
@ -1731,10 +1914,41 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter,
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
}
/**
@ -1743,7 +1957,7 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter,
* @param theRasterViewPort - pointer to the ViewPort struct containing dimensions of viewable area and subset area to be extracted from data file.
* @param theGdalBand - pointer to the GDALRasterBand which should be rendered.
*/
void QgsRasterLayer::drawPalettedMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawPalettedMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawPalettedMultiBandColor called" << std::endl;
@ -1810,29 +2024,57 @@ void QgsRasterLayer::drawPalettedMultiBandColor(QPainter * theQPainter, RasterVi
}
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage );
myQImage,
paintXoffset,
paintYoffset);
CPLFree(myGdalScanData);
// myQImage);
//>>>>>>> 1.98.2.9
}
void QgsRasterLayer::drawMultiBandSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawMultiBandSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
//delegate to drawSingleBandGray!
drawSingleBandGray(theQPainter, theRasterViewPort, theBandNoInt);
drawSingleBandGray(theQPainter, theRasterViewPort, theQgsMapToPixel, theBandNoInt);
}
void QgsRasterLayer::drawMultiBandSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt)
void QgsRasterLayer::drawMultiBandSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNoInt)
{
//delegate to drawSinglePseudocolor!
drawSingleBandPseudoColor(theQPainter, theRasterViewPort, theBandNoInt);
drawSingleBandPseudoColor(theQPainter, theRasterViewPort, theQgsMapToPixel, theBandNoInt);
}
void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort)
void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel)
{
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer::drawMultiBandColor called" << std::endl;
@ -1896,10 +2138,40 @@ void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, RasterViewPort *
//render any inline filters
filterLayer(&myQImage);
//part of the experimental transaparency support
// Set up the initial offset into the myQImage we want to copy to the map canvas
// This is useful when the source image pixels are larger than the screen image.
int paintXoffset = 0;
int paintYoffset = 0;
if (theQgsMapToPixel)
{
paintXoffset = static_cast<int>(
(theRasterViewPort->rectXOffsetFloat -
theRasterViewPort->rectXOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[1])
);
paintYoffset = static_cast<int>(
(theRasterViewPort->rectYOffsetFloat -
theRasterViewPort->rectYOffsetInt)
/ theQgsMapToPixel->mapUnitsPerPixel()
* fabs(adfGeoTransform[5])
);
}
#ifdef QGISDEBUG
std::cout << "QgsRasterLayer - painting image to canvas at "
<< paintXoffset << ", " << paintYoffset << "." << std::endl;
#endif
//part of the experimental transparency support
theQPainter->drawImage(static_cast<int>(theRasterViewPort->topLeftPoint.x()),
static_cast<int>(theRasterViewPort->topLeftPoint.y()),
myQImage);
myQImage,
paintXoffset,
paintYoffset);
//free the scanline memory
CPLFree(myGdalRedData);

View File

@ -243,11 +243,13 @@ typedef QValueVector<RasterBandStats> RasterStatsVector;
*/
struct RasterViewPort
{
/** \brief The offset from the left hand edge of the raster for the rectangle that will be drawn to screen.
* TODO Check this explanation is correc!*/
/** \brief The offset (in source raster pixel coordinates) from the left hand edge of the source raster for the rectangle that will be drawn to screen. */
float rectXOffsetFloat;
/** \brief The offset (in source raster pixel coordinates) from the top edge of the source raster for the rectangle that will be drawn to screen. */
float rectYOffsetFloat;
/** \brief The offset (in source raster pixel coordinates) from the left hand edge of the source raster for the rectangle that will be drawn to screen - truncated to an integer. */
int rectXOffsetInt;
/** \brief The offset from the bottom edge of the raster for the rectangle that will be drawn to screen.
* TODO Check this explanation is correc!*/
/** \brief The offset (in source raster pixel coordinates) from the top edge of the source raster for the rectangle that will be drawn to screen - truncated to an integer. */
int rectYOffsetInt;
/** \brief Lower left X dimension of clipped raster image in raster pixel space.
* RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only
@ -374,10 +376,12 @@ public:
QPixmap getPaletteAsPixmap();
/** \brief This is called when the view on the rasterlayer needs to be refreshed (redrawn). */
void draw(QPainter * theQPainter, QgsRect * theViewExtent, QgsMapToPixel * theQgsMapToPixel, QPaintDevice* dst);
void draw(QPainter * theQPainter, QgsRect * theViewExtent,
QgsMapToPixel * theQgsMapToPixel, QPaintDevice* dst);
/** \brief This is an overloaded version of the above function that is called by both draw above and drawThumbnail */
void draw (QPainter * theQPainter, RasterViewPort * myRasterViewPort);
void draw(QPainter * theQPainter, RasterViewPort * myRasterViewPort,
QgsMapToPixel * theQgsMapToPixel = 0);
//
// Accessors for image height and width
@ -865,10 +869,16 @@ private:
//
/** \brief Drawing routine for single band grayscale image. */
void drawSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt);
void drawSingleBandGray(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
/** \brief Drawing routine for single band grayscale image, rendered in pseudocolor. */
void drawSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt);
void drawSingleBandPseudoColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
//
@ -877,25 +887,29 @@ private:
/** \brief Drawing routine for paletted image, rendered as a single band image in color. */
void drawPalettedSingleBandColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
/** \brief Drawing routine for paletted image, rendered as a single band image in grayscale. */
void drawPalettedSingleBandGray(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt,
QString theColorQString);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt,
QString theColorQString);
/** \brief Drawing routine for paletted image, rendered as a single band image in pseudocolor. */
void drawPalettedSingleBandPseudoColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt,
QString theColorQString);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt,
QString theColorQString);
/** \brief Drawing routine for paletted multiband image. */
void drawPalettedMultiBandColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
//
// Multiband Layers
@ -903,17 +917,21 @@ private:
/** \brief Drawing routine for multiband image, rendered as a single band image in grayscale. */
void drawMultiBandSingleBandGray(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
/** \brief Drawing routine for multiband image, rendered as a single band image in pseudocolor. */
void drawMultiBandSingleBandPseudoColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
int theBandNoInt);
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel,
int theBandNoInt);
/** \brief Drawing routine for multiband image */
void drawMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort);
void drawMultiBandColor(QPainter * theQPainter,
RasterViewPort * theRasterViewPort,
QgsMapToPixel * theQgsMapToPixel);
/** \brief Read color table from GDAL raster band */
void readColorTable ( GDALRasterBand *gdalBand, QgsColorTable *theColorTable );