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" );
791 static const double splitCoord = 180.0;
805 if ( ll.
x() > ur.
x() )
822 extent =
QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX );
823 r2 =
QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX );
831 QgsDebugMsg( QString(
"sourceCrs = " +
tr( theLayer )->sourceCrs().authid() ) );
832 QgsDebugMsg( QString(
"destCRS = " +
tr( theLayer )->destCRS().authid() ) );
853 QgsDebugMsg( QString(
"layer sourceCrs = " +
tr( theLayer )->sourceCrs().authid() ) );
854 QgsDebugMsg( QString(
"layer destCRS = " +
tr( theLayer )->destCRS().authid() ) );
961 QStringList::iterator it =
mLayerSet.begin();
968 QgsDebugMsg( QString(
"WARNING: layer '%1' not found in map layer registry!" ).arg( *it ) );
1005 const double padFactor = 1e-8;
1027 QgsDebugMsg( QString(
"Entering: %1" ).arg( layers.join(
", " ) ) );
1039 QDomNode myNode = theNode.namedItem(
"units" );
1040 QDomElement element = myNode.toElement();
1044 if (
"meters" == element.text() )
1048 else if (
"feet" == element.text() )
1052 else if (
"degrees" == element.text() )
1056 else if (
"unknown" == element.text() )
1062 QgsDebugMsg(
"Unknown map unit type " + element.text() );
1068 QDomNode projNode = theNode.namedItem(
"projections" );
1069 element = projNode.toElement();
1074 QDomNode srsNode = theNode.namedItem(
"destinationsrs" );
1080 QDomNode extentNode = theNode.namedItem(
"extent" );
1082 QDomNode xminNode = extentNode.namedItem(
"xmin" );
1083 QDomNode yminNode = extentNode.namedItem(
"ymin" );
1084 QDomNode xmaxNode = extentNode.namedItem(
"xmax" );
1085 QDomNode ymaxNode = extentNode.namedItem(
"ymax" );
1087 QDomElement exElement = xminNode.toElement();
1088 double xmin = exElement.text().toDouble();
1091 exElement = yminNode.toElement();
1092 double ymin = exElement.text().toDouble();
1095 exElement = xmaxNode.toElement();
1096 double xmax = exElement.text().toDouble();
1099 exElement = ymaxNode.toElement();
1100 double ymax = exElement.text().toDouble();
1111 QDomElement unitsNode = theDoc.createElement(
"units" );
1112 theNode.appendChild( unitsNode );
1114 QString unitsString;
1119 unitsString =
"meters";
1122 unitsString =
"feet";
1125 unitsString =
"degrees";
1129 unitsString =
"unknown";
1132 QDomText unitsText = theDoc.createTextNode( unitsString );
1133 unitsNode.appendChild( unitsText );
1137 QDomElement extentNode = theDoc.createElement(
"extent" );
1138 theNode.appendChild( extentNode );
1140 QDomElement xMin = theDoc.createElement(
"xmin" );
1141 QDomElement yMin = theDoc.createElement(
"ymin" );
1142 QDomElement xMax = theDoc.createElement(
"xmax" );
1143 QDomElement yMax = theDoc.createElement(
"ymax" );
1151 xMin.appendChild( xMinText );
1152 yMin.appendChild( yMinText );
1153 xMax.appendChild( xMaxText );
1154 yMax.appendChild( yMaxText );
1156 extentNode.appendChild( xMin );
1157 extentNode.appendChild( yMin );
1158 extentNode.appendChild( xMax );
1159 extentNode.appendChild( yMax );
1162 QDomElement projNode = theDoc.createElement(
"projections" );
1163 theNode.appendChild( projNode );
1166 projNode.appendChild( projText );
1169 QDomElement srsNode = theDoc.createElement(
"destinationsrs" );
1170 theNode.appendChild( srsNode );
1198 switch ( blendMode )
1201 return QPainter::CompositionMode_SourceOver;
1203 return QPainter::CompositionMode_Lighten;
1205 return QPainter::CompositionMode_Screen;
1207 return QPainter::CompositionMode_ColorDodge;
1209 return QPainter::CompositionMode_Plus;
1211 return QPainter::CompositionMode_Darken;
1213 return QPainter::CompositionMode_Multiply;
1215 return QPainter::CompositionMode_ColorBurn;
1217 return QPainter::CompositionMode_Overlay;
1219 return QPainter::CompositionMode_SoftLight;
1221 return QPainter::CompositionMode_HardLight;
1223 return QPainter::CompositionMode_Difference;
1225 return QPainter::CompositionMode_Exclusion;
1227 return QPainter::CompositionMode_SourceOver;
1234 switch ( blendMode )
1236 case QPainter::CompositionMode_SourceOver:
1238 case QPainter::CompositionMode_Lighten:
1240 case QPainter::CompositionMode_Screen:
1242 case QPainter::CompositionMode_ColorDodge:
1244 case QPainter::CompositionMode_Plus:
1246 case QPainter::CompositionMode_Darken:
1248 case QPainter::CompositionMode_Multiply:
1250 case QPainter::CompositionMode_ColorBurn:
1252 case QPainter::CompositionMode_Overlay:
1254 case QPainter::CompositionMode_SoftLight:
1256 case QPainter::CompositionMode_HardLight:
1258 case QPainter::CompositionMode_Difference:
1260 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 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.
virtual void drawLabels(QgsRenderContext &rendererContext)
Draw labels.
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
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 setRendererScale(double scale)
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
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode Added in 1.9.
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
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 setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints. The rectangle is.
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.
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)
#define QgsDebugMsgLevel(str, level)
bool renderingStopped() const
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
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.
bool hasScaleBasedVisibility()
void destinationSrsChanged()
void setPainter(QPainter *p)
double rasterScaleFactor() const
Reads and writes project states.
bool mOverview
indicates whether it's map image for overview
const QgsCoordinateTransform * tr(QgsMapLayer *layer)
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.
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.
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)
void setRasterScaleFactor(double factor)
virtual void init(QgsMapRenderer *mp)=0
called when we're going to start with rendering
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.