Skip to content

Commit d3860bf

Browse files
author
Marco Hugentobler
committedOct 9, 2012
QGIS server: merge get_project_settings branch
2 parents f4dd8a0 + eae008e commit d3860bf

File tree

8 files changed

+277
-43
lines changed

8 files changed

+277
-43
lines changed
 

‎src/mapserver/qgis_map_serv.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,17 +409,22 @@ int main( int argc, char * argv[] )
409409
}
410410

411411
QString version = parameterMap.value( "VERSION", "1.3.0" );
412+
bool getProjectSettings = ( request == "GetProjectSettings" );
413+
if ( getProjectSettings )
414+
{
415+
version = "1.3.0"; //getProjectSettings extends WMS 1.3.0 capabilities
416+
}
412417

413-
if ( request == "GetCapabilities" )
418+
if ( request == "GetCapabilities" || getProjectSettings )
414419
{
415-
const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
420+
const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
416421
if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
417422
{
418423
QgsDebugMsg( "Capabilities document not found in cache" );
419424
QDomDocument doc;
420425
try
421426
{
422-
doc = theServer->getCapabilities( version );
427+
doc = theServer->getCapabilities( version, getProjectSettings );
423428
}
424429
catch ( QgsMapServiceException& ex )
425430
{
@@ -428,7 +433,7 @@ int main( int argc, char * argv[] )
428433
delete theServer;
429434
continue;
430435
}
431-
capabilitiesCache.insertCapabilitiesDocument( configFilePath, version, &doc );
436+
capabilitiesCache.insertCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version, &doc );
432437
capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
433438
}
434439
else

‎src/mapserver/qgsconfigparser.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ class QgsConfigParser
3939

4040
virtual ~QgsConfigParser();
4141

42-
/**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.*/
43-
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;
42+
/**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.
43+
@param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
44+
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings = false ) const = 0;
4445

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

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

64+
/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
65+
virtual QStringList wfsLayerNames() const { return QStringList(); }
66+
6367
/**Possibility to add a parameter map to the config parser. This is used by the SLD parser. Default implementation does nothing*/
6468
virtual void setParameterMap( const QMap<QString, QString>& parameterMap )
6569
{ Q_UNUSED( parameterMap ); }

‎src/mapserver/qgsprojectparser.cpp

Lines changed: 219 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -88,30 +88,22 @@ int QgsProjectParser::numberOfLayers() const
8888
return mProjectLayerElements.size();
8989
}
9090

91-
void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const
91+
void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings ) const
9292
{
9393
QStringList nonIdentifiableLayers = identifyDisabledLayers();
94-
QMap<QString, QgsMapLayer *> layerMap;
94+
if ( mProjectLayerElements.size() < 1 )
95+
{
96+
return;
97+
}
9598

96-
foreach ( const QDomElement &elem, mProjectLayerElements )
99+
if ( fullProjectSettings )
97100
{
98-
QgsMapLayer *layer = createLayerFromElement( elem );
99-
if ( layer )
100-
{
101-
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
102-
layerMap.insert( layer->id(), layer );
103-
}
104-
#if QGSMSDEBUG
105-
else
106-
{
107-
QString buf;
108-
QTextStream s( &buf );
109-
elem.save( s, 0 );
110-
QgsDebugMsg( QString( "layer %1 not found" ).arg( buf ) );
111-
}
112-
#endif
101+
addDrawingOrder( parentElement, doc );
113102
}
114103

104+
QMap<QString, QgsMapLayer *> layerMap;
105+
projectLayerMap( layerMap );
106+
115107
//According to the WMS spec, there can be only one toplevel layer.
116108
//So we create an artificial one here to be in accordance with the schema
117109
QString projTitle = projectTitle();
@@ -128,7 +120,7 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement,
128120

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

131-
addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers );
123+
addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
132124

133125
parentElement.appendChild( layerParentElem );
134126
combineExtentAndCrsOfGroupChildren( layerParentElem, doc );
@@ -356,14 +348,20 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
356348
QDomElement &parentElem,
357349
const QDomElement &legendElem,
358350
const QMap<QString, QgsMapLayer *> &layerMap,
359-
const QStringList &nonIdentifiableLayers ) const
351+
const QStringList &nonIdentifiableLayers,
352+
QString version,
353+
bool fullProjectSettings ) const
360354
{
361355
QDomNodeList legendChildren = legendElem.childNodes();
362356
for ( int i = 0; i < legendChildren.size(); ++i )
363357
{
364358
QDomElement currentChildElem = legendChildren.at( i ).toElement();
365-
366359
QDomElement layerElem = doc.createElement( "Layer" );
360+
if ( fullProjectSettings )
361+
{
362+
layerElem.setAttribute( "visible", !( currentChildElem.attribute( "checked" ) == "Qt::Unchecked" ) );
363+
}
364+
367365

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

411-
p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled );
409+
p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled, version, fullProjectSettings );
412410
}
413411
}
414412
else //normal (not embedded) legend group
415413
{
416-
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers );
414+
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
417415
}
418416

