Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL WMTS driver 4 : * Purpose: Implement GDAL WMTS support 5 : * Author: Even Rouault, <even dot rouault at spatialys dot com> 6 : * Funded by Land Information New Zealand (LINZ) 7 : * 8 : ********************************************************************** 9 : * Copyright (c) 2015, Even Rouault <even dot rouault at spatialys dot com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "wmtsdrivercore.h" 15 : 16 : /************************************************************************/ 17 : /* WMTSDriverIdentify() */ 18 : /************************************************************************/ 19 : 20 52444 : int WMTSDriverIdentify(GDALOpenInfo *poOpenInfo) 21 : 22 : { 23 52444 : if (STARTS_WITH_CI(poOpenInfo->pszFilename, "WMTS:")) 24 112 : return TRUE; 25 : 26 52332 : if (STARTS_WITH_CI(poOpenInfo->pszFilename, "<GDAL_WMTS")) 27 8 : return TRUE; 28 : 29 52324 : const bool bIsSingleDriver = poOpenInfo->IsSingleAllowedDriver("WMTS"); 30 52320 : if (bIsSingleDriver && (STARTS_WITH(poOpenInfo->pszFilename, "http://") || 31 25 : STARTS_WITH(poOpenInfo->pszFilename, "https://"))) 32 : { 33 3 : return true; 34 : } 35 : 36 52317 : if (poOpenInfo->nHeaderBytes == 0) 37 48112 : return FALSE; 38 : 39 4205 : const char *pszHeader = 40 : reinterpret_cast<const char *>(poOpenInfo->pabyHeader); 41 4205 : if (strstr(pszHeader, "<GDAL_WMTS") || 42 4198 : ((strstr(pszHeader, "<Capabilities") || 43 4192 : strstr(pszHeader, "<wmts:Capabilities")) && 44 6 : strstr(pszHeader, "http://www.opengis.net/wmts/1.0"))) 45 : { 46 12 : return TRUE; 47 : } 48 : 49 4193 : if (bIsSingleDriver) 50 : { 51 5 : while (*pszHeader != 0 && 52 4 : std::isspace(static_cast<unsigned char>(*pszHeader))) 53 0 : ++pszHeader; 54 5 : return *pszHeader == '<'; 55 : } 56 : 57 4188 : return FALSE; 58 : } 59 : 60 : /************************************************************************/ 61 : /* WMTSDriverSetCommonMetadata() */ 62 : /************************************************************************/ 63 : 64 1293 : void WMTSDriverSetCommonMetadata(GDALDriver *poDriver) 65 : { 66 1293 : poDriver->SetDescription(DRIVER_NAME); 67 1293 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 68 1293 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "OGC Web Map Tile Service"); 69 1293 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/wmts.html"); 70 : 71 1293 : poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "WMTS:"); 72 : 73 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 74 : 75 1293 : poDriver->SetMetadataItem( 76 : GDAL_DMD_OPENOPTIONLIST, 77 : "<OpenOptionList>" 78 : " <Option name='URL' type='string' description='URL that points to " 79 : "GetCapabilities response' required='YES'/>" 80 : " <Option name='LAYER' type='string' description='Layer identifier'/>" 81 : " <Option name='TILEMATRIXSET' alias='TMS' type='string' " 82 : "description='Tile matrix set identifier'/>" 83 : " <Option name='TILEMATRIX' type='string' description='Tile matrix " 84 : "identifier of maximum zoom level. Exclusive with ZOOM_LEVEL.'/>" 85 : " <Option name='ZOOM_LEVEL' alias='ZOOMLEVEL' type='int' " 86 : "description='Maximum zoom level. Exclusive with TILEMATRIX.'/>" 87 : " <Option name='STYLE' type='string' description='Style identifier'/>" 88 : " <Option name='EXTENDBEYONDDATELINE' type='boolean' " 89 : "description='Whether to enable extend-beyond-dateline behaviour' " 90 : "default='NO'/>" 91 : " <Option name='EXTENT_METHOD' type='string-select' description='How " 92 : "the raster extent is computed' default='AUTO'>" 93 : " <Value>AUTO</Value>" 94 : " <Value>LAYER_BBOX</Value>" 95 : " <Value>TILE_MATRIX_SET</Value>" 96 : " <Value>MOST_PRECISE_TILE_MATRIX</Value>" 97 : " </Option>" 98 : " <Option name='CLIP_EXTENT_WITH_MOST_PRECISE_TILE_MATRIX' " 99 : "type='boolean' description='Whether to use the implied bounds of the " 100 : "most precise tile matrix to clip the layer extent (defaults to NO if " 101 : "layer bounding box is used, YES otherwise)'/>" 102 : " <Option name='CLIP_EXTENT_WITH_MOST_PRECISE_TILE_MATRIX_LIMITS' " 103 : "type='boolean' description='Whether to use the implied bounds of the " 104 : "most precise tile matrix limits to clip the layer extent (defaults to " 105 : "NO if layer bounding box is used, YES otherwise)'/>" 106 1293 : "</OpenOptionList>"); 107 : 108 1293 : poDriver->pfnIdentify = WMTSDriverIdentify; 109 1293 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 110 1293 : poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); 111 1293 : } 112 : 113 : /************************************************************************/ 114 : /* DeclareDeferredWMTSPlugin() */ 115 : /************************************************************************/ 116 : 117 : #ifdef PLUGIN_FILENAME 118 : void DeclareDeferredWMTSPlugin() 119 : { 120 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 121 : { 122 : return; 123 : } 124 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 125 : #ifdef PLUGIN_INSTALLATION_MESSAGE 126 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 127 : PLUGIN_INSTALLATION_MESSAGE); 128 : #endif 129 : WMTSDriverSetCommonMetadata(poDriver); 130 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 131 : } 132 : #endif