Skip to content

Commit

Permalink
QGIS server: merge get_project_settings branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Hugentobler committed Oct 9, 2012
2 parents f4dd8a0 + eae008e commit d3860bf
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 43 deletions.
13 changes: 9 additions & 4 deletions src/mapserver/qgis_map_serv.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -409,17 +409,22 @@ int main( int argc, char * argv[] )
} }


QString version = parameterMap.value( "VERSION", "1.3.0" ); QString version = parameterMap.value( "VERSION", "1.3.0" );
bool getProjectSettings = ( request == "GetProjectSettings" );
if ( getProjectSettings )
{
version = "1.3.0"; //getProjectSettings extends WMS 1.3.0 capabilities
}


if ( request == "GetCapabilities" ) if ( request == "GetCapabilities" || getProjectSettings )
{ {
const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version ); const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
{ {
QgsDebugMsg( "Capabilities document not found in cache" ); QgsDebugMsg( "Capabilities document not found in cache" );
QDomDocument doc; QDomDocument doc;
try try
{ {
doc = theServer->getCapabilities( version ); doc = theServer->getCapabilities( version, getProjectSettings );
} }
catch ( QgsMapServiceException& ex ) catch ( QgsMapServiceException& ex )
{ {
Expand All @@ -428,7 +433,7 @@ int main( int argc, char * argv[] )
delete theServer; delete theServer;
continue; continue;
} }
capabilitiesCache.insertCapabilitiesDocument( configFilePath, version, &doc ); capabilitiesCache.insertCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version, &doc );
capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version ); capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
} }
else else
Expand Down
8 changes: 6 additions & 2 deletions src/mapserver/qgsconfigparser.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ class QgsConfigParser


virtual ~QgsConfigParser(); virtual ~QgsConfigParser();


/**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ /**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0; @param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings = false ) const = 0;


virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0; virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0;


Expand All @@ -60,6 +61,9 @@ class QgsConfigParser
/**Returns the xml fragment of a style*/ /**Returns the xml fragment of a style*/
virtual QDomDocument getStyle( const QString& styleName, const QString& layerName ) const = 0; virtual QDomDocument getStyle( const QString& styleName, const QString& layerName ) const = 0;


/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
virtual QStringList wfsLayerNames() const { return QStringList(); }

/**Possibility to add a parameter map to the config parser. This is used by the SLD parser. Default implementation does nothing*/ /**Possibility to add a parameter map to the config parser. This is used by the SLD parser. Default implementation does nothing*/
virtual void setParameterMap( const QMap<QString, QString>& parameterMap ) virtual void setParameterMap( const QMap<QString, QString>& parameterMap )
{ Q_UNUSED( parameterMap ); } { Q_UNUSED( parameterMap ); }
Expand Down
245 changes: 219 additions & 26 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -88,30 +88,22 @@ int QgsProjectParser::numberOfLayers() const
return mProjectLayerElements.size(); return mProjectLayerElements.size();
} }


void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings ) const
{ {
QStringList nonIdentifiableLayers = identifyDisabledLayers(); QStringList nonIdentifiableLayers = identifyDisabledLayers();
QMap<QString, QgsMapLayer *> layerMap; if ( mProjectLayerElements.size() < 1 )
{
return;
}


foreach ( const QDomElement &elem, mProjectLayerElements ) if ( fullProjectSettings )
{ {
QgsMapLayer *layer = createLayerFromElement( elem ); addDrawingOrder( parentElement, doc );
if ( layer )
{
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
layerMap.insert( layer->id(), layer );
}
#if QGSMSDEBUG
else
{
QString buf;
QTextStream s( &buf );
elem.save( s, 0 );
QgsDebugMsg( QString( "layer %1 not found" ).arg( buf ) );
}
#endif
} }


QMap<QString, QgsMapLayer *> layerMap;
projectLayerMap( layerMap );

//According to the WMS spec, there can be only one toplevel layer. //According to the WMS spec, there can be only one toplevel layer.
//So we create an artificial one here to be in accordance with the schema //So we create an artificial one here to be in accordance with the schema
QString projTitle = projectTitle(); QString projTitle = projectTitle();
Expand All @@ -128,7 +120,7 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement,


QDomElement legendElem = mXMLDoc->documentElement().firstChildElement( "legend" ); QDomElement legendElem = mXMLDoc->documentElement().firstChildElement( "legend" );


addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers ); addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );


parentElement.appendChild( layerParentElem ); parentElement.appendChild( layerParentElem );
combineExtentAndCrsOfGroupChildren( layerParentElem, doc ); combineExtentAndCrsOfGroupChildren( layerParentElem, doc );
Expand Down Expand Up @@ -356,14 +348,20 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
QDomElement &parentElem, QDomElement &parentElem,
const QDomElement &legendElem, const QDomElement &legendElem,
const QMap<QString, QgsMapLayer *> &layerMap, const QMap<QString, QgsMapLayer *> &layerMap,
const QStringList &nonIdentifiableLayers ) const const QStringList &nonIdentifiableLayers,
QString version,
bool fullProjectSettings ) const
{ {
QDomNodeList legendChildren = legendElem.childNodes(); QDomNodeList legendChildren = legendElem.childNodes();
for ( int i = 0; i < legendChildren.size(); ++i ) for ( int i = 0; i < legendChildren.size(); ++i )
{ {
QDomElement currentChildElem = legendChildren.at( i ).toElement(); QDomElement currentChildElem = legendChildren.at( i ).toElement();

QDomElement layerElem = doc.createElement( "Layer" ); QDomElement layerElem = doc.createElement( "Layer" );
if ( fullProjectSettings )
{
layerElem.setAttribute( "visible", !( currentChildElem.attribute( "checked" ) == "Qt::Unchecked" ) );
}



if ( currentChildElem.tagName() == "legendgroup" ) if ( currentChildElem.tagName() == "legendgroup" )
{ {
Expand Down Expand Up @@ -408,12 +406,12 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
pLayerMap.insert( layerId( elem ), p->createLayerFromElement( elem ) ); pLayerMap.insert( layerId( elem ), p->createLayerFromElement( elem ) );
} }


p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled ); p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled, version, fullProjectSettings );
} }
} }
else //normal (not embedded) legend group else //normal (not embedded) legend group
{ {
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers ); addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
} }


// combine bounding boxes of children (groups/layers) // combine bounding boxes of children (groups/layers)
Expand Down Expand Up @@ -489,6 +487,37 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
styleElem.appendChild( styleNameElem ); styleElem.appendChild( styleNameElem );
styleElem.appendChild( styleTitleElem ); styleElem.appendChild( styleTitleElem );
layerElem.appendChild( styleElem ); layerElem.appendChild( styleElem );

//min/max scale denominatormScaleBasedVisibility
if ( currentLayer->hasScaleBasedVisibility() )
{
QString minScaleString = QString::number( currentLayer->minimumScale() );
QString maxScaleString = QString::number( currentLayer->maximumScale() );

if ( version == "1.3.0" )
{
QDomElement minScaleElem = doc.createElement( "MinScaleDenominator" );
QDomText minScaleText = doc.createTextNode( minScaleString );
minScaleElem.appendChild( minScaleText );
layerElem.appendChild( minScaleElem );
QDomElement maxScaleElem = doc.createElement( "MaxScaleDenominator" );
QDomText maxScaleText = doc.createTextNode( maxScaleString );
maxScaleElem.appendChild( maxScaleText );
layerElem.appendChild( maxScaleElem );
}
else if ( version == "1.1.1" )
{
QDomElement scaleHintElem = doc.createElement( "ScaleHint" );
scaleHintElem.setAttribute( "min", minScaleString );
scaleHintElem.setAttribute( "max", maxScaleString );
layerElem.appendChild( scaleHintElem );
}
}

if ( fullProjectSettings )
{
addLayerProjectSettings( layerElem, doc, currentLayer );
}
} }
else else
{ {
Expand All @@ -500,6 +529,86 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
} }
} }


void QgsProjectParser::addLayerProjectSettings( QDomElement& layerElem, QDomDocument& doc, QgsMapLayer* currentLayer )
{
if ( !currentLayer )
{
return;
}

if ( currentLayer->type() == QgsMapLayer::VectorLayer )
{
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( currentLayer );

//displayfield
layerElem.setAttribute( "displayField", vLayer->displayField() );

//attributes
QDomElement attributesElem = doc.createElement( "Attributes" );
const QgsFieldMap& layerFields = vLayer->pendingFields();
QgsFieldMap::const_iterator fieldIt = layerFields.constBegin();
for ( ; fieldIt != layerFields.constEnd(); ++fieldIt )
{
QDomElement attributeElem = doc.createElement( "Attribute" );
attributeElem.setAttribute( "name", fieldIt->name() );
attributeElem.setAttribute( "type", QVariant::typeToName( fieldIt->type() ) );

//edit type to text
QgsVectorLayer::EditType typeEnum = vLayer->editType( fieldIt.key() );
attributeElem.setAttribute( "editType", editTypeString( typeEnum ) );
attributeElem.setAttribute( "comment", fieldIt->comment() );
attributeElem.setAttribute( "length", fieldIt->length() );
attributeElem.setAttribute( "precision", fieldIt->precision() );
attributesElem.appendChild( attributeElem );
}
layerElem.appendChild( attributesElem );
}
}

