Skip to content

Commit

Permalink
Merge pull request #1403 from mdouchin/getmap_image_quality
Browse files Browse the repository at this point in the history
QGIS Server - new project option imageQuality used for JPEG images
  • Loading branch information
mhugent committed Jun 5, 2014
2 parents 2a80881 + bcde66f commit 3637657
Show file tree
Hide file tree
Showing 14 changed files with 332 additions and 135 deletions.
18 changes: 18 additions & 0 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -351,6 +351,13 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
mMaxHeightLineEdit->setText( QString::number( maxHeight ) );
}

// WMS imageQuality
int imageQuality = QgsProject::instance()->readNumEntry( "WMSImageQuality", "/", -1 );
if ( imageQuality != -1 )
{
mWMSImageQualitySpinBox->setValue( imageQuality );
}

mWFSUrlLineEdit->setText( QgsProject::instance()->readEntry( "WFSUrl", "/", "" ) );
QStringList wfsLayerIdList = QgsProject::instance()->readListEntry( "WFSLayers", "/" );
QStringList wfstUpdateLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Update" );
Expand Down Expand Up @@ -812,6 +819,17 @@ void QgsProjectProperties::apply()
QgsProject::instance()->writeEntry( "WMSMaxHeight", "/", maxHeightText.toInt() );
}

// WMS Image quality
int imageQualityValue = mWMSImageQualitySpinBox->value();
if ( imageQualityValue == 0 )
{
QgsProject::instance()->removeEntry( "WMSImageQuality", "/" );
}
else
{
QgsProject::instance()->writeEntry( "WMSImageQuality", "/", imageQualityValue );
}

QgsProject::instance()->writeEntry( "WFSUrl", "/", mWFSUrlLineEdit->text() );
QStringList wfsLayerList;
QStringList wfstUpdateLayerList;
Expand Down
18 changes: 13 additions & 5 deletions src/mapserver/qgshttprequesthandler.cpp
Expand Up @@ -90,7 +90,7 @@ QString QgsHttpRequestHandler::formatToMimeType( const QString& format ) const
return format;
}

void QgsHttpRequestHandler::sendGetMapResponse( const QString& service, QImage* img ) const
void QgsHttpRequestHandler::sendGetMapResponse( const QString& service, QImage* img, int imageQuality = -1 ) const
{
Q_UNUSED( service );
QgsDebugMsg( "Sending getmap response..." );
Expand All @@ -112,28 +112,35 @@ void QgsHttpRequestHandler::sendGetMapResponse( const QString& service, QImage*
QBuffer buffer( &ba );
buffer.open( QIODevice::WriteOnly );

// Do not use imageQuality for PNG images
// For now, QImage expects quality to be a range 0-9 for PNG
if ( mFormat == "PNG" )
{
imageQuality = -1;
}

if ( png8Bit )
{
QVector<QRgb> colorTable;
medianCut( colorTable, 256, *img );
QImage palettedImg = img->convertToFormat( QImage::Format_Indexed8, colorTable, Qt::ColorOnly | Qt::ThresholdDither |
Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
palettedImg.save( &buffer, "PNG", -1 );
palettedImg.save( &buffer, "PNG", imageQuality );
}
else if ( png16Bit )
{
QImage palettedImg = img->convertToFormat( QImage::Format_ARGB4444_Premultiplied );
palettedImg.save( &buffer, "PNG", -1 );
palettedImg.save( &buffer, "PNG", imageQuality );
}
else if ( png1Bit )
{
QImage palettedImg = img->convertToFormat( QImage::Format_Mono, Qt::MonoOnly | Qt::ThresholdDither |
Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
palettedImg.save( &buffer, "PNG", -1 );
palettedImg.save( &buffer, "PNG", imageQuality );
}
else
{
img->save( &buffer, mFormat.toLocal8Bit().data(), -1 );
img->save( &buffer, mFormat.toLocal8Bit().data(), imageQuality );
}

if ( isBase64 )
Expand Down Expand Up @@ -458,6 +465,7 @@ void QgsHttpRequestHandler::requestStringToParameterMap( const QString& request,
mFormat = formatString;
}
}

}

QString QgsHttpRequestHandler::readPostBody() const
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgshttprequesthandler.h
Expand Up @@ -33,7 +33,7 @@ class QgsHttpRequestHandler: public QgsRequestHandler
QgsHttpRequestHandler();
~QgsHttpRequestHandler();

virtual void sendGetMapResponse( const QString& service, QImage* img ) const;
virtual void sendGetMapResponse( const QString& service, QImage* img, int imageQuality ) const;
virtual void sendGetCapabilitiesResponse( const QDomDocument& doc ) const;
virtual void sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const;
virtual void sendServiceException( const QgsMapServiceException& ex ) const;
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgsrequesthandler.h
Expand Up @@ -35,7 +35,7 @@ class QgsRequestHandler
/**Parses the input and creates a request neutral Parameter/Value map*/
virtual QMap<QString, QString> parseInput() = 0;
/**Sends the map image back to the client*/
virtual void sendGetMapResponse( const QString& service, QImage* img ) const = 0;
virtual void sendGetMapResponse( const QString& service, QImage* img, int imageQuality ) const = 0;
virtual void sendGetCapabilitiesResponse( const QDomDocument& doc ) const = 0;
virtual void sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const = 0;
virtual void sendServiceException( const QgsMapServiceException& ex ) const = 0;
Expand Down
9 changes: 9 additions & 0 deletions src/mapserver/qgssldconfigparser.cpp
Expand Up @@ -663,6 +663,15 @@ double QgsSLDConfigParser::maxHeight() const
return -1;
}

double QgsSLDConfigParser::imageQuality() const
{
if ( mFallbackParser )
{
return mFallbackParser->imageQuality();
}
return -1;
}

QgsComposition* QgsSLDConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
if ( mFallbackParser )
Expand Down
1 change: 1 addition & 0 deletions src/mapserver/qgssldconfigparser.h
Expand Up @@ -98,6 +98,7 @@ class QgsSLDConfigParser: public QgsWMSConfigParser

double maxWidth() const;
double maxHeight() const;
double imageQuality() const;

//printing

Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgssoaprequesthandler.cpp
Expand Up @@ -164,7 +164,7 @@ QMap<QString, QString> QgsSOAPRequestHandler::parseInput()
return result;
}

