Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improve QGIS Server WMS GetCapabilities output
  • Loading branch information
github-actions[bot] committed Apr 17, 2020
1 parent 984615f commit ac76dbd
Show file tree
Hide file tree
Showing 15 changed files with 495 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/server/services/wms/qgswms.cpp
Expand Up @@ -128,7 +128,7 @@ namespace QgsWms
}
else if ( QSTR_COMPARE( req, "GetSchemaExtension" ) )
{
writeGetSchemaExtension( mServerIface, version, request, response );
writeGetSchemaExtension( response );
}
else if ( QSTR_COMPARE( req, "GetStyle" ) )
{
Expand Down
94 changes: 58 additions & 36 deletions src/server/services/wms/qgswmsgetcapabilities.cpp
Expand Up @@ -266,14 +266,26 @@ namespace QgsWms
nameElem.appendChild( nameText );
serviceElem.appendChild( nameElem );

QDomText titleText;
QString title = QgsServerProjectUtils::owsServiceTitle( *project );
QDomElement titleElem = doc.createElement( QStringLiteral( "Title" ) );
if ( !title.isEmpty() )
{
QDomElement titleElem = doc.createElement( QStringLiteral( "Title" ) );
QDomText titleText = doc.createTextNode( title );
titleElem.appendChild( titleText );
serviceElem.appendChild( titleElem );
titleText = doc.createTextNode( title );
}
else
{
if ( !project->title().isEmpty() )
{
titleText = doc.createTextNode( project->title() );
}
else
{
titleText = doc.createTextNode( QStringLiteral( "untitled" ) );
}
}
titleElem.appendChild( titleText );
serviceElem.appendChild( titleElem );

QString abstract = QgsServerProjectUtils::owsServiceAbstract( *project );
if ( !abstract.isEmpty() )
Expand Down Expand Up @@ -313,38 +325,47 @@ namespace QgsWms

//Contact person primary
if ( !contactPerson.isEmpty() ||
!contactOrganization.isEmpty() ||
!contactPosition.isEmpty() )
!contactOrganization.isEmpty() )
{
QDomElement contactPersonPrimaryElem = doc.createElement( QStringLiteral( "ContactPersonPrimary" ) );

QDomText contactPersonText;
if ( !contactPerson.isEmpty() )
{
QDomElement contactPersonElem = doc.createElement( QStringLiteral( "ContactPerson" ) );
QDomText contactPersonText = doc.createTextNode( contactPerson );
contactPersonElem.appendChild( contactPersonText );
contactPersonPrimaryElem.appendChild( contactPersonElem );
contactPersonText = doc.createTextNode( contactPerson );
}
else
{
contactPersonText = doc.createTextNode( QStringLiteral( "unknown" ) );
}
QDomElement contactPersonElem = doc.createElement( QStringLiteral( "ContactPerson" ) );
contactPersonElem.appendChild( contactPersonText );
contactPersonPrimaryElem.appendChild( contactPersonElem );

QDomText contactOrganizationText;
if ( !contactOrganization.isEmpty() )
{
QDomElement contactOrganizationElem = doc.createElement( QStringLiteral( "ContactOrganization" ) );
QDomText contactOrganizationText = doc.createTextNode( contactOrganization );
contactOrganizationElem.appendChild( contactOrganizationText );
contactPersonPrimaryElem.appendChild( contactOrganizationElem );
contactOrganizationText = doc.createTextNode( contactOrganization );
}

if ( !contactPosition.isEmpty() )
else
{
QDomElement contactPositionElem = doc.createElement( QStringLiteral( "ContactPosition" ) );
QDomText contactPositionText = doc.createTextNode( contactPosition );
contactPositionElem.appendChild( contactPositionText );
contactPersonPrimaryElem.appendChild( contactPositionElem );
contactOrganizationText = doc.createTextNode( QStringLiteral( "unknown" ) );
}
QDomElement contactOrganizationElem = doc.createElement( QStringLiteral( "ContactOrganization" ) );
contactOrganizationElem.appendChild( contactOrganizationText );
contactPersonPrimaryElem.appendChild( contactOrganizationElem );

contactInfoElem.appendChild( contactPersonPrimaryElem );
}

if ( !contactPosition.isEmpty() )
{
QDomElement contactPositionElem = doc.createElement( QStringLiteral( "ContactPosition" ) );
QDomText contactPositionText = doc.createTextNode( contactPosition );
contactPositionElem.appendChild( contactPositionText );
contactInfoElem.appendChild( contactPositionElem );
}

if ( !contactPhone.isEmpty() )
{
QDomElement phoneElem = doc.createElement( QStringLiteral( "ContactVoiceTelephone" ) );
Expand Down Expand Up @@ -808,21 +829,6 @@ namespace QgsWms

QDomElement layerParentElem = doc.createElement( QStringLiteral( "Layer" ) );

if ( !project->title().isEmpty() )
{
// Root Layer title
QDomElement layerParentTitleElem = doc.createElement( QStringLiteral( "Title" ) );
QDomText layerParentTitleText = doc.createTextNode( project->title() );
layerParentTitleElem.appendChild( layerParentTitleText );
layerParentElem.appendChild( layerParentTitleElem );

// Root Layer abstract
QDomElement layerParentAbstElem = doc.createElement( QStringLiteral( "Abstract" ) );
QDomText layerParentAbstText = doc.createTextNode( project->title() );
layerParentAbstElem.appendChild( layerParentAbstText );
layerParentElem.appendChild( layerParentAbstElem );
}

// Root Layer name
QString rootLayerName = QgsServerProjectUtils::wmsRootName( *project );
if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
Expand All @@ -838,6 +844,21 @@ namespace QgsWms
layerParentElem.appendChild( layerParentNameElem );
}

if ( !project->title().isEmpty() )
{
// Root Layer title
QDomElement layerParentTitleElem = doc.createElement( QStringLiteral( "Title" ) );
QDomText layerParentTitleText = doc.createTextNode( project->title() );
layerParentTitleElem.appendChild( layerParentTitleText );
layerParentElem.appendChild( layerParentTitleElem );

// Root Layer abstract
QDomElement layerParentAbstElem = doc.createElement( QStringLiteral( "Abstract" ) );
QDomText layerParentAbstText = doc.createTextNode( project->title() );
layerParentAbstElem.appendChild( layerParentAbstText );
layerParentElem.appendChild( layerParentAbstElem );
}

// Keyword list
addKeywordListElement( project, doc, layerParentElem );

Expand Down Expand Up @@ -1373,7 +1394,8 @@ namespace QgsWms
//insert the CRS elements after the title element to be in accordance with the WMS 1.3 specification
QDomElement titleElement = layerElement.firstChildElement( QStringLiteral( "Title" ) );
QDomElement abstractElement = layerElement.firstChildElement( QStringLiteral( "Abstract" ) );
QDomElement CRSPrecedingElement = abstractElement.isNull() ? titleElement : abstractElement; //last element before the CRS elements
QDomElement keywordListElement = layerElement.firstChildElement( QStringLiteral( "KeywordList" ) );
QDomElement CRSPrecedingElement = !keywordListElement.isNull() ? keywordListElement : !abstractElement.isNull() ? abstractElement : titleElement;

if ( CRSPrecedingElement.isNull() )
{
Expand Down
49 changes: 21 additions & 28 deletions src/server/services/wms/qgswmsgetschemaextension.cpp
Expand Up @@ -24,13 +24,14 @@

#include <QDir>
#include <QFileInfo>
#include <QTextStream>

namespace QgsWms
{

void writeGetSchemaExtension( QgsServerInterface *serverIface, const QString &version,
const QgsServerRequest &request, QgsServerResponse &response )
void writeGetSchemaExtension( QgsServerResponse &response )
{
<<<<<<< HEAD
QDomDocument doc = getSchemaExtension( serverIface, version, request );
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
response.write( doc.toByteArray() );
Expand All @@ -46,42 +47,34 @@ namespace QgsWms

QDomDocument xsdDoc;

=======
>>>>>>> 970149f13e... Merge pull request #35702 from jgrocha/fix-wms-capabilities
QDir resourcesDir = QFileInfo( QgsApplication::serverResourcesPath() ).absoluteDir();
QFileInfo xsdFileInfo( resourcesDir, QStringLiteral( "schemaExtension.xsd" ) );
QString schema_str = QStringLiteral( "<?xml version='1.0'?>" );

if ( !xsdFileInfo.exists() )
{
QgsMessageLog::logMessage( QStringLiteral( "Error, xsd file 'schemaExtension.xsd' does not exist" ),
QStringLiteral( "Server" ), Qgis::Critical );
return xsdDoc;
}

QString xsdFilePath = xsdFileInfo.absoluteFilePath();
QFile xsdFile( xsdFilePath );
if ( !xsdFile.exists() )
else
{
QgsMessageLog::logMessage( QStringLiteral( "Error, xsd file 'schemaExtension.xsd' does not exist" ),
QStringLiteral( "Server" ), Qgis::Critical );
return xsdDoc;
}

if ( !xsdFile.open( QIODevice::ReadOnly ) )
{
QgsMessageLog::logMessage( QStringLiteral( "Error, cannot open xsd file 'schemaExtension.xsd' does not exist" ),
QStringLiteral( "Server" ), Qgis::Critical );
return xsdDoc;
QFile file( xsdFileInfo.absoluteFilePath() );
if ( file.open( QFile::ReadOnly | QFile::Text ) )
{
QTextStream in( &file );
schema_str = in.readAll();
file.close();
}
else
{
QgsMessageLog::logMessage( QStringLiteral( "Error, xsd file 'schemaExtension.xsd' not readable" ),
QStringLiteral( "Server" ), Qgis::Critical );
}
}

QString errorMsg;
int line, column;
if ( !xsdDoc.setContent( &xsdFile, true, &errorMsg, &line, &column ) )
{
QgsMessageLog::logMessage( QStringLiteral( "Error parsing file 'schemaExtension.xsd" ) +
QStringLiteral( "': parse error %1 at row %2, column %3" ).arg( errorMsg ).arg( line ).arg( column ),
QStringLiteral( "Server" ), Qgis::Critical );
}

return xsdDoc;
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
response.write( schema_str );
}

} // namespace QgsWms
11 changes: 1 addition & 10 deletions src/server/services/wms/qgswmsgetschemaextension.h
Expand Up @@ -25,16 +25,7 @@ namespace QgsWms
/**
* Output GetSchemaExtension response
*/
void writeGetSchemaExtension( QgsServerInterface *serverIface, const QString &version,
const QgsServerRequest &request, QgsServerResponse &response );


/**
* Returns the schemaExtension for WMS 1.3.0 capabilities
*/
QDomDocument getSchemaExtension( QgsServerInterface *serverIface, const QString &version,
const QgsServerRequest &request );

void writeGetSchemaExtension( QgsServerResponse &response );

} // namespace QgsWms

