Skip to content
Permalink
Browse files

[FEATURE]: getMap in dxf format

  • Loading branch information
mhugent committed Jun 30, 2015
1 parent 7b31f8a commit a9c830e67b7fe0e7f66fc23b5a5a85b7b8ac5c61
@@ -45,6 +45,7 @@ SET ( qgis_mapserv_SRCS
qgswmsconfigparser.cpp
qgswmsprojectparser.cpp
qgsserverprojectparser.cpp
qgsserverstreamingdevice.cpp
qgssldconfigparser.cpp
qgsconfigparserutils.cpp
)
@@ -160,6 +161,7 @@ INCLUDE_DIRECTORIES(
${QT_INCLUDE_DIR}
${QGIS_INCLUDE_DIR}
../core
../core/dxf
../core/geometry
../core/raster
../core/symbology-ng
@@ -131,7 +131,6 @@ void QgsHttpRequestHandler::sendHeaders()
printf( it.value().toLocal8Bit() );
printf( "\n" );
}
printf( "\n" );
}
printf( "\n" );
mHeaders.clear();
@@ -0,0 +1,59 @@
/***************************************************************************
qgsserverstreamingdevice.cpp
-------------------------------------------------------------------
Date : 25 May 2015
Copyright : (C) 2015 by Marco Hugentobler
email : marco.hugentobler at sourcepole dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsserverstreamingdevice.h"
#include "qgsrequesthandler.h"

QgsServerStreamingDevice::QgsServerStreamingDevice( const QString& formatName, QgsRequestHandler* rh, QObject* parent ): QIODevice( parent ), mFormatName( formatName ), mRequestHandler( rh )
{
}

QgsServerStreamingDevice::QgsServerStreamingDevice(): QIODevice( 0 ), mRequestHandler( 0 )
{

}

QgsServerStreamingDevice::~QgsServerStreamingDevice()
{
}

bool QgsServerStreamingDevice::open( OpenMode mode )
{
if( !mRequestHandler || mode != QIODevice::WriteOnly )
{
return false;
}

mRequestHandler->setHeader( "Content-Type", mFormatName );
mRequestHandler->sendResponse();
return QIODevice::open( mode );
}

void QgsServerStreamingDevice::close()
{
QIODevice::close();
}

qint64 QgsServerStreamingDevice::writeData( const char * data, qint64 maxSize )
{
QByteArray ba( data, maxSize );
mRequestHandler->setGetFeatureResponse( &ba );
return maxSize;
}

qint64 QgsServerStreamingDevice::readData( char * data, qint64 maxSize )
{
return -1; //reading not supported
}
@@ -0,0 +1,44 @@
/***************************************************************************
qgsserverstreamingdevice.h
-------------------------------------------------------------------
Date : 25 May 2015
Copyright : (C) 2015 by Marco Hugentobler
email : marco.hugentobler at sourcepole dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSSERVERSTREAMINGDEVICE_H
#define QGSSERVERSTREAMINGDEVICE_H

#include <QIODevice>

class QgsRequestHandler;

class QgsServerStreamingDevice: public QIODevice
{
public:
QgsServerStreamingDevice( const QString& formatName, QgsRequestHandler* rh, QObject* parent = 0 );
~QgsServerStreamingDevice();

bool isSequential() const { return false; }

bool open( OpenMode mode );
void close();

protected:
QString mFormatName;
QgsRequestHandler* mRequestHandler;

QgsServerStreamingDevice(); //default constructor forbidden

qint64 writeData( const char * data, qint64 maxSize );
qint64 readData ( char * data, qint64 maxSize );
};

#endif // QGSSERVERSTREAMINGDEVICE_H
@@ -18,6 +18,7 @@
#include "qgswmsserver.h"
#include "qgscapabilitiescache.h"
#include "qgscrscache.h"
#include "qgsdxfexport.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgslayertree.h"
@@ -46,6 +47,7 @@
#include "qgsogcutils.h"
#include "qgsfeature.h"
#include "qgseditorwidgetregistry.h"
#include "qgsserverstreamingdevice.h"

#include <QImage>
#include <QPainter>
@@ -158,6 +160,25 @@ void QgsWMSServer::executeRequest()
//GetMap
else if ( request.compare( "GetMap", Qt::CaseInsensitive ) == 0 )
{
//export as dxf
QString format = mParameters.value( "FORMAT" );
if ( format.compare( "application/dxf", Qt::CaseInsensitive ) == 0 )
{
try
{
getMapAsDxf();
cleanupAfterRequest();
return;
}
catch ( QgsMapServiceException& ex )
{
QgsDebugMsg( "Caught exception during GetMap request" );
mRequestHandler->setServiceException( ex );
cleanupAfterRequest();
return;
}
}

QImage* result = 0;
try
{
@@ -446,7 +467,7 @@ QDomDocument QgsWMSServer::getCapabilities( QString version, bool fullProjectInf

//wms:GetMap
elem = doc.createElement( "GetMap"/*wms:GetMap*/ );
appendFormats( doc, elem, QStringList() << "image/jpeg" << "image/png" << "image/png; mode=16bit" << "image/png; mode=8bit" << "image/png; mode=1bit" );
appendFormats( doc, elem, QStringList() << "image/jpeg" << "image/png" << "image/png; mode=16bit" << "image/png; mode=8bit" << "image/png; mode=1bit" << "application/dxf" );
elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
requestElement.appendChild( elem );