void QgsSOAPRequestHandler::sendGetMapResponse( const QString& service, QImage* img ) const
void QgsSOAPRequestHandler::sendGetMapResponse( const QString& service, QImage* img) const
{
QgsMapServiceException ex( "Send error", "Error, could not send Image" );
if ( service == "WMS" )
Expand Down
1 change: 1 addition & 0 deletions src/mapserver/qgswcsserver.h
Expand Up @@ -62,6 +62,7 @@ class QgsWCSServer: public QgsOWSServer
QString serviceUrl() const;

QgsWCSProjectParser* mConfigParser;

};

#endif
1 change: 1 addition & 0 deletions src/mapserver/qgswmsconfigparser.h
Expand Up @@ -96,6 +96,7 @@ class QgsWMSConfigParser

virtual double maxWidth() const = 0;
virtual double maxHeight() const = 0;
virtual double imageQuality() const = 0;

//printing

Expand Down
15 changes: 15 additions & 0 deletions src/mapserver/qgswmsprojectparser.cpp
Expand Up @@ -337,6 +337,21 @@ double QgsWMSProjectParser::maxHeight() const
return maxHeight;
}

double QgsWMSProjectParser::imageQuality() const
{
double imageQuality = -1;
QDomElement propertiesElem = mProjectParser.propertiesElem();
if ( !propertiesElem.isNull() )
{
QDomElement imageQualityElem = propertiesElem.firstChildElement( "WMSImageQuality" );
if ( !imageQualityElem.isNull() )
{
imageQuality = imageQualityElem.text().toInt();
}
}
return imageQuality;
}

QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlList ) const
{
//Create composition from xml
Expand Down
1 change: 1 addition & 0 deletions src/mapserver/qgswmsprojectparser.h
Expand Up @@ -55,6 +55,7 @@ class QgsWMSProjectParser: public QgsWMSConfigParser

double maxWidth() const;
double maxHeight() const;
double imageQuality() const;

//printing
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const;
Expand Down
33 changes: 27 additions & 6 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -155,7 +155,7 @@ void QgsWMSServer::executeRequest()
if ( result )
{
QgsDebugMsg( "Sending GetMap response" );
mRequestHandler->sendGetMapResponse( "WMS", result );
mRequestHandler->sendGetMapResponse( "WMS", result, getImageQuality() );
QgsDebugMsg( "Response sent" );
}
else
Expand Down Expand Up @@ -254,7 +254,7 @@ void QgsWMSServer::executeRequest()
{
QgsDebugMsg( "Sending GetLegendGraphic response" );
//sending is the same for GetMap and GetLegendGraphic
mRequestHandler->sendGetMapResponse( "WMS", result );
mRequestHandler->sendGetMapResponse( "WMS", result, getImageQuality() );
QgsDebugMsg( "Response sent" );
}
else
Expand Down Expand Up @@ -1010,12 +1010,13 @@ QImage* QgsWMSServer::getMap()
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );

QgsDebugMsg( "clearing filters" );
// QgsDebugMsg( "clearing filters" );
QgsMapLayerRegistry::instance()->removeAllMapLayers();

#ifdef QGISDEBUG
theImage->save( QDir::tempPath() + QDir::separator() + "lastrender.png" );
#endif
//#ifdef QGISDEBUG
// theImage->save( QDir::tempPath() + QDir::separator() + "lastrender.png" );
//#endif

return theImage;
}

Expand Down Expand Up @@ -2980,3 +2981,23 @@ QString QgsWMSServer::relationValue( const QString& attributeVal, QgsVectorLayer
}
return attributeVal;
}

int QgsWMSServer::getImageQuality( ) const
{

// First taken from QGIS project
int imageQuality = mConfigParser->imageQuality();

// Then checks if a parameter is given, if so use it instead
if ( mParameters.contains( "IMAGE_QUALITY" ) )
{
bool conversionSuccess;
int imageQualityParameter;
imageQualityParameter = mParameters[ "IMAGE_QUALITY" ].toInt( &conversionSuccess );
if ( conversionSuccess )
{
imageQuality = imageQualityParameter;
}
}
return imageQuality;
}
3 changes: 3 additions & 0 deletions src/mapserver/qgswmsserver.h
Expand Up @@ -255,6 +255,9 @@ class QgsWMSServer: public QgsOWSServer
/**Replaces attribute value with ValueRelation or ValueRelation if defined. Otherwise returns the original value*/
static QString replaceValueMapAndRelation( QgsVectorLayer* vl, int idx, const QString& attributeVal );
static QString relationValue( const QString& attributeVal, QgsVectorLayer* layer, const QString& key, const QString& value );

/** Return the image quality to use for getMap request */
int getImageQuality() const;
};

#endif

0 comments on commit 3637657

Please sign in to comment.