Ejemplo n.º 1
0
OGRESRIFeatureServiceDataset::OGRESRIFeatureServiceDataset(const CPLString &osURL,
                                                           OGRGeoJSONDataSource* poFirst)
{
    poCurrent = poFirst;
    poLayer = new OGRESRIFeatureServiceLayer(this);
    this->osURL = osURL;
    if( CPLURLGetValue(this->osURL, "resultRecordCount").size() == 0 )
    {
        // We assume that if the server sets the exceededTransferLimit, the
        // and resultRecordCount is not set, the number of features returned
        // in our first request is the maximum allowed by the server
        // So set it for following requests
        this->osURL = CPLURLAddKVP(this->osURL, "resultRecordCount",
                CPLSPrintf("%d", (int)poFirst->GetLayer(0)->GetFeatureCount()));
    }
    else
    {
        int nUserSetRecordCount = atoi(CPLURLGetValue(this->osURL, "resultRecordCount"));
        if( nUserSetRecordCount > poFirst->GetLayer(0)->GetFeatureCount() )
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Specificied resultRecordCount=%d is greater than the maximum %d supported by the server",
                     nUserSetRecordCount, (int)poFirst->GetLayer(0)->GetFeatureCount() );
        }
    }
    nFirstOffset = CPLAtoGIntBig(CPLURLGetValue(this->osURL, "resultOffset"));
    nLastOffset = nFirstOffset;
}
Ejemplo n.º 2
0
static GDALDataset* OGRGeoJSONDriverOpen( GDALOpenInfo* poOpenInfo )
{
    GeoJSONSourceType nSrcType;
    if( OGRGeoJSONDriverIdentifyInternal(poOpenInfo, nSrcType) == FALSE )
        return NULL;

    OGRGeoJSONDataSource* poDS
        = new OGRGeoJSONDataSource();

/* -------------------------------------------------------------------- */
/*      Processing configuration options.                               */
/* -------------------------------------------------------------------- */

    // TODO: Currently, options are based on environment variables.
    //       This is workaround for not yet implemented Andrey's concept
    //       described in document 'RFC 10: OGR Open Parameters'.

    poDS->SetGeometryTranslation( OGRGeoJSONDataSource::eGeometryPreserve );
    const char* pszOpt = CPLGetConfigOption("GEOMETRY_AS_COLLECTION", NULL);
    if( NULL != pszOpt && STARTS_WITH_CI(pszOpt, "YES") )
    {
            poDS->SetGeometryTranslation(
                OGRGeoJSONDataSource::eGeometryAsCollection );
    }

    poDS->SetAttributesTranslation( OGRGeoJSONDataSource::eAttributesPreserve );
    pszOpt = CPLGetConfigOption("ATTRIBUTES_SKIP", NULL);
    if( NULL != pszOpt && STARTS_WITH_CI(pszOpt, "YES") )
    {
        poDS->SetAttributesTranslation(
            OGRGeoJSONDataSource::eAttributesSkip );
    }

/* -------------------------------------------------------------------- */
/*      Open and start processing GeoJSON datasource to OGR objects.    */
/* -------------------------------------------------------------------- */
    if( !poDS->Open( poOpenInfo, nSrcType ) )
    {
        delete poDS;
        poDS = NULL;
    }

    if( poDS != NULL && poDS->HasOtherPages() )
    {
        const char* pszFSP = CSLFetchNameValue(poOpenInfo->papszOpenOptions,
                                               "FEATURE_SERVER_PAGING");
        bool bHasResultOffset = CPLURLGetValue( poOpenInfo->pszFilename,
                                                "resultOffset").size() > 0;
        if( (!bHasResultOffset && (pszFSP == NULL || CPLTestBool(pszFSP))) ||
            (bHasResultOffset && pszFSP != NULL && CPLTestBool(pszFSP)) )
        {
            return new OGRESRIFeatureServiceDataset(poOpenInfo->pszFilename,
                                                    poDS);
        }
    }

    return poDS;
}
Ejemplo n.º 3
0
static
CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo)
{
    const char* pszBaseURL = poOpenInfo->pszFilename;
    if (EQUALN(pszBaseURL, "WMS:", 4))
        pszBaseURL += 4;

    CPLString osLayer = CPLURLGetValue(pszBaseURL, "LAYERS");
    CPLString osVersion = CPLURLGetValue(pszBaseURL, "VERSION");
    CPLString osSRS = CPLURLGetValue(pszBaseURL, "SRS");
    CPLString osCRS = CPLURLGetValue(pszBaseURL, "CRS");
    CPLString osBBOX = CPLURLGetValue(pszBaseURL, "BBOX");
    CPLString osFormat = CPLURLGetValue(pszBaseURL, "FORMAT");
    CPLString osTransparent = CPLURLGetValue(pszBaseURL, "TRANSPARENT");

    /* GDAL specific extensions to alter the default settings */
    CPLString osOverviewCount = CPLURLGetValue(pszBaseURL, "OVERVIEWCOUNT");
    CPLString osTileSize = CPLURLGetValue(pszBaseURL, "TILESIZE");
    CPLString osMinResolution = CPLURLGetValue(pszBaseURL, "MINRESOLUTION");
    CPLString osBBOXOrder = CPLURLGetValue(pszBaseURL, "BBOXORDER");

    CPLString osBaseURL = pszBaseURL;
    /* Remove all keywords to get base URL */

    osBaseURL = CPLURLAddKVP(osBaseURL, "VERSION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "REQUEST", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "LAYERS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "SRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "CRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOX", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "FORMAT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TRANSPARENT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "STYLES", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "WIDTH", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "HEIGHT", NULL);

    osBaseURL = CPLURLAddKVP(osBaseURL, "OVERVIEWCOUNT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TILESIZE", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "MINRESOLUTION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOXORDER", NULL);

    if (osBaseURL.size() > 0 && osBaseURL[osBaseURL.size() - 1] == '&')
        osBaseURL.resize(osBaseURL.size() - 1);

    if (osVersion.size() == 0)
        osVersion = "1.1.1";

    CPLString osSRSTag;
    CPLString osSRSValue;
    if(VersionStringToInt(osVersion.c_str())>= VersionStringToInt("1.3.0"))
    {
        if (osSRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.3 and above expects CRS however SRS was set instead.");
        }
        osSRSValue = osCRS;
        osSRSTag = "CRS";
    }
    else
    {
        if (osCRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.1.1 and below expects SRS however CRS was set instead.");
        }
        osSRSValue = osSRS;
        osSRSTag = "SRS";
    }

    if (osSRSValue.size() == 0)
        osSRSValue = "EPSG:4326";
    
    if (osBBOX.size() == 0)
    {
        if (osBBOXOrder.compare("yxYX") == 0)
            osBBOX = "-90,-180,90,180";
        else
            osBBOX = "-180,-90,180,90";
    }

    char** papszTokens = CSLTokenizeStringComplex(osBBOX, ",", 0, 0);
    if (CSLCount(papszTokens) != 4)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }
    const char* pszMinX = papszTokens[0];
    const char* pszMinY = papszTokens[1];
    const char* pszMaxX = papszTokens[2];
    const char* pszMaxY = papszTokens[3];

    if (osBBOXOrder.compare("yxYX") == 0)
    {
        std::swap(pszMinX, pszMinY);
        std::swap(pszMaxX, pszMaxY);
    }

    double dfMinX = CPLAtofM(pszMinX);
    double dfMinY = CPLAtofM(pszMinY);
    double dfMaxX = CPLAtofM(pszMaxX);
    double dfMaxY = CPLAtofM(pszMaxY);

    if (dfMaxY <= dfMinY || dfMaxX <= dfMinX)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }

    int nTileSize = atoi(osTileSize);
    if (nTileSize <= 128 || nTileSize > 2048)
        nTileSize = 1024;

    int nXSize, nYSize;

    int nOverviewCount = (osOverviewCount.size()) ? atoi(osOverviewCount) : 20;

    if (osMinResolution.size() != 0)
    {
        double dfMinResolution = CPLAtofM(osMinResolution);

        while (nOverviewCount > 20)
        {
            nOverviewCount --;
            dfMinResolution *= 2;
        }

        nXSize = (int) ((dfMaxX - dfMinX) / dfMinResolution + 0.5);
        nYSize = (int) ((dfMaxY - dfMinY) / dfMinResolution + 0.5);
    }
    else
    {
        double dfRatio = (dfMaxX - dfMinX) / (dfMaxY - dfMinY);
        if (dfRatio > 1)
        {
            nXSize = nTileSize;
            nYSize = (int) (nXSize / dfRatio);
        }
        else
        {
            nYSize = nTileSize;
            nXSize = (int) (nYSize * dfRatio);
        }

        if (nOverviewCount < 0 || nOverviewCount > 20)
            nOverviewCount = 20;

        nXSize = nXSize * (1 << nOverviewCount);
        nYSize = nYSize * (1 << nOverviewCount);
    }

    int bTransparent = osTransparent.size() ? CSLTestBoolean(osTransparent) : FALSE;

    if (osFormat.size() == 0)
    {
        if (!bTransparent)
        {
            osFormat = "image/jpeg";
        }
        else
        {
            osFormat = "image/png";
        }
    }

    char* pszEscapedURL = CPLEscapeString(osBaseURL.c_str(), -1, CPLES_XML);
    char* pszEscapedLayerURL = CPLEscapeString(osLayer.c_str(), -1, CPLES_URL);
    char* pszEscapedLayerXML = CPLEscapeString(pszEscapedLayerURL, -1, CPLES_XML);

    CPLString osXML = CPLSPrintf(
            "<GDAL_WMS>\n"
            "  <Service name=\"WMS\">\n"
            "    <Version>%s</Version>\n"
            "    <ServerUrl>%s</ServerUrl>\n"
            "    <Layers>%s</Layers>\n"
            "    <%s>%s</%s>\n"
            "    <ImageFormat>%s</ImageFormat>\n"
            "    <Transparent>%s</Transparent>\n"
            "    <BBoxOrder>%s</BBoxOrder>\n"
            "  </Service>\n"
            "  <DataWindow>\n"
            "    <UpperLeftX>%s</UpperLeftX>\n"
            "    <UpperLeftY>%s</UpperLeftY>\n"
            "    <LowerRightX>%s</LowerRightX>\n"
            "    <LowerRightY>%s</LowerRightY>\n"
            "    <SizeX>%d</SizeX>\n"
            "    <SizeY>%d</SizeY>\n"
            "  </DataWindow>\n"
            "  <BandsCount>%d</BandsCount>\n"
            "  <BlockSizeX>%d</BlockSizeX>\n"
            "  <BlockSizeY>%d</BlockSizeY>\n"
            "  <OverviewCount>%d</OverviewCount>\n"
            "</GDAL_WMS>\n",
            osVersion.c_str(),
            pszEscapedURL,
            pszEscapedLayerXML,
            osSRSTag.c_str(),
            osSRSValue.c_str(),
            osSRSTag.c_str(),
            osFormat.c_str(),
            (bTransparent) ? "TRUE" : "FALSE",
            (osBBOXOrder.size()) ? osBBOXOrder.c_str() : "xyXY",
            pszMinX, pszMaxY, pszMaxX, pszMinY,
            nXSize, nYSize,
            (bTransparent) ? 4 : 3,
            nTileSize, nTileSize,
            nOverviewCount);

    CPLFree(pszEscapedURL);
    CPLFree(pszEscapedLayerURL);
    CPLFree(pszEscapedLayerXML);

    CSLDestroy(papszTokens);

    CPLDebug("WMS", "Opening WMS :\n%s", osXML.c_str());

    return CPLParseXMLString(osXML);
}
Ejemplo n.º 4
0
GDALDataset *GDALWMSDataset::Open(GDALOpenInfo *poOpenInfo)
{
    CPLXMLNode *config = NULL;
    CPLErr ret = CE_None;

    const char* pszFilename = poOpenInfo->pszFilename;
    const char* pabyHeader = (const char *) poOpenInfo->pabyHeader;

    if (poOpenInfo->nHeaderBytes == 0 &&
        EQUALN(pszFilename, "<GDAL_WMS>", 10))
    {
        config = CPLParseXMLString(pszFilename);
    }
    else if (poOpenInfo->nHeaderBytes >= 10 &&
             EQUALN(pabyHeader, "<GDAL_WMS>", 10))
    {
        config = CPLParseXMLFile(pszFilename);
    }
    else if (poOpenInfo->nHeaderBytes == 0 &&
             (EQUALN(pszFilename, "WMS:http", 8) ||
              EQUALN(pszFilename, "http", 4)) &&
             strstr(pszFilename, "/MapServer?f=json") != NULL)
    {
        if (EQUALN(pszFilename, "WMS:http", 8))
            pszFilename += 4;
        CPLString osURL(pszFilename);
        if (strstr(pszFilename, "&pretty=true") == NULL)
            osURL += "&pretty=true";
        CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL);
        if (psResult == NULL)
            return NULL;
        if (psResult->pabyData == NULL)
        {
            CPLHTTPDestroyResult(psResult);
            return NULL;
        }
        config = GDALWMSDatasetGetConfigFromArcGISJSON(osURL,
                                                       (const char*)psResult->pabyData);
        CPLHTTPDestroyResult(psResult);
    }

    else if (poOpenInfo->nHeaderBytes == 0 &&
             (EQUALN(pszFilename, "WMS:", 4) ||
              CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos))
    {
        CPLString osLayers = CPLURLGetValue(pszFilename, "LAYERS");
        CPLString osRequest = CPLURLGetValue(pszFilename, "REQUEST");
        if (osLayers.size() != 0)
            config = GDALWMSDatasetGetConfigFromURL(poOpenInfo);
        else if (EQUAL(osRequest, "GetTileService"))
            return GDALWMSMetaDataset::DownloadGetTileService(poOpenInfo);
        else
            return GDALWMSMetaDataset::DownloadGetCapabilities(poOpenInfo);
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             (strstr(pabyHeader, "<WMT_MS_Capabilities") != NULL ||
              strstr(pabyHeader, "<WMS_Capabilities") != NULL ||
              strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != NULL))
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetCapabilities(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<WMS_Tile_Service") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetTileService(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        config = GDALWMSDatasetGetConfigFromTileMap(psXML);
        CPLDestroyXMLNode( psXML );
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<Services") != NULL &&
             strstr(pabyHeader, "<TileMapService version=\"1.0") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        CPLXMLNode* psRoot = CPLGetXMLNode( psXML, "=Services" );
        GDALDataset* poRet = NULL;
        if (psRoot)
        {
            CPLXMLNode* psTileMapService = CPLGetXMLNode(psRoot, "TileMapService");
            if (psTileMapService)
            {
                const char* pszHref = CPLGetXMLValue(psTileMapService, "href", NULL);
                if (pszHref)
                {
                    poRet = (GDALDataset*) GDALOpen(pszHref, GA_ReadOnly);
                }
            }
        }
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeTileMapService(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else
        return NULL;
    if (config == NULL) return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLDestroyXMLNode(config);
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The WMS driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    GDALWMSDataset *ds = new GDALWMSDataset();
    ret = ds->Initialize(config);
    if (ret != CE_None) {
        delete ds;
        ds = NULL;
    }
    CPLDestroyXMLNode(config);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    if (ds != NULL)
    {
        ds->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );
        ds->SetDescription( poOpenInfo->pszFilename );
        ds->TryLoadXML();
    }

    return ds;
}
Ejemplo n.º 5
0
GDALDataset *GDALWMSDataset::Open(GDALOpenInfo *poOpenInfo)
{
    CPLXMLNode *config = NULL;
    CPLErr ret = CE_None;

    const char* pszFilename = poOpenInfo->pszFilename;
    const char* pabyHeader = (const char *) poOpenInfo->pabyHeader;

    if (poOpenInfo->nHeaderBytes == 0 &&
        EQUALN(pszFilename, "<GDAL_WMS>", 10))
    {
        config = CPLParseXMLString(pszFilename);
    }
    else if (poOpenInfo->nHeaderBytes >= 10 &&
             EQUALN(pabyHeader, "<GDAL_WMS>", 10))
    {
        config = CPLParseXMLFile(pszFilename);
    }
    else if (poOpenInfo->nHeaderBytes == 0 &&
             (EQUALN(pszFilename, "WMS:http", 8) ||
              EQUALN(pszFilename, "http", 4)) &&
             strstr(pszFilename, "/MapServer?f=json") != NULL)
    {
        if (EQUALN(pszFilename, "WMS:http", 8))
            pszFilename += 4;
        CPLString osURL(pszFilename);
        if (strstr(pszFilename, "&pretty=true") == NULL)
            osURL += "&pretty=true";
        CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL);
        if (psResult == NULL)
            return NULL;
        if (psResult->pabyData == NULL)
        {
            CPLHTTPDestroyResult(psResult);
            return NULL;
        }
        config = GDALWMSDatasetGetConfigFromArcGISJSON(osURL,
                                                       (const char*)psResult->pabyData);
        CPLHTTPDestroyResult(psResult);
    }

    else if (poOpenInfo->nHeaderBytes == 0 &&
             (EQUALN(pszFilename, "WMS:", 4) ||
              CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos))
    {
        CPLString osLayers = CPLURLGetValue(pszFilename, "LAYERS");
        CPLString osRequest = CPLURLGetValue(pszFilename, "REQUEST");
        if (osLayers.size() != 0)
            config = GDALWMSDatasetGetConfigFromURL(poOpenInfo);
        else if (EQUAL(osRequest, "GetTileService"))
            return GDALWMSMetaDataset::DownloadGetTileService(poOpenInfo);
        else
            return GDALWMSMetaDataset::DownloadGetCapabilities(poOpenInfo);
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             (strstr(pabyHeader, "<WMT_MS_Capabilities") != NULL ||
              strstr(pabyHeader, "<WMS_Capabilities") != NULL ||
              strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != NULL))
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetCapabilities(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<WMS_Tile_Service") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetTileService(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        config = GDALWMSDatasetGetConfigFromTileMap(psXML);
        CPLDestroyXMLNode( psXML );
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<Services") != NULL &&
             strstr(pabyHeader, "<TileMapService version=\"1.0") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        CPLXMLNode* psRoot = CPLGetXMLNode( psXML, "=Services" );
        GDALDataset* poRet = NULL;
        if (psRoot)
        {
            CPLXMLNode* psTileMapService = CPLGetXMLNode(psRoot, "TileMapService");
            if (psTileMapService)
            {
                const char* pszHref = CPLGetXMLValue(psTileMapService, "href", NULL);
                if (pszHref)
                {
                    poRet = (GDALDataset*) GDALOpen(pszHref, GA_ReadOnly);
                }
            }
        }
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes != 0 &&
             strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != NULL)
    {
        CPLXMLNode* psXML = CPLParseXMLFile(pszFilename);
        if (psXML == NULL)
            return NULL;
        GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeTileMapService(psXML);
        CPLDestroyXMLNode( psXML );
        return poRet;
    }
    else if (poOpenInfo->nHeaderBytes == 0 &&
              EQUALN(pszFilename, "AGS:", 4))
    {
		return NULL;
    }
    else if (poOpenInfo->nHeaderBytes == 0 &&
              EQUALN(pszFilename, "IIP:", 4))
    {
        CPLString osURL(pszFilename + 4);
        osURL += "&obj=Basic-Info";
        CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL);
        if (psResult == NULL)
            return NULL;
        if (psResult->pabyData == NULL)
        {
            CPLHTTPDestroyResult(psResult);
            return NULL;
        }
        int nXSize, nYSize;
        const char* pszMaxSize = strstr((const char*)psResult->pabyData, "Max-size:");
        const char* pszResolutionNumber = strstr((const char*)psResult->pabyData, "Resolution-number:");
        if( pszMaxSize &&
            sscanf(pszMaxSize + strlen("Max-size:"), "%d %d", &nXSize, &nYSize) == 2 &&
            pszResolutionNumber )
        {
            int nResolutions = atoi(pszResolutionNumber + strlen("Resolution-number:"));
            char* pszEscapedURL = CPLEscapeString(pszFilename + 4, -1, CPLES_XML);
            CPLString osXML = CPLSPrintf(
            "<GDAL_WMS>"
            "    <Service name=\"IIP\">"
            "        <ServerUrl>%s</ServerUrl>"
            "    </Service>"
            "    <DataWindow>"
            "        <SizeX>%d</SizeX>"
            "        <SizeY>%d</SizeY>"
            "        <TileLevel>%d</TileLevel>"
            "    </DataWindow>"
            "    <BlockSizeX>256</BlockSizeX>"
            "    <BlockSizeY>256</BlockSizeY>"
            "    <BandsCount>3</BandsCount>"
            "    <Cache />"
            "</GDAL_WMS>",
                pszEscapedURL,
                nXSize, nYSize, nResolutions - 1);
            config = CPLParseXMLString(osXML);
            CPLFree(pszEscapedURL);
        }
        CPLHTTPDestroyResult(psResult);
    }
    else
        return NULL;
    if (config == NULL) return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLDestroyXMLNode(config);
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The WMS poDriver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    GDALWMSDataset *ds = new GDALWMSDataset();
    ret = ds->Initialize(config);
    if (ret != CE_None) {
        delete ds;
        ds = NULL;
    }
    CPLDestroyXMLNode(config);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    if (ds != NULL)
    {
        ds->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );
        ds->SetDescription( poOpenInfo->pszFilename );
        ds->TryLoadXML();
    }

    return ds;
}