Skip to content
Permalink
Browse files
Further improvements to WMS.
* pseudo-status bar in the "Add a WMS Layer" dialog - shows progress of network operations
* Can now handle old-style "SRS" tags as well as the existing "CRS" support - SRS could contain several SRSs separated by whitespace, the provider now handles this.
* The retrieval of server capabilities is not now handled by the WMS constructor, instead it is triggered at the time a function needs them (e.g. calculateExtents).  This gives time for a caller to connect a slot to the setStatus signal _before_ the interesting stuff happens.



git-svn-id: http://svn.osgeo.org/qgis/trunk@4909 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
morb_au committed Feb 26, 2006
1 parent ecf20c1 commit 90f2f9bac67a43150990956597fbd359a3df2c8b
@@ -311,6 +311,8 @@ void QgsServerSourceSelect::on_btnConnect_clicked()
QgsWmsProvider* wmsProvider =
(QgsWmsProvider*) pReg->getProvider( "wms", m_connInfo );

connect(wmsProvider, SIGNAL(setStatus(QString)), this, SLOT(showStatusMessage(QString)));

populateLayerList(wmsProvider);

}
@@ -432,3 +434,14 @@ QString QgsServerSourceSelect::selectedImageEncoding()

}

void QgsServerSourceSelect::showStatusMessage(QString const & theMessage)
{
labelStatus->setText(theMessage);

// update the display of this widget
this->update();
}




@@ -85,6 +85,10 @@ public slots:
//! Signaled when a layer selection is changed. Ensures that only one style is selected per layer.
void on_lstLayers_selectionChanged();

//! Set status message to theMessage
void showStatusMessage(QString const & theMessage);


private:

//! Populate the layer list - private for now.
@@ -250,7 +250,6 @@ void QgsHttpTransaction::dataProgress( int done, int total )
}

emit setStatus( status );

}

void QgsHttpTransaction::dataFinished( int id, bool error )
@@ -283,60 +282,71 @@ void QgsHttpTransaction::dataStateChanged( int state )
std::cout << "QgsHttpTransaction::dataStateChanged to " << state << "." << std::endl << " ";
#endif

#ifdef QGISDEBUG
switch (state)
{
case Q3Http::Unconnected:
// std::cout << "There is no connection to the host." << std::endl;

#ifdef QGISDEBUG
std::cout << "There is no connection to the host." << std::endl;
#endif

emit setStatus( QString("Not connected") );
break;

case Q3Http::HostLookup:
// std::cout << "A host name lookup is in progress." << std::endl;

#ifdef QGISDEBUG
std::cout << "A host name lookup is in progress." << std::endl;
#endif

emit setStatus( QString("Looking up '%1'")
.arg(httphost) );
break;

case Q3Http::Connecting:
// std::cout << "An attempt to connect to the host is in progress." << std::endl;

#ifdef QGISDEBUG
std::cout << "An attempt to connect to the host is in progress." << std::endl;
#endif

emit setStatus( QString("Connecting to '%1'")
.arg(httphost) );
break;

case Q3Http::Sending:
// std::cout << "The client is sending its request to the server." << std::endl;

#ifdef QGISDEBUG
std::cout << "The client is sending its request to the server." << std::endl;
#endif

emit setStatus( QString("Sending request '%1'")
.arg(httpurl) );
break;

case Q3Http::Reading:
// std::cout << "The client's request has been sent and the client "
// "is reading the server's response." << std::endl;

#ifdef QGISDEBUG
std::cout << "The client's request has been sent and the client "
"is reading the server's response." << std::endl;
#endif

emit setStatus( QString("Receiving reply") );
break;

case Q3Http::Connected:
// std::cout << "The connection to the host is open, but the client "
// "is neither sending a request, nor waiting for a response." << std::endl;

#ifdef QGISDEBUG
std::cout << "The connection to the host is open, but the client "
"is neither sending a request, nor waiting for a response." << std::endl;
#endif

emit setStatus( QString("Response is complete") );
break;

case Q3Http::Closing:
// std::cout << "The connection is closing down, but is not yet closed. "
// "(The state will be Unconnected when the connection is closed.)" << std::endl;

#ifdef QGISDEBUG
std::cout << "The connection is closing down, but is not yet closed. "
"(The state will be Unconnected when the connection is closed.)" << std::endl;
#endif

emit setStatus( QString("Closing down connection") );
break;
}
}

#endif

}