@@ -1311,6 +1332,76 @@ QImage* QgsWMSServer::getMap( HitTest* hitTest )
return theImage;
}

void QgsWMSServer::getMapAsDxf()
{
QgsServerStreamingDevice d( "application/dxf" , mRequestHandler );
if ( !d.open( QIODevice::WriteOnly ) )
{
throw QgsMapServiceException( "Internal server error", "Error opening output device for writing" );
}

QgsDxfExport dxf;

//BBOX
bool bboxOk;
QgsRectangle extent = _parseBBOX( mParameters.value( "BBOX", "0,0,0,0" ), bboxOk );
if ( !bboxOk )
{
extent = QgsRectangle();
}
dxf.setExtent( extent );

//get format options (for MODE,SCALE, LAYERATTRIBUTES )
QMap<QString, QString > formatOptionsMap;
readFormatOptions( formatOptionsMap );

QList< QPair<QgsVectorLayer *, int > > layers;
readDxfLayerSettings( layers, formatOptionsMap );
dxf.addLayers( layers );

//MODE
QMap<QString, QString>::const_iterator modeIt = formatOptionsMap.find( "MODE" );

QgsDxfExport::SymbologyExport se;
if ( modeIt == formatOptionsMap.constEnd() )
{
se = QgsDxfExport::NoSymbology;
}
else
{
if ( modeIt->compare( "SymbolLayerSymbology", Qt::CaseInsensitive ) == 0 )
{
se = QgsDxfExport::SymbolLayerSymbology;
}
else if ( modeIt->compare( "FeatureSymbology", Qt::CaseInsensitive ) == 0 )
{
se = QgsDxfExport::FeatureSymbology;
}
else
{
se = QgsDxfExport::NoSymbology;
}
}
dxf.setSymbologyExport( se );

//SCALE
QMap<QString, QString>::const_iterator scaleIt = formatOptionsMap.find( "SCALE" );
if ( scaleIt != formatOptionsMap.constEnd() )
{
dxf.setSymbologyScaleDenominator( scaleIt->toDouble() );
}

QString codec = "ISO-8859-1";
QMap<QString, QString>::const_iterator codecIt = formatOptionsMap.find( "CODEC" );
if ( codecIt != formatOptionsMap.constEnd() )
{
codec = formatOptionsMap.value( "CODEC" );
}

dxf.writeToFile( &d, codec );
d.close();
}

int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
{
if ( !mMapRenderer || !mConfigParser )
@@ -3114,3 +3205,82 @@ QgsRectangle QgsWMSServer::featureInfoSearchRect( QgsVectorLayer* ml, QgsMapRend
infoPoint.x() + mapUnitTolerance, infoPoint.y() + mapUnitTolerance );
return( mr->mapToLayerCoordinates( ml, mapRectangle ) );
}

