Skip to content

Commit 716d619

Browse files
committed
Print svg item in qgis server. Developed for Faunalia (http://www.faunalia.it) with funding from Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED AMBIENTALE
1 parent cca386f commit 716d619

File tree

2 files changed

+101
-25
lines changed

2 files changed

+101
-25
lines changed

src/mapserver/qgsprojectparser.cpp

+93-23
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "qgscomposershape.h"
3939

4040
#include "QFileInfo"
41+
#include <QSvgRenderer>
4142
#include <QTextDocument>
4243
#include "QTextStream"
4344

@@ -75,6 +76,7 @@ QgsProjectParser::QgsProjectParser( QDomDocument* xmlDoc, const QString& filePat
7576

7677
mRestrictedLayers = restrictedLayers();
7778
createTextAnnotationItems();
79+
createSvgAnnotationItems();
7880
}
7981
}
8082

@@ -86,6 +88,7 @@ QgsProjectParser::~QgsProjectParser()
8688
{
8789
delete mXMLDoc;
8890
cleanupTextAnnotationItems();
91+
cleanupSvgAnnotationItems();
8992
}
9093

9194
int QgsProjectParser::numberOfLayers() const
@@ -2451,16 +2454,60 @@ void QgsProjectParser::drawOverlays( QPainter* p, int dpi, int width, int height
24512454

24522455
//calculate item position
24532456
double xPos, yPos;
2454-
if ( !annotationPosition( annotationElem, scaleFactor, prjExtent, width, height, itemWidth, itemHeight, xPos, yPos ) )
2457+
if ( !annotationPosition( annotationElem, scaleFactor, xPos, yPos ) )
24552458
{
24562459
continue;
24572460
}
24582461

24592462
drawAnnotationRectangle( p, annotationElem, scaleFactor, xPos, yPos, itemWidth, itemHeight );
24602463

24612464
//draw annotation contents
2462-
p->translate( xPos / scaleFactor, yPos / scaleFactor );
2463-
textIt->first->drawContents( p, QRectF( 0, 0, itemWidth, itemHeight ) );
2465+
p->translate( xPos, yPos );
2466+
p->scale( scaleFactor, scaleFactor );
2467+
textIt->first->drawContents( p, QRectF( 0, 0, itemWidth / scaleFactor, itemHeight / scaleFactor ) );
2468+
p->restore();
2469+
}
2470+
2471+
//svg annotations
2472+
QList< QPair< QSvgRenderer*, QDomElement > >::const_iterator svgIt = mSvgAnnotationElems.constBegin();
2473+
QDomElement annotationElem;
2474+
for ( ; svgIt != mSvgAnnotationElems.constEnd(); ++svgIt )
2475+
{
2476+
annotationElem = svgIt->second;
2477+
int itemWidth = annotationElem.attribute( "frameWidth", "0" ).toInt() * scaleFactor;
2478+
int itemHeight = annotationElem.attribute( "frameHeight", "0" ).toInt() * scaleFactor;
2479+
2480+
//calculate item position
2481+
double xPos, yPos;
2482+
if ( !annotationPosition( annotationElem, scaleFactor, xPos, yPos ) )
2483+
{
2484+
continue;
2485+
}
2486+
2487+
drawAnnotationRectangle( p, annotationElem, scaleFactor, xPos, yPos, itemWidth, itemHeight );
2488+
2489+
//keep width/height ratio of svg
2490+
QRect viewBox = svgIt->first->viewBox();
2491+
if ( viewBox.isValid() )
2492+
{
2493+
double widthRatio = ( double )( itemWidth ) / ( double )( viewBox.width() );
2494+
double heightRatio = ( double )( itemHeight ) / ( double )( viewBox.height() );
2495+
double renderWidth = 0;
2496+
double renderHeight = 0;
2497+
if ( widthRatio <= heightRatio )
2498+
{
2499+
renderWidth = itemWidth;
2500+
renderHeight = viewBox.height() * itemWidth / viewBox.width() ;
2501+
}
2502+
else
2503+
{
2504+
renderHeight = itemHeight;
2505+
renderWidth = viewBox.width() * itemHeight / viewBox.height() ;
2506+
}
2507+
2508+
svgIt->first->render( p, QRectF( xPos, yPos, renderWidth,
2509+
renderHeight ) );
2510+
}
24642511
}
24652512
}
24662513

@@ -2491,6 +2538,44 @@ void QgsProjectParser::createTextAnnotationItems()
24912538
}
24922539
}
24932540