419417
// combine bounding boxes of children (groups/layers)
@@ -489,6 +487,37 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
489487
styleElem.appendChild( styleNameElem );
490488
styleElem.appendChild( styleTitleElem );
491489
layerElem.appendChild( styleElem );
490+
491+
//min/max scale denominatormScaleBasedVisibility
492+
if ( currentLayer->hasScaleBasedVisibility() )
493+
{
494+
QString minScaleString = QString::number( currentLayer->minimumScale() );
495+
QString maxScaleString = QString::number( currentLayer->maximumScale() );
496+
497+
if ( version == "1.3.0" )
498+
{
499+
QDomElement minScaleElem = doc.createElement( "MinScaleDenominator" );
500+
QDomText minScaleText = doc.createTextNode( minScaleString );
501+
minScaleElem.appendChild( minScaleText );
502+
layerElem.appendChild( minScaleElem );
503+
QDomElement maxScaleElem = doc.createElement( "MaxScaleDenominator" );
504+
QDomText maxScaleText = doc.createTextNode( maxScaleString );
505+
maxScaleElem.appendChild( maxScaleText );
506+
layerElem.appendChild( maxScaleElem );
507+
}
508+
else if ( version == "1.1.1" )
509+
{
510+
QDomElement scaleHintElem = doc.createElement( "ScaleHint" );
511+
scaleHintElem.setAttribute( "min", minScaleString );
512+
scaleHintElem.setAttribute( "max", maxScaleString );
513+
layerElem.appendChild( scaleHintElem );
514+
}
515+
}
516+
517+
if ( fullProjectSettings )
518+
{
519+
addLayerProjectSettings( layerElem, doc, currentLayer );
520+
}
492521
}
493522
else
494523
{
@@ -500,6 +529,86 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
500529
}
501530
}
502531