@@ -123,7 +123,7 @@ QgsWmsProvider::QgsWmsProvider(QString const & uri)
std::cout << "baseUrl = " << baseUrl.toLocal8Bit().data() << std::endl;
#endif

getServerCapabilities();
// getServerCapabilities();

//httpuri = "http://www.ga.gov.au/bin/getmap.pl?dataset=national&Service=WMS&Version=1.1.0&Request=GetMap&"
// "BBox=130,-40,160,-10&SRS=EPSG:4326&Width=400&Height=400&Layers=railways&Format=image/png";
@@ -380,6 +380,9 @@ QImage* QgsWmsProvider::draw(QgsRect const & viewExtent, int pixelWidth, int pi
url += "&";
url += "TRANSPARENT=TRUE";

#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::draw: emitting setStatus(Test from QgsWmsProvider)." << std::endl;
#endif
emit setStatus( QString("Test from QgsWmsProvider") );


@@ -464,7 +467,7 @@ QImage* QgsWmsProvider::draw(QgsRect const & viewExtent, int pixelWidth, int pi

}


/*
void QgsWmsProvider::getServerCapabilities()
{
@@ -481,31 +484,43 @@ void QgsWmsProvider::getServerCapabilities()
#endif
}
*/


void QgsWmsProvider::retrieveServerCapabilities()
bool QgsWmsProvider::retrieveServerCapabilities(bool forceRefresh)
{
#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::retrieveServerCapabilities: entering." << std::endl;
#endif

// TODO: Smarter caching - need to refresh if demanded.

if ( httpcapabilitiesresponse.isNull() )
if ( httpcapabilitiesresponse.isNull() or
forceRefresh )
{

QString url = baseUrl + "SERVICE=WMS&REQUEST=GetCapabilities";

QgsHttpTransaction http(url, httpproxyhost, httpproxyport);

// Do a passthrough for the status bar text
connect(
&http, SIGNAL(setStatus (QString)),
this, SLOT(showStatusMessage(QString))
);

http.getSynchronously(httpcapabilitiesresponse);


#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::getServerCapabilities: Converting to DOM." << std::endl;
#endif

parseCapabilities(httpcapabilitiesresponse, capabilities);
bool parseSuccess = parseCapabilities(httpcapabilitiesresponse, capabilities);

if (!parseSuccess)
{
// TODO
}

}

@@ -525,6 +540,12 @@ bool QgsWmsProvider::downloadCapabilitiesURI(QString const & uri)

QgsHttpTransaction http(uri, httpproxyhost, httpproxyport);

// Do a passthrough for the status bar text
connect(
&http, SIGNAL(setStatus (QString)),
this, SLOT(showStatusMessage(QString))
);

bool httpOk;

httpOk = http.getSynchronously(httpcapabilitiesresponse);
@@ -556,7 +577,7 @@ bool QgsWmsProvider::downloadCapabilitiesURI(QString const & uri)
}


void QgsWmsProvider::parseCapabilities(QByteArray const & xml, QgsWmsCapabilitiesProperty& capabilitiesProperty)
bool QgsWmsProvider::parseCapabilities(QByteArray const & xml, QgsWmsCapabilitiesProperty& capabilitiesProperty)
{
#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::parseCapabilities: entering." << std::endl;
@@ -565,6 +586,7 @@ void QgsWmsProvider::parseCapabilities(QByteArray const & xml, QgsWmsCapabiliti
QString responsestring(xml);
qWarning("QgsWmsProvider::parseCapabilities, received the following data: "+responsestring);


//QFile file( "/tmp/qgis-wmsprovider-capabilities.xml" );
//if ( file.open( QIODevice::WriteOnly ) )
//{
@@ -574,13 +596,27 @@ void QgsWmsProvider::parseCapabilities(QByteArray const & xml, QgsWmsCapabiliti
#endif

// Convert completed document into a DOM
QString errormsg;
bool contentsuccess = capabilitiesDOM.setContent(xml, false, &errormsg);
QString errorMsg;
int errorLine;
int errorColumn;
bool contentSuccess = capabilitiesDOM.setContent(xml, false, &errorMsg, &errorLine, &errorColumn);

if (!contentSuccess)
{
mErrorCaption = tr("DOM Exception");
mError = QString(tr("Could not get WMS capabilities at %1: %2 at line %3 column %4")
.arg(baseUrl)
.arg(errorMsg)
.arg(errorLine)
.arg(errorColumn) );

#ifdef QGISDEBUG
qWarning("errormessage is: "+errormsg);
qWarning("DOM Exception: "+mError);
#endif

return FALSE;
}

QDomElement docElem = capabilitiesDOM.documentElement();

// TODO: Assert the docElem.tagName() is "WMS_Capabilities"
@@ -613,6 +649,8 @@ void QgsWmsProvider::parseCapabilities(QByteArray const & xml, QgsWmsCapabiliti
#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::parseCapabilities: exiting." << std::endl;
#endif

return TRUE;
}


@@ -1172,24 +1210,32 @@ void QgsWmsProvider::parseLayer(QDomElement const & e, QgsWmsLayerProperty& laye
{
parseKeywordList(e1, layerProperty.keywordList);
}
else if (
(e1.tagName() == "CRS") ||
(e1.tagName() == "SRS") // legacy from earlier versions of WMS
)
else if (e1.tagName() == "CRS")
{
layerProperty.crs.push_back(e1.text());
}
else if (e1.tagName() == "SRS") // legacy from earlier versions of WMS
{
// SRS can contain several definitions separated by whitespace
QStringList srsList = e1.text().split(QRegExp("\\s+"));

QStringList::const_iterator i;
for (i = srsList.constBegin(); i != srsList.constEnd(); ++i)
{
layerProperty.crs.push_back(*i);
}
}
else if (
(e1.tagName() == "EX_GeographicBoundingBox") ||
(e1.tagName() == "LatLonBoundingBox") // legacy from earlier versions of WMS
)
{

// std::cout << " LLBB is: '" << e1.attribute("minx") << "'." << std::endl;
// std::cout << " LLBB is: '" << e1.attribute("miny") << "'." << std::endl;
// std::cout << " LLBB is: '" << e1.attribute("maxx") << "'." << std::endl;
// std::cout << " LLBB is: '" << e1.attribute("maxy") << "'." << std::endl;

layerProperty.ex_GeographicBoundingBox = QgsRect(
e1.attribute("minx").toDouble(),
e1.attribute("miny").toDouble(),
@@ -1272,18 +1318,25 @@ void QgsWmsProvider::parseLayer(QDomElement const & e, QgsWmsLayerProperty& laye
extentForLayer[ layerProperty.name ] = layerProperty.ex_GeographicBoundingBox;

// see if we can refine the bounding box with the CRS-specific bounding boxes
if ( layerProperty.crs.size() > 0 )
for ( int i = 0; i < layerProperty.boundingBox.size(); i++ )
{
for ( int i = 0; i < layerProperty.boundingBox.size(); i++ )
{
if ( layerProperty.boundingBox[i].crs == DEFAULT_LATLON_CRS )
{
extentForLayer[ layerProperty.name ] =
layerProperty.boundingBox[i].box;
}
}
#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::parseLayer: testing bounding box CRS which is "
<< layerProperty.boundingBox[i].crs.toLocal8Bit().data() << "." << std::endl;
#endif
if ( layerProperty.boundingBox[i].crs == DEFAULT_LATLON_CRS )
{
extentForLayer[ layerProperty.name ] =
layerProperty.boundingBox[i].box;
}
}

#ifdef QGISDEBUG
std::cout << "QgsWmsProvider::parseLayer: extent for "
<< layerProperty.name.toLocal8Bit().data() << " is "
<< extentForLayer[ layerProperty.name ].stringRep(3).toLocal8Bit().data() << "." << std::endl;
#endif

// Insert into the local class' registry
layersSupported.push_back(layerProperty);
}
@@ -1361,11 +1414,6 @@ int QgsWmsProvider::capabilities() const

void QgsWmsProvider::showStatusMessage(QString const & theMessage)
{

#ifdef QGISDEBUG
// std::cout << "QgsWmsProvider::showStatusMessage: entered with '" << theMessage << "'." << std::endl;
#endif

// Pass-through
// TODO: See if we can connect signal-to-signal. This is a kludge according to the Qt doc.
emit setStatus(theMessage);
@@ -1379,6 +1427,9 @@ void QgsWmsProvider::calculateExtent()
std::cout << "QgsWmsProvider::calculateExtent: entered." << std::endl;
#endif

// Make sure we know what extents are available
retrieveServerCapabilities();

for ( QStringList::Iterator it = activeSubLayers.begin();
it != activeSubLayers.end();
++it )

0 comments on commit 90f2f9b

Please sign in to comment.