Skip to content
Permalink
Browse files

[QGIS-Server] More ISO compatibility for WxS capabilities

* Add ISO keyword for the service
* Default Fees is conditions unknown
* Default AccessConstraints is None
* Calculate boundingBox for all CRSes
  • Loading branch information
rldhont committed Nov 2, 2015
1 parent 584c86d commit 67d541c619b312bd64cae35b66d98f0cae92f3a2
@@ -78,7 +78,7 @@ void QgsConfigParserUtils::appendCRSElementToLayer( QDomElement& layerElement, c
}

void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent,
const QgsCoordinateReferenceSystem& layerCRS )
const QgsCoordinateReferenceSystem& layerCRS, const QStringList &crsList, const QStringList& constrainedCrsList )
{
if ( layerElem.isNull() )
{
@@ -123,7 +123,7 @@ void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDo
ExGeoBBoxElement.appendChild( nBoundLatitudeElement );
}


/*
//BoundingBox element
QDomElement bBoxElement = doc.createElement( "BoundingBox" );
if ( layerCRS.isValid() )
@@ -141,17 +141,86 @@ void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDo
bBoxElement.setAttribute( "miny", QString::number( r.yMinimum() ) );
bBoxElement.setAttribute( "maxx", QString::number( r.xMaximum() ) );
bBoxElement.setAttribute( "maxy", QString::number( r.yMaximum() ) );
*/

QDomElement lastCRSElem = layerElem.lastChildElement( version == "1.1.1" ? "SRS" : "CRS" );
if ( !lastCRSElem.isNull() )
{
layerElem.insertAfter( ExGeoBBoxElement, lastCRSElem );
layerElem.insertAfter( bBoxElement, ExGeoBBoxElement );
//layerElem.insertAfter( bBoxElement, ExGeoBBoxElement );
}
else
{
layerElem.appendChild( ExGeoBBoxElement );
layerElem.appendChild( bBoxElement );
//layerElem.appendChild( bBoxElement );
}

//In case the number of advertised CRS is constrained
if ( constrainedCrsList.size() > 0 )
{
for ( int i = constrainedCrsList.size() - 1; i >= 0; --i )
{
appendLayerBoundingBox( layerElem, doc, layerExtent, layerCRS, constrainedCrsList.at( i ) );
}
}
else //no crs constraint
{
Q_FOREACH ( const QString& crs, crsList )
{
appendLayerBoundingBox( layerElem, doc, layerExtent, layerCRS, crs );
}
}
}

void QgsConfigParserUtils::appendLayerBoundingBox( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent,
const QgsCoordinateReferenceSystem& layerCRS, const QString& crsText )
{
if ( layerElem.isNull() )
{
return;
}

QString version = doc.documentElement().attribute( "version" );

const QgsCoordinateReferenceSystem& crs = QgsCRSCache::instance()->crsByAuthId( crsText );

//transform the layers native CRS into CRS
QgsCoordinateTransform crsTransform( layerCRS, crs );
QgsRectangle crsExtent = crsTransform.transformBoundingBox( layerExtent );

//BoundingBox element
QDomElement bBoxElement = doc.createElement( "BoundingBox" );
if ( crs.isValid() )
{
bBoxElement.setAttribute( version == "1.1.1" ? "SRS" : "CRS", crs.authid() );
}

if ( version != "1.1.1" && crs.axisInverted() )
{
crsExtent.invert();
}

bBoxElement.setAttribute( "minx", QString::number( crsExtent.xMinimum() ) );
bBoxElement.setAttribute( "miny", QString::number( crsExtent.yMinimum() ) );
bBoxElement.setAttribute( "maxx", QString::number( crsExtent.xMaximum() ) );
bBoxElement.setAttribute( "maxy", QString::number( crsExtent.yMaximum() ) );

QDomElement lastBBoxElem = layerElem.lastChildElement( "BoundingBox" );
if ( !lastBBoxElem.isNull() )
{
layerElem.insertAfter( bBoxElement, lastBBoxElem );
}
else
{
lastBBoxElem = layerElem.lastChildElement( version == "1.1.1" ? "LatLonBoundingBox" : "EX_GeographicBoundingBox" );
if ( !lastBBoxElem.isNull() )
{
layerElem.insertAfter( bBoxElement, lastBBoxElem );
}
else
{
layerElem.appendChild( bBoxElement );
}
}
}

