?? qgswmsprovider.cpp
字號:
/*************************************************************************** qgswmsprovider.cpp - QGIS Data provider for OGC Web Map Service layers ------------------- begin : 17 Mar, 2005 copyright : (C) 2005 by Brendan Morley email : morb at ozemail dot com dot au ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//* $Id: qgswmsprovider.cpp 7349 2007-11-07 14:18:34Z jef $ */#include "qgslogger.h"#include "qgswmsprovider.h"#include <math.h>#include "qgscoordinatetransform.h"#include "qgsrect.h"#include "qgsspatialrefsys.h"#include "qgshttptransaction.h"#include <QUrl>#include <QImage>#include <QSet>#ifdef _MSC_VER#include <float.h>#define isfinite(x) _finite(x)#endif#ifdef QGISDEBUG#include <QFile>#endifstatic QString WMS_KEY = "wms";static QString WMS_DESCRIPTION = "OGC Web Map Service version 1.3 data provider";static QString DEFAULT_LATLON_CRS = "CRS:84";QgsWmsProvider::QgsWmsProvider(QString const & uri) : QgsRasterDataProvider(uri), httpuri(uri), mHttpProxyHost(0), mHttpProxyPort(80), mHttpProxyUser(0), mHttpProxyPass(0), httpcapabilitiesresponse(0), imageCrs(DEFAULT_LATLON_CRS), cachedImage(0), cachedViewExtent(0), cachedPixelWidth(0), cachedPixelHeight(0), mCoordinateTransform(0), extentDirty(TRUE), mGetFeatureInfoUrlBase(0){ QgsDebugMsg("QgsWmsProvider: constructing with uri '" + uri + "'."); // assume this is a valid layer until we determine otherwise valid = true; // URL can be in 3 forms: // 1) http://xxx.xxx.xx/yyy/yyy // 2) http://xxx.xxx.xx/yyy/yyy? // 3) http://xxx.xxx.xx/yyy/yyy?zzz=www // Prepare the URI so that we can later simply append param=value baseUrl = httpuri; if ( !(baseUrl.contains("?")) ) { baseUrl.append("?"); } else if ( (baseUrl.right(1) != "?" ) && (baseUrl.right(1) != "&" ) ) { baseUrl.append("&"); } QgsDebugMsg("baseUrl = " + baseUrl );// 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"; //httpuri = "http://www.ga.gov.au/bin/getmap.pl?dataset=national&"; /* // 302-redirects to: uri = "http://www.ga.gov.au/bin/mapserv40?" "map=/public/http/www/docs/map/national/national.map&" "map_logo_status=off&map_coast_status=off&Service=WMS&Version=1.1.0&" "Request=GetMap&BBox=130,-40,160,-10&SRS=EPSG:4326&Width=800&" "Height=800&Layers=railways&Format=image/png";*/ // downloadMapURI(uri); QgsDebugMsg("QgsWmsProvider: exiting constructor.");}QgsWmsProvider::~QgsWmsProvider(){ QgsDebugMsg("QgsWmsProvider: deconstructing."); // Dispose of any cached image as created by draw() if (cachedImage) { delete cachedImage; } if (mCoordinateTransform) { delete mCoordinateTransform; }}QString QgsWmsProvider::proxyHost() const{ return mHttpProxyHost;}int QgsWmsProvider::proxyPort() const{ return mHttpProxyPort;}QString QgsWmsProvider::proxyUser() const{ return mHttpProxyUser;}QString QgsWmsProvider::proxyPass() const{ return mHttpProxyPass;}bool QgsWmsProvider::setProxy(QString const & host, int port, QString const & user, QString const & pass){ mHttpProxyHost = host; mHttpProxyPort = port; mHttpProxyUser = user; mHttpProxyPass = pass; return TRUE;}bool QgsWmsProvider::supportedLayers(std::vector<QgsWmsLayerProperty> & layers){ QgsDebugMsg("Entering."); // Allow the provider to collect the capabilities first. if (!retrieveServerCapabilities()) { return FALSE; } layers = layersSupported; QgsDebugMsg("Exiting."); return TRUE;}QSet<QString> QgsWmsProvider::supportedCrsForLayers(QStringList const & layers){ QSet<QString> crsCandidates; QStringList::const_iterator i; for (i = layers.constBegin(); i != layers.constEnd(); ++i) { std::vector<QString> crsVector = crsForLayer[*i]; QSet<QString> crsSet; // convert std::vector to std::set for set comparisons for (uint j = 0; j < crsVector.size(); j++) { crsSet.insert( crsVector[j] ); } // first time through? if ( i == layers.constBegin() ) { // do initial population of set crsCandidates = crsSet; } else { // do lowest common denominator (set intersection) crsCandidates.intersect(crsSet); } } return crsCandidates;}size_t QgsWmsProvider::layerCount() const{ return 1; // XXX properly return actual number of layers} // QgsWmsProvider::layerCount()void QgsWmsProvider::addLayers(QStringList const & layers, QStringList const & styles){ QgsDebugMsg("Entering with layer list of " + layers.join(", ") + " and style list of " + styles.join(", ") ); // TODO: Make activeSubLayers a std::map in order to avoid duplicates activeSubLayers += layers; activeSubStyles += styles; // Set the visibility of these new layers on by default for ( QStringList::const_iterator it = layers.begin(); it != layers.end(); ++it ) { activeSubLayerVisibility[*it] = TRUE; QgsDebugMsg("set visibility of layer '" + (*it) + "' to TRUE."); } // now that the layers have changed, the extent will as well. extentDirty = TRUE; QgsDebugMsg("Exiting.");} void QgsWmsProvider::setLayerOrder(QStringList const & layers){ QgsDebugMsg("Entering."); activeSubLayers = layers; QgsDebugMsg("Exiting.");}void QgsWmsProvider::setSubLayerVisibility(QString const & name, bool vis){ activeSubLayerVisibility[name] = vis;}QString QgsWmsProvider::imageEncoding() const{ return imageMimeType;}void QgsWmsProvider::setImageEncoding(QString const & mimeType){ QgsDebugMsg("Setting image encoding to " + mimeType + ".") imageMimeType = mimeType;}void QgsWmsProvider::setImageCrs(QString const & crs){ QgsDebugMsg("Setting image CRS to " + crs + "."); if ( (crs != imageCrs) && (! crs.isEmpty() ) ) { // delete old coordinate transform as it is no longer valid if (mCoordinateTransform) { delete mCoordinateTransform; } extentDirty = TRUE; imageCrs = crs; }}QImage* QgsWmsProvider::draw(QgsRect const & viewExtent, int pixelWidth, int pixelHeight){ QgsDebugMsg("Entering."); QgsDebugMsg("pixelWidth = " + QString(pixelWidth) ); QgsDebugMsg("pixelHeight = " + QString(pixelHeight) );#ifdef QGISDEBUG QgsLogger::debug<QgsRect>("viewExtent: ", viewExtent, __FILE__, __FUNCTION__, __LINE__);#endif // Can we reuse the previously cached image? if ( (cachedImage) && (cachedViewExtent == viewExtent) && (cachedPixelWidth == pixelWidth) && (cachedPixelHeight == pixelHeight) ) { return cachedImage; } // Bounding box in WMS format QString bbox; // Warning: does not work with scientific notation bbox = QString("%1,%2,%3,%4"). arg(viewExtent.xMin(),0,'f'). arg(viewExtent.yMin(),0,'f'). arg(viewExtent.xMax(),0,'f'). arg(viewExtent.yMax(),0,'f'); // Width in WMS format QString width; width = width.setNum(pixelWidth); // Height in WMS format QString height; height = height.setNum(pixelHeight); // Calculate active layers that are also visible. QgsDebugMsg("Active layer list of " + activeSubLayers.join(", ") + " and style list of " + activeSubStyles.join(", ") ); QStringList visibleLayers = QStringList(); QStringList visibleStyles = QStringList(); QStringList::Iterator it2 = activeSubStyles.begin(); for ( QStringList::Iterator it = activeSubLayers.begin(); it != activeSubLayers.end(); ++it ) { if (TRUE == activeSubLayerVisibility.find( *it )->second) { visibleLayers += *it; visibleStyles += *it2; } ++it2; } QgsDebugMsg("Visible layer list of " + visibleLayers.join(", ") + " and style list of " + visibleStyles.join(", ") ); QString layers = QUrl::toPercentEncoding(visibleLayers.join(",")); QString styles = QUrl::toPercentEncoding(visibleStyles.join(",")); // compose the URL query string for the WMS server. QString url = baseUrl; url += "SERVICE=WMS"; url += "&"; url += "VERSION=" + mCapabilities.version; url += "&"; url += "REQUEST=GetMap"; url += "&"; url += "BBOX=" + bbox; url += "&"; url += "SRS=" + imageCrs; url += "&"; url += "WIDTH=" + width; url += "&"; url += "HEIGHT=" + height; url += "&"; url += "LAYERS=" + layers; url += "&"; url += "STYLES=" + styles; url += "&"; url += "FORMAT=" + imageMimeType; if(!imageMimeType.contains("jpeg", Qt::CaseInsensitive) && !imageMimeType.contains("jpg", Qt::CaseInsensitive)) //MH: jpeg does not support transparency and some servers complain if jpg and transparent=true { url += "&"; url += "TRANSPARENT=TRUE"; } qWarning(url); // cache some details for if the user wants to do an identifyAsHtml() later mGetFeatureInfoUrlBase = baseUrl; mGetFeatureInfoUrlBase += "SERVICE=WMS"; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "VERSION=" + mCapabilities.version; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "REQUEST=GetFeatureInfo"; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "BBOX=" + bbox; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "SRS=" + imageCrs; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "WIDTH=" + width; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "HEIGHT=" + height; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "LAYERS=" + layers; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "STYLES=" + styles; mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "FORMAT=" + imageMimeType; if(!imageMimeType.contains("jpeg", Qt::CaseInsensitive) && !imageMimeType.contains("jpg", Qt::CaseInsensitive)) { mGetFeatureInfoUrlBase += "&"; mGetFeatureInfoUrlBase += "TRANSPARENT=TRUE"; } QByteArray imagesource; imagesource = retrieveUrl(url); if (imagesource.isEmpty()) { return 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -