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
Expand Up @@ -409,17 +409,22 @@ int main( int argc, char * argv[] )
}

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
{
QgsDebugMsg( "Capabilities document not found in cache" );
QDomDocument doc;
try
{
doc = theServer->getCapabilities( version );
doc = theServer->getCapabilities( version, getProjectSettings );
}
catch ( QgsMapServiceException& ex )
{
Expand All @@ -428,7 +433,7 @@ int main( int argc, char * argv[] )
delete theServer;
continue;
}
capabilitiesCache.insertCapabilitiesDocument( configFilePath, version, &doc );
capabilitiesCache.insertCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version, &doc );
capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
}
else
Expand Down
8 changes: 6 additions & 2 deletions src/mapserver/qgsconfigparser.h
Expand Up @@ -39,8 +39,9 @@ class 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.*/
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;
/**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.
@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;

Expand All @@ -60,6 +61,9 @@ class QgsConfigParser
/**Returns the xml fragment of a style*/
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*/
virtual void setParameterMap( const QMap<QString, QString>& parameterMap )
{ Q_UNUSED( parameterMap ); }
Expand Down
245 changes: 219 additions & 26 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -88,30 +88,22 @@ int QgsProjectParser::numberOfLayers() const
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();
QMap<QString, QgsMapLayer *> layerMap;
if ( mProjectLayerElements.size() < 1 )
{
return;
}

foreach ( const QDomElement &elem, mProjectLayerElements )
if ( fullProjectSettings )
{
QgsMapLayer *layer = createLayerFromElement( elem );
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
addDrawingOrder( parentElement, doc );
}

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

//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
QString projTitle = projectTitle();
Expand All @@ -128,7 +120,7 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement,

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

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

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

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


if ( currentChildElem.tagName() == "legendgroup" )
{
Expand Down Expand Up @@ -408,12 +406,12 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
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
{
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers );
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
}

// 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( styleTitleElem );
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
{
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
{
QgsRectangle combinedBBox;
Expand Down Expand Up @@ -1338,9 +1447,6 @@ void QgsProjectParser::printCapabilities( QDomElement& parentElement, QDomDocume
}

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 )
{
Expand Down Expand Up @@ -1576,6 +1682,32 @@ QString QgsProjectParser::serviceUrl() const
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
{
if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) )
Expand Down Expand Up @@ -1778,3 +1910,64 @@ QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement&
BBox = t.transformBoundingBox( 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 );
}
}
}

0 comments on commit d3860bf

Please sign in to comment.