@@ -35,7 +35,10 @@ class QgsConfigParserUtils
static void appendCRSElementToLayer( QDomElement& layerElement, const QDomElement& precedingElement,
const QString& crsText, QDomDocument& doc );
static void appendLayerBoundingBoxes( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent,
const QgsCoordinateReferenceSystem& layerCRS );
const QgsCoordinateReferenceSystem& layerCRS, const QStringList &crsList,
const QStringList& constrainedCrsList );
static void appendLayerBoundingBox( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent,
const QgsCoordinateReferenceSystem& layerCRS, const QString& crsText );
/** Returns a list of supported EPSG coordinate system numbers from a layer*/
static QStringList createCRSListForLayer( QgsMapLayer* theMapLayer );

@@ -418,26 +418,33 @@ void QgsServerProjectParser::serviceCapabilities( QDomElement& parentElement, QD

//keyword list
QDomElement keywordListElem = propertiesElement.firstChildElement( "WMSKeywordList" );
QDomElement wmsKeywordElem = doc.createElement( "KeywordList" );
//add default keyword
QDomElement keywordElem = doc.createElement( "Keyword" );
keywordElem.setAttribute( "vocabulary", "ISO" );
QDomText keywordText = doc.createTextNode( "infoMapAccessService" );
if ( service.compare( "WFS", Qt::CaseInsensitive ) == 0 )
keywordText = doc.createTextNode( "infoFeatureAccessService" );
else if ( service.compare( "WCS", Qt::CaseInsensitive ) == 0 )
keywordText = doc.createTextNode( "infoCoverageAccessService" );
keywordElem.appendChild( keywordText );
wmsKeywordElem.appendChild( keywordElem );
serviceElem.appendChild( wmsKeywordElem );
//add config keywords
if ( !keywordListElem.isNull() && !keywordListElem.text().isEmpty() )
{
QDomElement wmsKeywordElem = doc.createElement( "KeywordList" );
QDomNodeList keywordList = keywordListElem.elementsByTagName( "value" );
for ( int i = 0; i < keywordList.size(); ++i )
{
QDomElement keywordElem = doc.createElement( "Keyword" );
QDomText keywordText = doc.createTextNode( keywordList.at( i ).toElement().text() );
keywordElem = doc.createElement( "Keyword" );
keywordText = doc.createTextNode( keywordList.at( i ).toElement().text() );
keywordElem.appendChild( keywordText );
if ( sia2045 )
{
keywordElem.setAttribute( "vocabulary", "SIA_Geo405" );
}
wmsKeywordElem.appendChild( keywordElem );
}

if ( keywordList.size() > 0 )
{
serviceElem.appendChild( wmsKeywordElem );
}
}

//OnlineResource element is mandatory according to the WMS specification
@@ -511,23 +518,25 @@ void QgsServerProjectParser::serviceCapabilities( QDomElement& parentElement, QD

//Fees
QDomElement feesElem = propertiesElement.firstChildElement( "WMSFees" );
if ( !feesElem.isNull() )
QDomElement wmsFeesElem = doc.createElement( "Fees" );
QDomText wmsFeesText = doc.createTextNode( "conditions unknown" ); // default value if access conditions are unknown
if ( !feesElem.isNull() && feesElem.text() != "" )
{
QDomElement wmsFeesElem = doc.createElement( "Fees" );
QDomText wmsFeesText = doc.createTextNode( feesElem.text() );
wmsFeesElem.appendChild( wmsFeesText );
serviceElem.appendChild( wmsFeesElem );
wmsFeesText = doc.createTextNode( feesElem.text() );
}
wmsFeesElem.appendChild( wmsFeesText );
serviceElem.appendChild( wmsFeesElem );

//AccessConstraints
QDomElement accessConstraintsElem = propertiesElement.firstChildElement( "WMSAccessConstraints" );
if ( !accessConstraintsElem.isNull() )
QDomElement wmsAccessConstraintsElem = doc.createElement( "AccessConstraints" );
QDomText wmsAccessConstraintsText = doc.createTextNode( "None" ); // default value if access constraints are unknown
if ( !accessConstraintsElem.isNull() && accessConstraintsElem.text() != "" )
{
QDomElement wmsAccessConstraintsElem = doc.createElement( "AccessConstraints" );
QDomText wmsAccessConstraintsText = doc.createTextNode( accessConstraintsElem.text() );
wmsAccessConstraintsElem.appendChild( wmsAccessConstraintsText );
serviceElem.appendChild( wmsAccessConstraintsElem );
wmsAccessConstraintsText = doc.createTextNode( accessConstraintsElem.text() );
}
wmsAccessConstraintsElem.appendChild( wmsAccessConstraintsText );
serviceElem.appendChild( wmsAccessConstraintsElem );

//max width, max height for WMS
if ( service.compare( "WMS", Qt::CaseInsensitive ) == 0 )
@@ -692,7 +701,7 @@ void QgsServerProjectParser::combineExtentAndCrsOfGroupChildren( QDomElement& gr
combinedBBox = mapRect;
}
}
QgsConfigParserUtils::appendLayerBoundingBoxes( groupElem, doc, combinedBBox, groupCRS );
QgsConfigParserUtils::appendLayerBoundingBoxes( groupElem, doc, combinedBBox, groupCRS, combinedCRSSet.toList(), supportedOutputCrsList() );
}

