Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GPX Translator 4 : * Purpose: Implements OGRGPXDriver. 5 : * Author: Even Rouault, even dot rouault at spatialys.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2007-2008, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * Permission is hereby granted, free of charge, to any person obtaining a 11 : * copy of this software and associated documentation files (the "Software"), 12 : * to deal in the Software without restriction, including without limitation 13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 : * and/or sell copies of the Software, and to permit persons to whom the 15 : * Software is furnished to do so, subject to the following conditions: 16 : * 17 : * The above copyright notice and this permission notice shall be included 18 : * in all copies or substantial portions of the Software. 19 : * 20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 : * DEALINGS IN THE SOFTWARE. 27 : ****************************************************************************/ 28 : 29 : #include "cpl_port.h" 30 : #include "ogr_gpx.h" 31 : 32 : #include <cstring> 33 : 34 : #include "cpl_conv.h" 35 : #include "cpl_error.h" 36 : #include "cpl_vsi.h" 37 : #include "gdal.h" 38 : #include "gdal_priv.h" 39 : #include "ogr_core.h" 40 : 41 : /************************************************************************/ 42 : /* Identify() */ 43 : /************************************************************************/ 44 : 45 44883 : static int OGRGPXDriverIdentify(GDALOpenInfo *poOpenInfo) 46 : 47 : { 48 44883 : if (poOpenInfo->eAccess == GA_Update || poOpenInfo->fpL == nullptr) 49 41252 : return false; 50 : 51 3631 : return strstr(reinterpret_cast<const char *>(poOpenInfo->pabyHeader), 52 3631 : "<gpx") != nullptr; 53 : } 54 : 55 : /************************************************************************/ 56 : /* Open() */ 57 : /************************************************************************/ 58 : 59 29 : static GDALDataset *OGRGPXDriverOpen(GDALOpenInfo *poOpenInfo) 60 : 61 : { 62 29 : if (poOpenInfo->eAccess == GA_Update || !OGRGPXDriverIdentify(poOpenInfo)) 63 0 : return nullptr; 64 : 65 29 : OGRGPXDataSource *poDS = new OGRGPXDataSource(); 66 : 67 29 : if (!poDS->Open(poOpenInfo)) 68 : { 69 0 : delete poDS; 70 0 : poDS = nullptr; 71 : } 72 : 73 29 : return poDS; 74 : } 75 : 76 : /************************************************************************/ 77 : /* Create() */ 78 : /************************************************************************/ 79 : 80 : static GDALDataset * 81 25 : OGRGPXDriverCreate(const char *pszName, CPL_UNUSED int nBands, 82 : CPL_UNUSED int nXSize, CPL_UNUSED int nYSize, 83 : CPL_UNUSED GDALDataType eDT, CPL_UNUSED char **papszOptions) 84 : { 85 25 : OGRGPXDataSource *poDS = new OGRGPXDataSource(); 86 : 87 25 : if (!poDS->Create(pszName, papszOptions)) 88 : { 89 1 : delete poDS; 90 1 : poDS = nullptr; 91 : } 92 : 93 25 : return poDS; 94 : } 95 : 96 : /************************************************************************/ 97 : /* Delete() */ 98 : /************************************************************************/ 99 : 100 16 : static CPLErr OGRGPXDriverDelete(const char *pszFilename) 101 : 102 : { 103 16 : if (VSIUnlink(pszFilename) == 0) 104 16 : return CE_None; 105 : else 106 0 : return CE_Failure; 107 : } 108 : 109 : /************************************************************************/ 110 : /* RegisterOGRGPX() */ 111 : /************************************************************************/ 112 : 113 1520 : void RegisterOGRGPX() 114 : 115 : { 116 1520 : if (!GDAL_CHECK_VERSION("OGR/GPX driver")) 117 0 : return; 118 : 119 1520 : if (GDALGetDriverByName("GPX") != nullptr) 120 301 : return; 121 : 122 1219 : GDALDriver *poDriver = new GDALDriver(); 123 : 124 1219 : poDriver->SetDescription("GPX"); 125 1219 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 126 1219 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES"); 127 1219 : poDriver->SetMetadataItem(GDAL_DCAP_DELETE_LAYER, "YES"); 128 1219 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES"); 129 1219 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 130 1219 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "GPX"); 131 1219 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "gpx"); 132 1219 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/gpx.html"); 133 1219 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 134 : 135 1219 : poDriver->SetMetadataItem( 136 : GDAL_DMD_OPENOPTIONLIST, 137 : "<OpenOptionList>" 138 : " <Option name='N_MAX_LINKS' type='integer' default='2' " 139 : "description='Maximum number of links attributes'/>" 140 : " <Option name='ELE_AS_25D' type='boolean' default='NO' " 141 : "description='Whether to use the value of the ele element as the Z " 142 : "ordinate of geometries'/>" 143 : " <Option name='SHORT_NAMES' type='boolean' default='NO' " 144 : "description='Whether to use short field names (typically for " 145 : "shapefile compatibility'/>" 146 1219 : "</OpenOptionList>"); 147 : 148 1219 : poDriver->SetMetadataItem( 149 : GDAL_DMD_CREATIONOPTIONLIST, 150 : "<CreationOptionList>" 151 : #ifdef _WIN32 152 : " <Option name='LINEFORMAT' type='string-select' " 153 : "description='end-of-line sequence' default='CRLF'>" 154 : #else 155 : " <Option name='LINEFORMAT' type='string-select' " 156 : "description='end-of-line sequence' default='LF'>" 157 : #endif 158 : " <Value>CRLF</Value>" 159 : " <Value>LF</Value>" 160 : " </Option>" 161 : " <Option name='GPX_USE_EXTENSIONS' type='boolean' " 162 : "description='Whether to write non-GPX attributes in an " 163 : "<extensions> tag' default='NO'/>" 164 : " <Option name='GPX_EXTENSIONS_NS' type='string' " 165 : "description='Namespace value used for extension tags' default='ogr'/>" 166 : " <Option name='GPX_EXTENSIONS_NS_URL' type='string' " 167 : "description='Namespace URI' default='http://osgeo.org/gdal'/>" 168 : " <Option name='METADATA_AUTHOR_EMAIL' type='string'/>" 169 : " <Option name='METADATA_AUTHOR_NAME' type='string'/>" 170 : " <Option name='METADATA_AUTHOR_LINK_HREF' type='string'/>" 171 : " <Option name='METADATA_AUTHOR_LINK_TEXT' type='string'/>" 172 : " <Option name='METADATA_AUTHOR_LINK_TYPE' type='string'/>" 173 : " <Option name='METADATA_COPYRIGHT_AUTHOR' type='string'/>" 174 : " <Option name='METADATA_COPYRIGHT_LICENSE' type='string'/>" 175 : " <Option name='METADATA_COPYRIGHT_YEAR' type='string'/>" 176 : " <Option name='METADATA_DESCRIPTION' type='string'/>" 177 : " <Option name='METADATA_KEYWORDS' type='string'/>" 178 : " <Option name='METADATA_LINK_*_HREF' type='string'/>" 179 : " <Option name='METADATA_LINK_*_TEXT' type='string'/>" 180 : " <Option name='METADATA_LINK_*_TYPE' type='string'/>" 181 : " <Option name='METADATA_NAME' type='string'/>" 182 : " <Option name='METADATA_TIME' type='string'/>" 183 : " <Option name='CREATOR' type='string'/>" 184 1219 : "</CreationOptionList>"); 185 : 186 1219 : poDriver->SetMetadataItem( 187 : GDAL_DS_LAYER_CREATIONOPTIONLIST, 188 : "<LayerCreationOptionList>" 189 : " <Option name='FORCE_GPX_TRACK' type='boolean' description='Whether " 190 : "to force layers with geometries of type wkbLineString as tracks' " 191 : "default='NO'/>" 192 : " <Option name='FORCE_GPX_ROUTE' type='boolean' description='Whether " 193 : "to force layers with geometries of type wkbMultiLineString (with " 194 : "single line string in them) as routes' default='NO'/>" 195 1219 : "</LayerCreationOptionList>"); 196 : 197 1219 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 198 1219 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 199 : 200 1219 : poDriver->pfnIdentify = OGRGPXDriverIdentify; 201 1219 : poDriver->pfnOpen = OGRGPXDriverOpen; 202 1219 : poDriver->pfnCreate = OGRGPXDriverCreate; 203 1219 : poDriver->pfnDelete = OGRGPXDriverDelete; 204 : 205 1219 : GetGDALDriverManager()->RegisterDriver(poDriver); 206 : }