Line data Source code
1 : /****************************************************************************** 2 : * Project: OGR 3 : * Purpose: OGRGMLASDriver implementation 4 : * Author: Even Rouault, <even dot rouault at spatialys dot com> 5 : * 6 : * Initial development funded by the European Earth observation programme 7 : * Copernicus 8 : * 9 : ****************************************************************************** 10 : * Copyright (c) 2016, Even Rouault, <even dot rouault at spatialys dot com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #include "gdal_frmts.h" 16 : #include "gdalplugindriverproxy.h" 17 : 18 : #include "ogrsf_frmts.h" 19 : 20 : #include "ogrgmlasdrivercore.h" 21 : #include "ogr_gmlas_consts.h" 22 : 23 : /************************************************************************/ 24 : /* OGRGMLASDriverIdentify() */ 25 : /************************************************************************/ 26 : 27 53003 : int OGRGMLASDriverIdentify(GDALOpenInfo *poOpenInfo) 28 : 29 : { 30 53003 : if (STARTS_WITH_CI(poOpenInfo->pszFilename, "GMLAS:")) 31 368 : return true; 32 : 33 52635 : if (poOpenInfo->IsSingleAllowedDriver("GMLAS")) 34 : { 35 2 : const char *pszPtr = 36 : reinterpret_cast<const char *>(poOpenInfo->pabyHeader); 37 : 38 : // Skip UTF-8 BOM 39 2 : if (poOpenInfo->nHeaderBytes > 3 && 40 2 : memcmp(poOpenInfo->pabyHeader, "\xEF\xBB\xBF", 3) == 0) 41 : { 42 0 : pszPtr += 3; 43 : } 44 : 45 : // Skip spaces 46 2 : while (*pszPtr && std::isspace(static_cast<unsigned char>(*pszPtr))) 47 0 : ++pszPtr; 48 : 49 : // Here, we expect the opening chevrons of GML tree root element */ 50 2 : return pszPtr[0] == '<'; 51 : } 52 : 53 52633 : return false; 54 : } 55 : 56 : /************************************************************************/ 57 : /* OGRGMLASDriverSetCommonMetadata() */ 58 : /************************************************************************/ 59 : 60 1755 : void OGRGMLASDriverSetCommonMetadata(GDALDriver *poDriver) 61 : { 62 1755 : poDriver->SetDescription(DRIVER_NAME); 63 1755 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 64 1755 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, 65 : "Geography Markup Language (GML) " 66 1755 : "driven by application schemas"); 67 1755 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "gml xml"); 68 1755 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/gmlas.html"); 69 : 70 1755 : poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, szGMLAS_PREFIX); 71 1755 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 72 : 73 1755 : poDriver->SetMetadataItem( 74 : GDAL_DMD_OPENOPTIONLIST, 75 : "<OpenOptionList>" 76 : " <Option name='XSD' type='string' description='Space separated list " 77 : "of " 78 : "filenames of XML schemas that apply to the data file'/>" 79 : " <Option name='CONFIG_FILE' type='string' " 80 : "description='Filename of the configuration file'/>" 81 : " <Option name='EXPOSE_METADATA_LAYERS' type='boolean' " 82 : "description='Whether metadata layers should be reported by default.' " 83 : "default='NO'/>" 84 : " <Option name='SCHEMA_FULL_CHECKING' type='boolean' description=" 85 : "'Whether the full schema constraint checking should be enabled.' " 86 : "default='YES'/>" 87 : " <Option name='HANDLE_MULTIPLE_IMPORTS' type='boolean' " 88 : "description='Whether " 89 : "multiple imports of the same namespace can be done.' default='NO'/>" 90 : " <Option name='VALIDATE' type='boolean' description='Whether " 91 : "validation " 92 : "against the schema should be done' default='NO'/>" 93 : " <Option name='FAIL_IF_VALIDATION_ERROR' type='boolean' " 94 : "description='Whether a validation error should cause dataset opening " 95 : "to fail' " 96 : "default='NO'/>" 97 : " <Option name='REFRESH_CACHE' type='boolean' " 98 : "description='Whether remote schemas and resolved xlink resources " 99 : "should " 100 : "be downloaded from the server' " 101 : "default='NO'/>" 102 : " <Option name='SWAP_COORDINATES' type='string-select' " 103 : "description='Whether the order of geometry coordinates should be " 104 : "inverted.' " 105 : "default='AUTO'>" 106 : " <Value>AUTO</Value>" 107 : " <Value>YES</Value>" 108 : " <Value>NO</Value>" 109 : " </Option>" 110 : " <Option name='REMOVE_UNUSED_LAYERS' type='boolean' " 111 : "description='Whether unused layers should be removed' " 112 : "default='NO'/>" 113 : " <Option name='REMOVE_UNUSED_FIELDS' type='boolean' " 114 : "description='Whether unused fields should be removed' " 115 : "default='NO'/>" 116 1755 : "</OpenOptionList>"); 117 : 118 1755 : poDriver->SetMetadataItem( 119 : GDAL_DMD_CREATIONOPTIONLIST, 120 3510 : (CPLString("<CreationOptionList>") + " <Option name='" + 121 3510 : szINPUT_XSD_OPTION + 122 : "' type='string' description='" 123 : "Space separated list of filenames of XML schemas that apply to the " 124 : "data file'/>" 125 3510 : " <Option name='" + 126 3510 : szCONFIG_FILE_OPTION + 127 : "' type='string' " 128 : "description='Filename of the configuration file'/>" 129 3510 : " <Option name='" + 130 3510 : szLAYERS_OPTION + 131 : "' type='string' " 132 : "description='Comma separated list of layer names to export'/>" 133 3510 : " <Option name='" + 134 3510 : szSRSNAME_FORMAT_OPTION + 135 : "' type='string-select' " 136 : "description='Format of srsName' " 137 3510 : "default='" + 138 3510 : szSRSNAME_DEFAULT + 139 : "'>" 140 3510 : " <Value>" + 141 3510 : szSHORT + 142 : "</Value>" 143 3510 : " <Value>" + 144 3510 : szOGC_URN + 145 : "</Value>" 146 3510 : " <Value>" + 147 3510 : szOGC_URL + 148 : "</Value>" 149 : " </Option>" 150 3510 : " <Option name='" + 151 3510 : szINDENT_SIZE_OPTION + 152 : "' type='int' min='0' max='8' " 153 : "description='Number of spaces for each indentation level' " 154 : "default='2'/>" 155 3510 : " <Option name='" + 156 3510 : szCOMMENT_OPTION + 157 : "' type='string' description='" 158 : "Comment to add at top of generated XML file'/>" 159 3510 : " <Option name='" + 160 3510 : szLINEFORMAT_OPTION + 161 : "' type='string-select' " 162 : "description='end-of-line sequence' " 163 : #ifdef _WIN32 164 : "default='" + 165 : szCRLF + 166 : "'>" 167 : #else 168 3510 : "default='" + 169 3510 : szLF + 170 : "'>" 171 : #endif 172 3510 : " <Value>" + 173 3510 : szCRLF + 174 : "</Value>" 175 3510 : " <Value>" + 176 3510 : szLF + 177 : "</Value>" 178 : " </Option>" 179 3510 : " <Option name='" + 180 3510 : szWRAPPING_OPTION + 181 : "' type='string-select' " 182 : "description='How to wrap features' " 183 3510 : "default='" + 184 3510 : szWFS2_FEATURECOLLECTION + 185 : "'>" 186 3510 : " <Value>" + 187 3510 : szWFS2_FEATURECOLLECTION + 188 : "</Value>" 189 3510 : " <Value>" + 190 3510 : szGMLAS_FEATURECOLLECTION + 191 : "</Value>" 192 : " </Option>" 193 3510 : " <Option name='" + 194 3510 : szTIMESTAMP_OPTION + 195 : "' type='string' " 196 : "description='User-specified XML " 197 : "dateTime value for timestamp to use in wfs:FeatureCollection " 198 : "attribute." 199 3510 : "Only valid for " + 200 3510 : szWRAPPING_OPTION + "=" + szWFS2_FEATURECOLLECTION + 201 : "'/>" 202 3510 : " <Option name='" + 203 3510 : szWFS20_SCHEMALOCATION_OPTION + 204 : "' type='string' " 205 3510 : "description='Path or URL to wfs.xsd. Only valid for " + 206 3510 : szWRAPPING_OPTION + "=" + szWFS2_FEATURECOLLECTION + 207 : "'/>" 208 3510 : " <Option name='" + 209 3510 : szGENERATE_XSD_OPTION + 210 : "' type='boolean' " 211 3510 : "description='Whether to generate a .xsd file. Only valid for " + 212 3510 : szWRAPPING_OPTION + "=" + szGMLAS_FEATURECOLLECTION + 213 : "' " 214 : "default='YES'/>" 215 3510 : " <Option name='" + 216 3510 : szOUTPUT_XSD_FILENAME_OPTION + 217 : "' type='string' " 218 : "description='Wrapping .xsd filename. If not specified, same " 219 3510 : "basename as output file with .xsd extension. Only valid for " + 220 3510 : szWRAPPING_OPTION + "=" + szGMLAS_FEATURECOLLECTION + 221 : "'/>" 222 : "</CreationOptionList>") 223 1755 : .c_str()); 224 : 225 1755 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 226 1755 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 227 : 228 1755 : poDriver->pfnIdentify = OGRGMLASDriverIdentify; 229 1755 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 230 1755 : poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); 231 1755 : } 232 : 233 : /************************************************************************/ 234 : /* DeclareDeferredOGRGMLASPlugin() */ 235 : /************************************************************************/ 236 : 237 : #ifdef PLUGIN_FILENAME 238 : void DeclareDeferredOGRGMLASPlugin() 239 : { 240 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 241 : { 242 : return; 243 : } 244 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 245 : #ifdef PLUGIN_INSTALLATION_MESSAGE 246 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 247 : PLUGIN_INSTALLATION_MESSAGE); 248 : #endif 249 : OGRGMLASDriverSetCommonMetadata(poDriver); 250 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 251 : } 252 : #endif