33 #include <QDomDocument>
35 #include <QMutexLocker>
37 #include <QListIterator>
40 #include <QCoreApplication>
54 mSize = QSize( 0, 0 );
98 if ( extent.
width() > 0 &&
100 extent.
width() < 1 &&
105 double xMean = ( qAbs( extent.
xMinimum() ) + qAbs( extent.
xMaximum() ) ) * 0.5;
106 double yMean = ( qAbs( extent.
yMinimum() ) + qAbs( extent.
yMaximum() ) ) * 0.5;
108 double xRange = extent.
width() / xMean;
109 double yRange = extent.
height() / yMean;
111 static const double minProportion = 1e-12;
112 if ( xRange < minProportion || yRange < minProportion )
126 mSize = QSizeF( size.width(), size.height() );
145 return mSize.toSize();
155 double myHeight =
mSize.height();
156 double myWidth =
mSize.width();
160 if ( !myWidth || !myHeight )
171 mMapUnitsPerPixel = mapUnitsPerPixelY > mapUnitsPerPixelX ? mapUnitsPerPixelY : mapUnitsPerPixelX;
174 double dxmin, dxmax, dymin, dymax, whitespace;
176 if ( mapUnitsPerPixelY > mapUnitsPerPixelX )
227 bool mySameAsLastFlag =
true;
237 if (
mSize.width() == 1 &&
mSize.height() == 1 )
243 QPaintDevice* thePaintDevice = painter->device();
244 if ( !thePaintDevice )
253 QCoreApplication::processEvents();
283 int myRed = prj->
readNumEntry(
"Gui",
"/SelectionColorRedPart", 255 );
284 int myGreen = prj->
readNumEntry(
"Gui",
"/SelectionColorGreenPart", 255 );
285 int myBlue = prj->
readNumEntry(
"Gui",
"/SelectionColorBluePart", 0 );
286 int myAlpha = prj->
readNumEntry(
"Gui",
"/SelectionColorAlphaPart", 255 );
293 double scaleFactor = 1.0;
296 if ( forceWidthScale )
298 scaleFactor = *forceWidthScale;
302 scaleFactor = sceneDpi / 25.4;
305 double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
309 mySameAsLastFlag =
false;
314 mySameAsLastFlag =
false;
320 mySameAsLastFlag =
false;
325 mySameAsLastFlag =
false;
334 if ( !mySameAsLastFlag )
337 QSettings mySettings;
338 if ( mySettings.value(
"/qgis/enable_render_caching",
false ).toBool() )
350 while ( li.hasPrevious() )
361 QImage * mypFlattenedImage = 0;
363 QString layerId = li.previous();
365 QgsDebugMsg(
"Rendering at layer item " + layerId );
373 QgsDebugMsg(
"If there is a QPaintEngine error here, it is caused by an emit call" );
384 QgsDebugMsg( QString(
"layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 extent:%5 blendmode:%6" )
397 mypContextPainter->setCompositionMode( ml->
blendMode() );
433 bool scaleRaster =
false;
454 QSettings mySettings;
455 bool useRenderCaching =
false;
458 if ( mySettings.value(
"/qgis/enable_render_caching",
false ).toBool() )
460 useRenderCaching =
true;
461 if ( !mySameAsLastFlag || ml->
cacheImage() == 0 )
463 QgsDebugMsg(
"Caching enabled but layer redraw forced by extent change or empty cache" );
466 if ( mypImage->isNull() )
475 QPainter * mypPainter =
new QPainter( ml->
cacheImage() );
477 if ( mySettings.value(
"/qgis/enable_anti_aliasing",
true ).toBool() )
479 mypPainter->setRenderHint( QPainter::Antialiasing );
483 else if ( mySameAsLastFlag )
486 QgsDebugMsg(
"Caching enabled --- drawing layer from cached image" );
487 mypContextPainter->drawImage( 0, 0, *( ml->
cacheImage() ) );
499 bool flattenedLayer =
false;
503 if (( !useRenderCaching )
504 && (( vl->
blendMode() != QPainter::CompositionMode_SourceOver )
508 flattenedLayer =
true;
511 if ( mypFlattenedImage->isNull() )
518 mypFlattenedImage->fill( 0 );
519 QPainter * mypPainter =
new QPainter( mypFlattenedImage );
520 if ( mySettings.value(
"/qgis/enable_anti_aliasing",
true ).toBool() )
522 mypPainter->setRenderHint( QPainter::Antialiasing );
524 mypPainter->scale( rasterScaleFactor, rasterScaleFactor );
584 QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->
layerTransparency() / 100 ) );
592 if ( useRenderCaching )
600 mypContextPainter->drawImage( 0, 0, *( ml->
cacheImage() ) );
602 else if ( flattenedLayer )
607 mypContextPainter->save();
608 mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
609 mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
610 mypContextPainter->restore();
611 delete mypFlattenedImage;
612 mypFlattenedImage = 0;
619 QgsDebugMsg(
"Layer not rendered because it is not within the defined "
620 "visibility scale range" );
634 while ( li.hasPrevious() )
641 QString layerId = li.previous();
692 QgsDebugMsg(
"Rendering completed in (seconds): " + QString(
"%1" ).arg( renderTime.elapsed() / 1000.0 ) );
726 QgsDebugMsg(
"Adjusting DistArea projection on/off" );
746 if ( refreshCoordinateTransformInfo )
796 static const double splitCoord = 180.0;
809 ll = transform->
transform( ll.x(), ll.y(),
811 ur = transform->
transform( ur.x(), ur.y(),
816 if ( ll.x() > ur.x() )
836 extent =
QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX );
837 r2 =
QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX );
998 QStringList::iterator it =
mLayerSet.begin();
1005 QgsDebugMsg( QString(
"WARNING: layer '%1' not found in map layer registry!" ).arg( *it ) );
1042 const double padFactor = 1e-8;
1064 QgsDebugMsg( QString(
"Entering: %1" ).arg( layers.join(
", " ) ) );
1076 QDomNode myNode = theNode.namedItem(
"units" );
1077 QDomElement element = myNode.toElement();
1081 if (
"meters" == element.text() )
1085 else if (
"feet" == element.text() )
1089 else if (
"nautical miles" == element.text() )
1093 else if (
"degrees" == element.text() )
1097 else if (
"unknown" == element.text() )
1103 QgsDebugMsg(
"Unknown map unit type " + element.text() );
1109 QDomNode projNode = theNode.namedItem(
"projections" );
1110 element = projNode.toElement();
1115 QDomElement layerCoordTransformInfoElem = theNode.firstChildElement(
"layer_coordinate_transform_info" );
1116 if ( !layerCoordTransformInfoElem.isNull() )
1118 QDomNodeList layerCoordinateTransformList = layerCoordTransformInfoElem.elementsByTagName(
"layer_coordinate_transform" );
1119 QDomElement layerCoordTransformElem;
1120 for (
int i = 0; i < layerCoordinateTransformList.size(); ++i )
1122 layerCoordTransformElem = layerCoordinateTransformList.at( i ).toElement();
1123 QString layerId = layerCoordTransformElem.attribute(
"layerid" );
1124 if ( layerId.isEmpty() )
1130 lct.
srcAuthId = layerCoordTransformElem.attribute(
"srcAuthId" );
1131 lct.
destAuthId = layerCoordTransformElem.attribute(
"destAuthId" );
1132 lct.
srcDatumTransform = layerCoordTransformElem.attribute(
"srcDatumTransform",
"-1" ).toInt();
1133 lct.
destDatumTransform = layerCoordTransformElem.attribute(
"destDatumTransform",
"-1" ).toInt();
1140 QDomNode srsNode = theNode.namedItem(
"destinationsrs" );
1146 QDomNode extentNode = theNode.namedItem(
"extent" );
1148 QDomNode xminNode = extentNode.namedItem(
"xmin" );
1149 QDomNode yminNode = extentNode.namedItem(
"ymin" );
1150 QDomNode xmaxNode = extentNode.namedItem(
"xmax" );
1151 QDomNode ymaxNode = extentNode.namedItem(
"ymax" );
1153 QDomElement exElement = xminNode.toElement();
1154 double xmin = exElement.text().toDouble();
1157 exElement = yminNode.toElement();
1158 double ymin = exElement.text().toDouble();
1161 exElement = xmaxNode.toElement();
1162 double xmax = exElement.text().toDouble();
1165 exElement = ymaxNode.toElement();
1166 double ymax = exElement.text().toDouble();
1178 QDomElement unitsNode = theDoc.createElement(
"units" );
1179 theNode.appendChild( unitsNode );
1181 QString unitsString;
1186 unitsString =
"meters";
1189 unitsString =
"feet";
1192 unitsString =
"nautical miles";
1195 unitsString =
"degrees";
1199 unitsString =
"unknown";
1202 QDomText unitsText = theDoc.createTextNode( unitsString );
1203 unitsNode.appendChild( unitsText );
1207 QDomElement extentNode = theDoc.createElement(
"extent" );
1208 theNode.appendChild( extentNode );
1210 QDomElement xMin = theDoc.createElement(
"xmin" );
1211 QDomElement yMin = theDoc.createElement(
"ymin" );
1212 QDomElement xMax = theDoc.createElement(
"xmax" );
1213 QDomElement yMax = theDoc.createElement(
"ymax" );
1221 xMin.appendChild( xMinText );
1222 yMin.appendChild( yMinText );
1223 xMax.appendChild( xMaxText );
1224 yMax.appendChild( yMaxText );
1226 extentNode.appendChild( xMin );
1227 extentNode.appendChild( yMin );
1228 extentNode.appendChild( xMax );
1229 extentNode.appendChild( yMax );
1232 QDomElement projNode = theDoc.createElement(
"projections" );
1233 theNode.appendChild( projNode );
1236 projNode.appendChild( projText );
1239 QDomElement srsNode = theDoc.createElement(
"destinationsrs" );
1240 theNode.appendChild( srsNode );
1244 QDomElement layerCoordTransformInfo = theDoc.createElement(
"layer_coordinate_transform_info" );
1248 QDomElement layerCoordTransformElem = theDoc.createElement(
"layer_coordinate_transform" );
1249 layerCoordTransformElem.setAttribute(
"layerid", coordIt.key() );
1250 layerCoordTransformElem.setAttribute(
"srcAuthId", coordIt->srcAuthId );
1251 layerCoordTransformElem.setAttribute(
"destAuthId", coordIt->destAuthId );
1252 layerCoordTransformElem.setAttribute(
"srcDatumTransform", QString::number( coordIt->srcDatumTransform ) );
1253 layerCoordTransformElem.setAttribute(
"destDatumTransform", QString::number( coordIt->destDatumTransform ) );
1254 layerCoordTransformInfo.appendChild( layerCoordTransformElem );
1256 theNode.appendChild( layerCoordTransformInfo );
1282 && ctIt->srcAuthId == layer->
crs().
authid()
1295 || ctIt->srcAuthId == layer->
crs().
authid()
1309 switch ( blendMode )
1312 return QPainter::CompositionMode_SourceOver;
1314 return QPainter::CompositionMode_Lighten;
1316 return QPainter::CompositionMode_Screen;
1318 return QPainter::CompositionMode_ColorDodge;
1320 return QPainter::CompositionMode_Plus;
1322 return QPainter::CompositionMode_Darken;
1324 return QPainter::CompositionMode_Multiply;
1326 return QPainter::CompositionMode_ColorBurn;
1328 return QPainter::CompositionMode_Overlay;
1330 return QPainter::CompositionMode_SoftLight;
1332 return QPainter::CompositionMode_HardLight;
1334 return QPainter::CompositionMode_Difference;
1336 return QPainter::CompositionMode_Exclusion;
1338 return QPainter::CompositionMode_SourceOver;
1345 switch ( blendMode )
1347 case QPainter::CompositionMode_SourceOver:
1349 case QPainter::CompositionMode_Lighten:
1351 case QPainter::CompositionMode_Screen:
1353 case QPainter::CompositionMode_ColorDodge:
1355 case QPainter::CompositionMode_Plus:
1357 case QPainter::CompositionMode_Darken:
1359 case QPainter::CompositionMode_Multiply:
1361 case QPainter::CompositionMode_ColorBurn:
1363 case QPainter::CompositionMode_Overlay:
1365 case QPainter::CompositionMode_SoftLight:
1367 case QPainter::CompositionMode_HardLight:
1369 case QPainter::CompositionMode_Difference:
1371 case QPainter::CompositionMode_Exclusion:
virtual void exit()=0
called when we're done with rendering
void setMapUnits(QGis::UnitType mapUnits)
Set the map units.
void unionRect(const QgsRectangle &rect)
updates rectangle to include passed argument
void setRenderingStopped(bool stopped)
A rectangle specified with double values.
Base class for all map layer types.
void clearLayerCoordinateTransforms()
void render(QPainter *painter, double *forceWidthScale=0)
starts rendering @ param forceWidthScale Force a specific scale factor for line widths and marker siz...
void setLabelingEngine(QgsLabelingEngineInterface *iface)
Set labeling engine.
bool isEmpty() const
test if rectangle is empty
QgsMapLayer::LayerType type() const
Get the type of the layer.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
virtual void drawLabels(QgsRenderContext &rendererContext)
Draw labels.
void setYMaximum(double ymax)
Set maximum y value.
void drawError(QgsMapLayer *)
emitted when layer's draw() returned false
void setCacheImage(QImage *thepImage)
Set the QImage used for caching render operations.
void setXMaximum(double x)
Set the maximum x value.
OutputUnits mOutputUnits
Output units.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
double yMaximum() const
Get the y maximum value (top side of rectangle)
bool mProjectionsEnabled
detemines whether on the fly projection support is enabled
QgsRectangle mLastExtent
Last extent to we drew so we know if we can used layer render caching or not.
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
double rendererScale() const
QgsScaleCalculator * mScaleCalculator
scale calculator
QgsRectangle extent() const
returns current extent
QString qgsDoubleToString(const double &a)
void addLayerCoordinateTransform(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform=-1, int destDatumTransform=-1)
void setRendererScale(double scale)
float minimumScale() const
void drawingProgress(int current, int total)
~QgsMapRenderer()
destructor
void setDpi(double dpi)
Set the dpi to be used in scale calculations.
QGis::UnitType mapUnits() const
Returns current map units.
QImage * cacheImage()
Get the QImage used for caching render operations.
void setProjectionsEnabled(bool enabled)
sets whether to use projections for this layer set
static bool mDrawing
indicates drawing in progress
bool splitLayersExtent(QgsMapLayer *layer, QgsRectangle &extent, QgsRectangle &r2)
Convenience function to project an extent into the layer source CRS, but also split it into two exten...
double scaleFactor() const
void setLayerSet(const QStringList &layers)
change current layer set
double outputDpi()
accessor for output dpi
QgsPoint mapToLayerCoordinates(QgsMapLayer *theLayer, QgsPoint point)
transform point coordinates from output CRS to layer's CRS
QgsRectangle outputExtentToLayerExtent(QgsMapLayer *theLayer, QgsRectangle extent)
transform bounding box from output CRS to layer's CRS
void setExtent(const QgsRectangle &extent)
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=0) const
const QgsCoordinateTransform * transformation(const QgsMapLayer *layer) const
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
QgsRectangle mExtent
current extent to be drawn
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
QgsMapRenderer()
constructor
QgsPoint layerToMapCoordinates(QgsMapLayer *theLayer, QgsPoint point)
transform point coordinates from layer's CRS to output CRS
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
void setCoordinateTransform(const QgsCoordinateTransform *t)
Sets coordinate transformation.
QSize outputSize()
accessor for output size
virtual bool draw(QgsRenderContext &rendererContext)
This is the method that does the actual work of drawing the layer onto a paint device.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
const QString & name() const
Get the display name of the layer.
QMutex mRenderMutex
Locks rendering loop for concurrent draws.
Perform transforms between map coordinates and device coordinates.
void setSelectionColor(const QColor &color)
Added in QGIS v2.0.
QPainter::CompositionMode blendMode() const
Read blend mode for layer.
QgsCoordinateReferenceSystem * mDestCRS
destination spatial reference system of the projection
void setScaleFactor(double factor)
QgsDistanceArea * mDistArea
tool for measuring
QPainter::CompositionMode featureBlendMode() const
Read blend mode for layer.
double calculate(const QgsRectangle &mapExtent, int canvasWidth)
Calculate the scale denominator.
bool hasScaleBasedVisibility() const
void adjustExtentToSize()
adjust extent to fit the pixmap size
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
void hasCrsTransformEnabledChanged(bool flag)
This signal is emitted when CRS transformation is enabled/disabled.
#define QgsDebugMsgLevel(str, level)
bool renderingStopped() const
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
float maximumScale() const
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void setYMinimum(double y)
Set the minimum y value.
void setDrawEditingInformation(bool b)
bool setExtent(const QgsRectangle &extent)
sets extent and checks whether suitable (returns false if not)
void setMapUnits(QGis::UnitType u)
const long GEOCRS_ID
Magic number for a geographic coord sys in QGIS srs.db tbl_srs.srs_id.
void destinationSrsChanged()
void setPainter(QPainter *p)
double rasterScaleFactor() const
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Reads and writes project states.
bool mOverview
indicates whether it's map image for overview
double mapUnitsPerPixel() const
Return current map units per pixel.
void setOutputSize(QSize size, int dpi)
A class to represent a point geometry.
void updateFullExtent()
updates extent of the layer set
This class tracks map layers that are currently loaded and provides a means to fetch a pointer to a m...
double dpi()
Accessor for dpi used in scale calculations.
bool writeXML(QDomNode &theNode, QDomDocument &theDoc)
write settings
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
int layerTransparency() const
Read transparency for layer.
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode Added in 1.9.
General purpose distance and area calculator.
QgsRectangle fullExtent()
returns current extent of layer set
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
virtual void drawLabeling(QgsRenderContext &context)=0
called when the map is drawn and labels should be placed
void setYMaximum(double y)
Set the maximum y value.
void onDrawingProgress(int current, int total)
called by signal from layer current being drawn
void setLabelingEngine(QgsLabelingEngineInterface *iface)
Added in QGIS v1.4.
double mScale
Map scale denominator at its current zoom level.
QHash< QString, QgsLayerCoordinateTransform > mLayerCoordinateTransformInfo
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs, bool refreshCoordinateTransformInfo=true)
sets destination coordinate reference system
static QgsProject * instance()
access to canonical QgsProject instance
Class for storing a coordinate reference system (CRS)
void setMapToPixel(const QgsMapToPixel &mtp)
UnitType
Map units that qgis supports.
const QgsMapToPixel & mapToPixel() const
void clearAllLayerCaches()
Clears all layer caches, resetting them to zero and freeing up any memory they may have been using...
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
void setParameters(double mapUnitsPerPixel, double xmin, double ymin, double ymax)
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
bool readXML(QDomNode &theNode)
virtual bool willUseLayer(QgsVectorLayer *layer)=0
called to find out whether the layer is used for labeling
void updateScale()
Recalculate the map scale.
QStringList mLayerSet
stores array of layers to be rendered (identified by string)
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
void setRasterScaleFactor(double factor)
virtual void init(QgsMapRenderer *mp)=0
called when we're going to start with rendering
void datumTransformInfoRequested(const QgsMapLayer *ml, const QString &srcAuthId, const QString &destAuthId) const
Notifies higher level components to show the datum transform dialog and add a QgsLayerCoordinateTrans...
Custom exception class for Coordinate Reference System related exceptions.
double mMapUnitsPerPixel
map units per pixel
Labeling engine interface.
QgsRenderContext mRenderContext
Encapsulates context of rendering.
double width() const
Width of the rectangle.
void setMapUnitsPerPixel(double mapUnitsPerPixel)
virtual bool isEditable() const
Returns true if the provider is in editing mode.
virtual QgsRectangle extent()
Return the extent of the layer.
QGis::UnitType mapUnits() const
Represents a vector layer which manages a vector based data sets.
QgsLabelingEngineInterface * mLabelingEngine
Labeling engine (NULL by default)
bool geographicFlag() const
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
bool readXML(QDomNode &theNode)
read settings
double xMinimum() const
Get the x minimum value (left side of rectangle)
QStringList & layerSet()
returns current layer set
QgsRectangle mFullExtent
full extent of the layer set
void setXMinimum(double x)
Set the minimum x value.
void setEllipsoidalMode(bool flag)
sets whether coordinates must be projected to ellipsoid before measuring
QgsRectangle layerExtentToOutputExtent(QgsMapLayer *theLayer, QgsRectangle extent)
transform bounding box from layer's CRS to output CRS
QgsLabelingEngineInterface * labelingEngine() const
Added in QGIS v1.4.
double height() const
Height of the rectangle.
QString toProj4() const
Get the Proj Proj4 string representation of this srs.