2541+
void QgsProjectParser::createSvgAnnotationItems()
2542+
{
2543+
mSvgAnnotationElems.clear();
2544+
if ( !mXMLDoc )
2545+
{
2546+
return;
2547+
}
2548+
2549+
QDomElement qgisElem = mXMLDoc->documentElement();
2550+
QDomNodeList svgAnnotationList = qgisElem.elementsByTagName( "SVGAnnotationItem" );
2551+
QDomElement svgAnnotationElem;
2552+
QDomElement annotationElem;
2553+
for ( int i = 0; i < svgAnnotationList.size(); ++i )
2554+
{
2555+
svgAnnotationElem = svgAnnotationList.at( i ).toElement();
2556+
annotationElem = svgAnnotationElem.firstChildElement( "AnnotationItem" );
2557+
QSvgRenderer* svg = new QSvgRenderer();
2558+
if ( svg->load( convertToAbsolutePath( svgAnnotationElem.attribute( "file" ) ) ) )
2559+
{
2560+
mSvgAnnotationElems.push_back( qMakePair( svg, annotationElem ) );
2561+
}
2562+
else
2563+
{
2564+
delete svg;
2565+
}
2566+
}
2567+
}
2568+
2569+
void QgsProjectParser::cleanupSvgAnnotationItems()
2570+
{
2571+
QList< QPair< QSvgRenderer*, QDomElement > >::const_iterator it = mSvgAnnotationElems.constBegin();
2572+
for ( ; it != mSvgAnnotationElems.constEnd(); ++it )
2573+
{
2574+
delete it->first;
2575+
}
2576+
mSvgAnnotationElems.clear();
2577+
}
2578+
24942579
void QgsProjectParser::cleanupTextAnnotationItems()
24952580
{
24962581
QList< QPair< QTextDocument*, QDomElement > >::const_iterator it = mTextAnnotationItems.constBegin();
@@ -2501,23 +2586,11 @@ void QgsProjectParser::cleanupTextAnnotationItems()
25012586
mTextAnnotationItems.clear();
25022587
}
25032588

2504-
bool QgsProjectParser::annotationPosition( const QDomElement& elem, double scaleFactor, const QgsRectangle& projectExtent, int width, int height,
2505-
int itemWidth, int itemHeight, double& xPos, double& yPos )
2589+
bool QgsProjectParser::annotationPosition( const QDomElement& elem, double scaleFactor,
2590+
double& xPos, double& yPos )
25062591
{
2507-
if ( projectExtent.isEmpty() )
2508-
{
2509-
return false;
2510-
}
2511-
2512-
double itemMapPosX = elem.attribute( "mapPosX" ).toDouble();
2513-
double itemCanvasPosX = elem.attribute( "canvasPosX" ).toDouble();
2514-
int maxCanvasX = itemCanvasPosX / ( itemMapPosX - projectExtent.xMinimum() ) * projectExtent.width();
2515-
xPos = width - ( maxCanvasX - itemCanvasPosX ) * scaleFactor - itemWidth / 2.0 + 100;
2516-
2517-
double itemMapPosY = elem.attribute( "mapPosY" ).toDouble();
2518-
double itemCanvasPosY = elem.attribute( "canvasPosY" ).toDouble();
2519-
int maxCanvasY = itemCanvasPosY / ( projectExtent.yMaximum() - itemMapPosY ) * projectExtent.height();
2520-
yPos = height - ( maxCanvasY - itemCanvasPosY ) * scaleFactor - itemHeight + 100;
2592+
xPos = elem.attribute( "canvasPosX" ).toDouble() / scaleFactor;
2593+
yPos = elem.attribute( "canvasPosY" ).toDouble() / scaleFactor;
25212594
return true;
25222595
}
25232596

@@ -2535,8 +2608,5 @@ void QgsProjectParser::drawAnnotationRectangle( QPainter* p, const QDomElement&
25352608
framePen.setWidth( elem.attribute( "frameBorderWidth", "1" ).toInt() );
25362609
p->setPen( framePen );
25372610

2538-
p->save();
2539-
p->scale( scaleFactor, scaleFactor );
2540-
p->drawRect( QRectF( xPos / scaleFactor, yPos / scaleFactor, itemWidth, itemHeight ) );
2541-
p->restore();
2611+
p->drawRect( QRectF( xPos, yPos, itemWidth, itemHeight ) );
25422612
}

src/mapserver/qgsprojectparser.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <QList>
2424
#include <QPair>
2525

26+
class QSvgRenderer;
2627
class QTextDocument;
2728

2829
//Information about relationship between groups and layers
@@ -151,6 +152,8 @@ class QgsProjectParser: public QgsConfigParser
151152
QSet<QString> mRestrictedLayers;
152153
/**Watermark text items*/
153154
QList< QPair< QTextDocument*, QDomElement > > mTextAnnotationItems;
155+
/**Watermark items (content cached in QgsSVGCache)*/
156+
QList< QPair< QSvgRenderer*, QDomElement > > mSvgAnnotationElems;
154157

155158
/**Creates a maplayer object from <maplayer> element. The layer cash owns the maplayer, so don't delete it
156159
@return the maplayer or 0 in case of error*/
@@ -217,16 +220,19 @@ class QgsProjectParser: public QgsConfigParser
217220
QgsRectangle projectExtent() const;
218221

219222
void createTextAnnotationItems();
223+
void createSvgAnnotationItems();
224+
225+
void cleanupSvgAnnotationItems();
220226
void cleanupTextAnnotationItems();
227+
221228
/**Calculates annotation position to provide the same distance to the lower right corner as in the QGIS project file
222229
@param width output image pixel width
223230
@param height output image pixel height
224231
@param itemWidth item width in pixels in the QGIS project (screen pixels)
225232
@param itemHeight item height in pixels in the QGIS project (screen pixels)
226233
@param xPos out: x-coordinate of the item in the output image
227234
@param yPos out: y-coordinate of the item in the output image*/
228-
static bool annotationPosition( const QDomElement& elem, double scaleFactor, const QgsRectangle& projectExtent, int width, int height,
229-
int itemWidth, int itemHeight, double& xPos, double& yPos );
235+
static bool annotationPosition( const QDomElement& elem, double scaleFactor, double& xPos, double& yPos );
230236

231237
/**Draws background rectangle and frame for an annotation
232238
@param elem <Annotation> xml element

0 commit comments

Comments
 (0)