Expand Down
8 changes: 4 additions & 4 deletions tests/testdata/qgis_server/getcapabilities.txt
Expand Up @@ -101,8 +101,12 @@ Content-Type: text/xml; charset=utf-8
</Exception>
<sld:UserDefinedSymbolization SupportSLD="1" RemoteWCS="0" UserLayer="0" InlineFeature="0" RemoteWFS="0" UserStyle="1"/>
<Layer queryable="1">
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
<Abstract>QGIS Test Project</Abstract>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
Expand All @@ -114,10 +118,6 @@ Content-Type: text/xml; charset=utf-8
</EX_GeographicBoundingBox>
<BoundingBox maxy="5606043.446" maxx="913283.462" miny="5605986.581" CRS="EPSG:3857" minx="913170.942"/>
<BoundingBox maxy="8.204165" maxx="44.901599" miny="8.203154" CRS="EPSG:4326" minx="44.901236"/>
<Name>QGIS Test Project</Name>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<Layer queryable="1">
<Name>layer_with_short_name</Name>
<Title>A Layer with a short name</Title>
Expand Down
10 changes: 5 additions & 5 deletions tests/testdata/qgis_server/getcapabilities_inspire.txt
Expand Up @@ -15,8 +15,8 @@ Content-Type: text/xml; charset=utf-8
<ContactPersonPrimary>
<ContactPerson>Alessandro Pasotti</ContactPerson>
<ContactOrganization>QGIS dev team</ContactOrganization>
<ContactPosition>originator</ContactPosition>
</ContactPersonPrimary>
<ContactPosition>originator</ContactPosition>
<ContactElectronicMailAddress>elpaso@itopen.it</ContactElectronicMailAddress>
</ContactInformation>
<Fees>conditions unknown</Fees>
Expand Down Expand Up @@ -122,8 +122,12 @@ Content-Type: text/xml; charset=utf-8
</inspire_common:ResponseLanguage>
</inspire_vs:ExtendedCapabilities>
<Layer queryable="1">
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
<Abstract>QGIS Test Project</Abstract>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
Expand All @@ -135,10 +139,6 @@ Content-Type: text/xml; charset=utf-8
</EX_GeographicBoundingBox>
<BoundingBox maxy="5606043.446" maxx="913283.462" miny="5605986.581" CRS="EPSG:3857" minx="913170.942"/>
<BoundingBox maxy="8.204165" maxx="44.901599" miny="8.203154" CRS="EPSG:4326" minx="44.901236"/>
<Name>QGIS Test Project</Name>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<Layer queryable="1">
<Name>testlayer èé</Name>
<Title>A test vector layer</Title>
Expand Down
8 changes: 4 additions & 4 deletions tests/testdata/qgis_server/getprojectsettings.txt
Expand Up @@ -122,8 +122,12 @@ Content-Type: text/xml; charset=utf-8
<WFSLayer name="testlayer èé"/>
</WFSLayers>
<Layer>
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
<Abstract>QGIS Test Project</Abstract>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
Expand All @@ -135,10 +139,6 @@ Content-Type: text/xml; charset=utf-8
</EX_GeographicBoundingBox>
<BoundingBox maxy="5606043.446" maxx="913283.462" miny="5605986.581" CRS="EPSG:3857" minx="913170.942"/>
<BoundingBox maxy="8.204165" maxx="44.901599" miny="8.203154" CRS="EPSG:4326" minx="44.901236"/>
<Name>QGIS Test Project</Name>
<KeywordList>
<Keyword vocabulary="ISO">infoMapAccessService</Keyword>
</KeywordList>
<TreeName>QGIS Test Project</TreeName>
<Layer geometryType="Point" queryable="1" displayField="id" visible="1">
<Name>layer_with_short_name</Name>
Expand Down

0 comments on commit ac76dbd

Please sign in to comment.