532+
void QgsProjectParser::addLayerProjectSettings( QDomElement& layerElem, QDomDocument& doc, QgsMapLayer* currentLayer )
533+
{
534+
if ( !currentLayer )
535+
{
536+
return;
537+
}
538+
539+
if ( currentLayer->type() == QgsMapLayer::VectorLayer )
540+
{
541+
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( currentLayer );
542+
543+
//displayfield
544+
layerElem.setAttribute( "displayField", vLayer->displayField() );
545+
546+
//attributes
547+
QDomElement attributesElem = doc.createElement( "Attributes" );
548+
const QgsFieldMap& layerFields = vLayer->pendingFields();
549+
QgsFieldMap::const_iterator fieldIt = layerFields.constBegin();
550+
for ( ; fieldIt != layerFields.constEnd(); ++fieldIt )
551+
{
552+
QDomElement attributeElem = doc.createElement( "Attribute" );
553+
attributeElem.setAttribute( "name", fieldIt->name() );
554+
attributeElem.setAttribute( "type", QVariant::typeToName( fieldIt->type() ) );
555+
556+
//edit type to text
557+
QgsVectorLayer::EditType typeEnum = vLayer->editType( fieldIt.key() );
558+
attributeElem.setAttribute( "editType", editTypeString( typeEnum ) );
559+
attributeElem.setAttribute( "comment", fieldIt->comment() );
560+
attributeElem.setAttribute( "length", fieldIt->length() );
561+
attributeElem.setAttribute( "precision", fieldIt->precision() );
562+
attributesElem.appendChild( attributeElem );
563+
}
564+
layerElem.appendChild( attributesElem );
565+
}
566+
}
567+
568+
//not very nice, needs to be kept in sync with QgsVectorLayer class...
569+
QString QgsProjectParser::editTypeString( QgsVectorLayer::EditType type )
570+
{
571+
switch ( type )
572+
{
573+
case QgsVectorLayer::LineEdit:
574+
return "LineEdit";
575+
case QgsVectorLayer::UniqueValues:
576+
return "UniqueValues";
577+
case QgsVectorLayer::UniqueValuesEditable:
578+
return "UniqueValuesEditable";
579+
case QgsVectorLayer::ValueMap:
580+
return "ValueMap";
581+
case QgsVectorLayer::Classification:
582+
return "Classification";
583+
case QgsVectorLayer::EditRange:
584+
return "EditRange";
585+
case QgsVectorLayer::SliderRange:
586+
return "SliderRange";
587+
case QgsVectorLayer::CheckBox:
588+
return "CheckBox";
589+
case QgsVectorLayer::FileName:
590+
return "FileName";
591+
case QgsVectorLayer::Enumeration:
592+
return "Enumeration";
593+
case QgsVectorLayer::Immutable:
594+
return "Immutable";
595+
case QgsVectorLayer::Hidden:
596+
return "Hidden";
597+
case QgsVectorLayer::TextEdit:
598+
return "TextEdit";
599+
case QgsVectorLayer::Calendar:
600+
return "Calendar";
601+
case QgsVectorLayer::DialRange:
602+
return "DialRange";
603+
case QgsVectorLayer::ValueRelation:
604+
return "ValueRelation";
605+
case QgsVectorLayer::UuidGenerator:
606+
return "UuidGenerator";
607+
default:
608+
return "Unknown";
609+
}
610+
}
611+
503612
void QgsProjectParser::combineExtentAndCrsOfGroupChildren( QDomElement& groupElem, QDomDocument& doc ) const
504613
{
505614
QgsRectangle combinedBBox;
@@ -1338,9 +1447,6 @@ void QgsProjectParser::printCapabilities( QDomElement& parentElement, QDomDocume
13381447
}
13391448

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

13451451
for ( int i = 0; i < composerNodeList.size(); ++i )
13461452
{
@@ -1576,6 +1682,32 @@ QString QgsProjectParser::serviceUrl() const
15761682
return url;
15771683
}
15781684

1685+
QStringList QgsProjectParser::wfsLayerNames() const
1686+
{
1687+
QStringList layerNameList;
1688+
1689+
QMap<QString, QgsMapLayer*> layerMap;
1690+
projectLayerMap( layerMap );
1691+
1692+
QgsMapLayer* currentLayer = 0;
1693+
QStringList wfsIdList = wfsLayers();
1694+
QStringList::const_iterator wfsIdIt = wfsIdList.constBegin();
1695+
for ( ; wfsIdIt != wfsIdList.constEnd(); ++wfsIdIt )
1696+
{
1697+
QMap<QString, QgsMapLayer*>::const_iterator layerMapIt = layerMap.find( *wfsIdIt );
1698+
if ( layerMapIt != layerMap.constEnd() )
1699+
{
1700+
currentLayer = layerMapIt.value();
1701+
if ( currentLayer )
1702+
{
1703+
layerNameList.append( currentLayer->name() );
1704+
}
1705+
}
1706+
}
1707+
1708+
return layerNameList;
1709+
}
1710+
15791711
QString QgsProjectParser::convertToAbsolutePath( const QString& file ) const
15801712
{
15811713
if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) )
@@ -1778,3 +1910,64 @@ QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement&
17781910
BBox = t.transformBoundingBox( BBox );
17791911
return BBox;
17801912
}
1913+
1914+
void QgsProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const
1915+
{
1916+
if ( !mXMLDoc )
1917+
{
1918+
return;
1919+
}
1920+
1921+
//find legend section
1922+
QDomElement legendElement = mXMLDoc->documentElement().firstChildElement( "legend" );
1923+
if ( legendElement.isNull() )
1924+
{
1925+
return;
1926+
}
1927+
1928+
QStringList layerList;
1929+
1930+
bool useDrawingOrder = ( legendElement.attribute( "updateDrawingOrder" ) == "false" );
1931+
QDomNodeList layerNodeList = legendElement.elementsByTagName( "legendlayer" );
1932+
if ( !useDrawingOrder ) //bottom to top
1933+
{
1934+
for ( int i = 0; i < layerNodeList.size(); ++i )
1935+
{
1936+
layerList.prepend( layerNodeList.at( i ).toElement().attribute( "name" ) );
1937+
}
1938+
}
1939+
else
1940+
{
1941+
QMap<int, QString> orderedLayerNames;
1942+
for ( int i = 0; i < layerNodeList.size(); ++i )
1943+
{
1944+
QString layerName = layerNodeList.at( i ).toElement().attribute( "name" );
1945+
int order = layerNodeList.at( i ).toElement().attribute( "drawingOrder" ).toInt();
1946+
orderedLayerNames.insert( order, layerName );
1947+
}
1948+
1949+
QMap<int, QString>::const_iterator orderIt = orderedLayerNames.constBegin();
1950+
for ( ; orderIt != orderedLayerNames.constEnd(); ++orderIt )
1951+
{
1952+
layerList.prepend( *orderIt );
1953+
}
1954+
}
1955+
QDomElement layerDrawingOrderElem = doc.createElement( "LayerDrawingOrder" );
1956+
QDomText drawingOrderText = doc.createTextNode( layerList.join( "," ) );
1957+
layerDrawingOrderElem.appendChild( drawingOrderText );
1958+
parentElem.appendChild( layerDrawingOrderElem );
1959+
}
1960+
1961+
void QgsProjectParser::projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap ) const
1962+
{
1963+
layerMap.clear();
1964+
foreach ( const QDomElement &elem, mProjectLayerElements )
1965+
{
1966+
QgsMapLayer *layer = createLayerFromElement( elem );
1967+
if ( layer )
1968+
{
1969+
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
1970+
layerMap.insert( layer->id(), layer );
1971+
}
1972+
}
1973+
}

0 commit comments

Comments
 (0)
Please sign in to comment.