void QgsWMSServer::readFormatOptions( QMap<QString, QString>& formatOptions ) const
{
formatOptions.clear();
QString fo = mParameters.value( "FORMAT_OPTIONS" );
QStringList formatOptionsList = fo.split( ";" );
QStringList::const_iterator optionsIt = formatOptionsList.constBegin();
for ( ; optionsIt != formatOptionsList.constEnd(); ++optionsIt )
{
int equalIdx = optionsIt->indexOf( ":" );
if ( equalIdx > 0 && equalIdx < ( optionsIt->length() - 1 ) )
{
formatOptions.insert( optionsIt->left( equalIdx ).toUpper(), optionsIt->right( optionsIt->length() - equalIdx - 1 ).toUpper() );
}
}
}

void QgsWMSServer::readDxfLayerSettings( QList< QPair<QgsVectorLayer *, int > >& layers, const QMap<QString, QString>& formatOptionsMap ) const
{
layers.clear();

QSet<QString> wfsLayers = QSet<QString>::fromList( mConfigParser->wfsLayerNames() );

QStringList layerAttributes;
QMap<QString, QString>::const_iterator layerAttributesIt = formatOptionsMap.find( "LAYERATTRIBUTES" );
if ( layerAttributesIt != formatOptionsMap.constEnd() )
{
layerAttributes = formatOptionsMap.value( "LAYERATTRIBUTES" ).split( "," );
}

//LAYERS and STYLES
QStringList layerList, styleList;
if ( readLayersAndStyles( layerList, styleList ) != 0 )
{
return;
}

for ( int i = 0; i < layerList.size(); ++i )
{
QString layerName = layerList.at( i );
QString styleName;
if ( styleList.size() > i )
{
styleName = styleList.at( i );
}

QList<QgsMapLayer*> layerList = mConfigParser->mapLayerFromStyle( layerName, styleName );
QList<QgsMapLayer*>::const_iterator layerIt = layerList.constBegin();
for ( ; layerIt != layerList.constEnd(); ++layerIt )
{
if ( !( *layerIt ) )
{
continue;
}

//vector layer?
if (( *layerIt )->type() != QgsMapLayer::VectorLayer )
{
continue;
}

QgsVectorLayer* vlayer = static_cast<QgsVectorLayer*>( *layerIt );

int layerAttribute = -1;
if ( layerAttributes.size() > i )
{
layerAttribute = vlayer->pendingFields().indexFromName( layerAttributes.at( i ) );
}

//only wfs layers are allowed to be published
if ( !wfsLayers.contains( vlayer->name() ) )
{
continue;
}

layers.append( qMakePair( vlayer, layerAttribute ) );
}
}
}
@@ -84,6 +84,8 @@ class QgsWMSServer: public QgsOWSServer
of the image object). If an instance to existing hit test structure is passed, instead of rendering
it will fill the structure with symbols that would be used for rendering */
QImage* getMap( HitTest* hitTest = 0 );
/**GetMap request with vector format output. This output is usually symbolized (difference to WFS GetFeature)*/
void getMapAsDxf();
/**Returns an SLD file with the style of the requested layer. Exception is raised in case of troubles :-)*/
QDomDocument getStyle();
/**Returns an SLD file with the styles of the requested layers. Exception is raised in case of troubles :-)*/
@@ -254,6 +256,10 @@ class QgsWMSServer: public QgsOWSServer

/**Gets layer search rectangle (depending on request parameter, layer type, map and layer crs)*/
QgsRectangle featureInfoSearchRect( QgsVectorLayer* ml, QgsMapRenderer* mr, const QgsRenderContext& rct, const QgsPoint& infoPoint ) const;

/**Reads and extracts the different options in the FORMAT_OPTIONS parameter*/
void readFormatOptions( QMap<QString, QString>& formatOptions ) const;
void readDxfLayerSettings( QList< QPair<QgsVectorLayer *, int > >& layers, const QMap<QString, QString>& formatOptionsMap ) const;
};

#endif

0 comments on commit a9c830e

Please sign in to comment.
You can’t perform that action at this time.