void QgsServerProjectParser::addLayerProjectSettings( QDomElement& layerElem, QDomDocument& doc, QgsMapLayer* currentLayer ) const
@@ -166,7 +166,7 @@ void QgsSLDConfigParser::layersAndStylesCapabilities( QDomElement& parentElement
QStringList crsNumbers = QgsConfigParserUtils::createCRSListForLayer( theMapLayer );
QStringList crsRestriction; //no crs restrictions in SLD parser
QgsConfigParserUtils::appendCRSElementsToLayer( layerElement, doc, crsNumbers, crsRestriction );
QgsConfigParserUtils::appendLayerBoundingBoxes( layerElement, doc, theMapLayer->extent(), theMapLayer->crs() );
QgsConfigParserUtils::appendLayerBoundingBoxes( layerElement, doc, theMapLayer->extent(), theMapLayer->crs(), crsNumbers, crsRestriction );

//iterate over all <UserStyle> nodes within a user layer
QDomNodeList userStyleList = layerNodeList.item( i ).toElement().elementsByTagName( "UserStyle" );
@@ -1082,7 +1082,7 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,
QgsConfigParserUtils::appendCRSElementsToLayer( layerElem, doc, crsList, mProjectParser->supportedOutputCrsList() );

//Ex_GeographicBoundingBox
QgsConfigParserUtils::appendLayerBoundingBoxes( layerElem, doc, currentLayer->extent(), currentLayer->crs() );
QgsConfigParserUtils::appendLayerBoundingBoxes( layerElem, doc, currentLayer->extent(), currentLayer->crs(), crsList, mProjectParser->supportedOutputCrsList() );
}

// add details about supported styles of the layer

4 comments on commit 67d541c

@m-kuhn

This comment has been minimized.

Copy link
Member

@m-kuhn m-kuhn replied Nov 2, 2015

This introduces the following diff in the server test:

6a7,9
>   <KeywordList>
>    <Keyword vocabulary="ISO">infoMapAccessService</Keyword>
>   </KeywordList>
16,17c19,20
<   <Fees></Fees>
<   <AccessConstraints></AccessConstraints>

---
>   <Fees>conditions unknown</Fees>
>   <AccessConstraints>None</AccessConstraints>
105a109
>    <BoundingBox CRS="EPSG:3857" maxx="913283" minx="913171" maxy="5.60604e+06" miny="5.60599e+06"/>
118a123
>     <BoundingBox CRS="EPSG:3857" maxx="913215" minx="913205" maxy="5.60603e+06" miny="5.60601e+06"/>

Can you check if this is expected/okay and update the test?
Thanks

http://dash.orfeo-toolbox.org/testDetails.php?test=34371054&build=205744

@nyalldawson

This comment has been minimized.

Copy link
Collaborator

@nyalldawson nyalldawson replied Nov 2, 2015

@rldhont this has broken the server unit test... Can you please update that test too?

@rldhont

This comment has been minimized.

Copy link
Contributor Author

@rldhont rldhont replied Nov 2, 2015

Ooops, I'll updated the test because the diff is expected.

@rldhont

This comment has been minimized.

Copy link
Contributor Author

@rldhont rldhont replied Nov 2, 2015

Done here a9e5670

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