//not very nice, needs to be kept in sync with QgsVectorLayer class...
QString QgsProjectParser::editTypeString( QgsVectorLayer::EditType type )
{
switch ( type )
{
case QgsVectorLayer::LineEdit:
return "LineEdit";
case QgsVectorLayer::UniqueValues:
return "UniqueValues";
case QgsVectorLayer::UniqueValuesEditable:
return "UniqueValuesEditable";
case QgsVectorLayer::ValueMap:
return "ValueMap";
case QgsVectorLayer::Classification:
return "Classification";
case QgsVectorLayer::EditRange:
return "EditRange";
case QgsVectorLayer::SliderRange:
return "SliderRange";
case QgsVectorLayer::CheckBox:
return "CheckBox";
case QgsVectorLayer::FileName:
return "FileName";
case QgsVectorLayer::Enumeration:
return "Enumeration";
case QgsVectorLayer::Immutable:
return "Immutable";
case QgsVectorLayer::Hidden:
return "Hidden";
case QgsVectorLayer::TextEdit:
return "TextEdit";
case QgsVectorLayer::Calendar:
return "Calendar";
case QgsVectorLayer::DialRange:
return "DialRange";
case QgsVectorLayer::ValueRelation:
return "ValueRelation";
case QgsVectorLayer::UuidGenerator:
return "UuidGenerator";
default:
return "Unknown";
}
}

void QgsProjectParser::combineExtentAndCrsOfGroupChildren( QDomElement& groupElem, QDomDocument& doc ) const void QgsProjectParser::combineExtentAndCrsOfGroupChildren( QDomElement& groupElem, QDomDocument& doc ) const
{ {
QgsRectangle combinedBBox; QgsRectangle combinedBBox;
Expand Down Expand Up @@ -1338,9 +1447,6 @@ void QgsProjectParser::printCapabilities( QDomElement& parentElement, QDomDocume
} }


QDomElement composerTemplatesElem = doc.createElement( "ComposerTemplates" ); QDomElement composerTemplatesElem = doc.createElement( "ComposerTemplates" );
composerTemplatesElem.setAttribute( "xmlns:wms", "http://www.opengis.net/wms" );
composerTemplatesElem.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
composerTemplatesElem.setAttribute( "xsi:type", "wms:_ExtendedCapabilities" );


for ( int i = 0; i < composerNodeList.size(); ++i ) for ( int i = 0; i < composerNodeList.size(); ++i )
{ {
Expand Down Expand Up @@ -1576,6 +1682,32 @@ QString QgsProjectParser::serviceUrl() const
return url; return url;
} }


QStringList QgsProjectParser::wfsLayerNames() const
{
QStringList layerNameList;

QMap<QString, QgsMapLayer*> layerMap;
projectLayerMap( layerMap );

QgsMapLayer* currentLayer = 0;
QStringList wfsIdList = wfsLayers();
QStringList::const_iterator wfsIdIt = wfsIdList.constBegin();
for ( ; wfsIdIt != wfsIdList.constEnd(); ++wfsIdIt )
{
QMap<QString, QgsMapLayer*>::const_iterator layerMapIt = layerMap.find( *wfsIdIt );
if ( layerMapIt != layerMap.constEnd() )
{
currentLayer = layerMapIt.value();
if ( currentLayer )
{
layerNameList.append( currentLayer->name() );
}
}
}

return layerNameList;
}

QString QgsProjectParser::convertToAbsolutePath( const QString& file ) const QString QgsProjectParser::convertToAbsolutePath( const QString& file ) const
{ {
if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) ) if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) )
Expand Down Expand Up @@ -1778,3 +1910,64 @@ QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement&
BBox = t.transformBoundingBox( BBox ); BBox = t.transformBoundingBox( BBox );
return BBox; return BBox;
} }

void QgsProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const
{
if ( !mXMLDoc )
{
return;
}

//find legend section
QDomElement legendElement = mXMLDoc->documentElement().firstChildElement( "legend" );
if ( legendElement.isNull() )
{
return;
}

QStringList layerList;

bool useDrawingOrder = ( legendElement.attribute( "updateDrawingOrder" ) == "false" );
QDomNodeList layerNodeList = legendElement.elementsByTagName( "legendlayer" );
if ( !useDrawingOrder ) //bottom to top
{
for ( int i = 0; i < layerNodeList.size(); ++i )
{
layerList.prepend( layerNodeList.at( i ).toElement().attribute( "name" ) );
}
}
else
{
QMap<int, QString> orderedLayerNames;
for ( int i = 0; i < layerNodeList.size(); ++i )
{
QString layerName = layerNodeList.at( i ).toElement().attribute( "name" );
int order = layerNodeList.at( i ).toElement().attribute( "drawingOrder" ).toInt();
orderedLayerNames.insert( order, layerName );
}

QMap<int, QString>::const_iterator orderIt = orderedLayerNames.constBegin();
for ( ; orderIt != orderedLayerNames.constEnd(); ++orderIt )
{
layerList.prepend( *orderIt );
}
}
QDomElement layerDrawingOrderElem = doc.createElement( "LayerDrawingOrder" );
QDomText drawingOrderText = doc.createTextNode( layerList.join( "," ) );
layerDrawingOrderElem.appendChild( drawingOrderText );
parentElem.appendChild( layerDrawingOrderElem );
}

void QgsProjectParser::projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap ) const
{
layerMap.clear();
foreach ( const QDomElement &elem, mProjectLayerElements )
{
QgsMapLayer *layer = createLayerFromElement( elem );
if ( layer )
{
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
layerMap.insert( layer->id(), layer );
}
}
}
Loading

0 comments on commit d3860bf

Please sign in to comment.