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 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_port.h" 14 : #include "ogr_gpx.h" 15 : 16 : #include <cstring> 17 : 18 : #include "cpl_conv.h" 19 : #include "cpl_error.h" 20 : #include "cpl_vsi.h" 21 : #include "gdal.h" 22 : #include "gdal_priv.h" 23 : #include "ogr_core.h" 24 : 25 : /************************************************************************/ 26 : /* Identify() */ 27 : /************************************************************************/ 28 : 29 58030 : static int OGRGPXDriverIdentify(GDALOpenInfo *poOpenInfo) 30 : 31 : { 32 58030 : if (poOpenInfo->eAccess == GA_Update || poOpenInfo->fpL == nullptr) 33 53202 : return false; 34 : 35 4828 : return strstr(reinterpret_cast<const char *>(poOpenInfo->pabyHeader), 36 4828 : "<gpx") != nullptr; 37 : } 38 : 39 : /************************************************************************/ 40 : /* Open() */ 41 : /************************************************************************/ 42 : 43 29 : static GDALDataset *OGRGPXDriverOpen(GDALOpenInfo *poOpenInfo) 44 : 45 : { 46 29 : if (poOpenInfo->eAccess == GA_Update || !OGRGPXDriverIdentify(poOpenInfo)) 47 0 : return nullptr; 48 : 49 29 : OGRGPXDataSource *poDS = new OGRGPXDataSource(); 50 : 51 29 : if (!poDS->Open(poOpenInfo)) 52 : { 53 0 : delete poDS; 54 0 : poDS = nullptr; 55 : } 56 : 57 29 : return poDS; 58 : } 59 : 60 : /************************************************************************/ 61 : /* Create() */ 62 : /************************************************************************/ 63 : 64 25 : static GDALDataset *OGRGPXDriverCreate(const char *pszName, 65 : CPL_UNUSED int nBands, 66 : CPL_UNUSED int nXSize, 67 : CPL_UNUSED int nYSize, 68 : CPL_UNUSED GDALDataType eDT, 69 : CPL_UNUSED CSLConstList papszOptions) 70 : { 71 25 : OGRGPXDataSource *poDS = new OGRGPXDataSource(); 72 : 73 25 : if (!poDS->Create(pszName, papszOptions)) 74 : { 75 1 : delete poDS; 76 1 : poDS = nullptr; 77 : } 78 : 79 25 : return poDS; 80 : } 81 : 82 : /************************************************************************/ 83 : /* Delete() */ 84 : /************************************************************************/ 85 : 86 16 : static CPLErr OGRGPXDriverDelete(const char *pszFilename) 87 : 88 : { 89 16 : if (VSIUnlink(pszFilename) == 0) 90 16 : return CE_None; 91 : else 92 0 : return CE_Failure; 93 : } 94 : 95 : /************************************************************************/ 96 : /* RegisterOGRGPX() */ 97 : /************************************************************************/ 98 : 99 2059 : void RegisterOGRGPX() 100 : 101 : { 102 2059 : if (!GDAL_CHECK_VERSION("OGR/GPX driver")) 103 0 : return; 104 : 105 2059 : if (GDALGetDriverByName("GPX") != nullptr) 106 283 : return; 107 : 108 1776 : GDALDriver *poDriver = new GDALDriver(); 109 : 110 1776 : poDriver->SetDescription("GPX"); 111 1776 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 112 1776 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES"); 113 1776 : poDriver->SetMetadataItem(GDAL_DCAP_DELETE_LAYER, "YES"); 114 1776 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES"); 115 1776 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 116 1776 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "GPX"); 117 1776 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "gpx"); 118 1776 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/gpx.html"); 119 1776 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 120 : 121 1776 : poDriver->SetMetadataItem( 122 : GDAL_DMD_OPENOPTIONLIST, 123 : "<OpenOptionList>" 124 : " <Option name='N_MAX_LINKS' type='integer' default='2' " 125 : "description='Maximum number of links attributes'/>" 126 : " <Option name='ELE_AS_25D' type='boolean' default='NO' " 127 : "description='Whether to use the value of the ele element as the Z " 128 : "ordinate of geometries'/>" 129 : " <Option name='SHORT_NAMES' type='boolean' default='NO' " 130 : "description='Whether to use short field names (typically for " 131 : "shapefile compatibility'/>" 132 1776 : "</OpenOptionList>"); 133 : 134 1776 : poDriver->SetMetadataItem( 135 : GDAL_DMD_CREATIONOPTIONLIST, 136 : "<CreationOptionList>" 137 : #ifdef _WIN32 138 : " <Option name='LINEFORMAT' type='string-select' " 139 : "description='end-of-line sequence' default='CRLF'>" 140 : #else 141 : " <Option name='LINEFORMAT' type='string-select' " 142 : "description='end-of-line sequence' default='LF'>" 143 : #endif 144 : " <Value>CRLF</Value>" 145 : " <Value>LF</Value>" 146 : " </Option>" 147 : " <Option name='GPX_USE_EXTENSIONS' type='boolean' " 148 : "description='Whether to write non-GPX attributes in an " 149 : "<extensions> tag' default='NO'/>" 150 : " <Option name='GPX_EXTENSIONS_NS' type='string' " 151 : "description='Namespace value used for extension tags' default='ogr'/>" 152 : " <Option name='GPX_EXTENSIONS_NS_URL' type='string' " 153 : "description='Namespace URI' default='http://osgeo.org/gdal'/>" 154 : " <Option name='METADATA_AUTHOR_EMAIL' type='string'/>" 155 : " <Option name='METADATA_AUTHOR_NAME' type='string'/>" 156 : " <Option name='METADATA_AUTHOR_LINK_HREF' type='string'/>" 157 : " <Option name='METADATA_AUTHOR_LINK_TEXT' type='string'/>" 158 : " <Option name='METADATA_AUTHOR_LINK_TYPE' type='string'/>" 159 : " <Option name='METADATA_COPYRIGHT_AUTHOR' type='string'/>" 160 : " <Option name='METADATA_COPYRIGHT_LICENSE' type='string'/>" 161 : " <Option name='METADATA_COPYRIGHT_YEAR' type='string'/>" 162 : " <Option name='METADATA_DESCRIPTION' type='string'/>" 163 : " <Option name='METADATA_KEYWORDS' type='string'/>" 164 : " <Option name='METADATA_LINK_*_HREF' type='string'/>" 165 : " <Option name='METADATA_LINK_*_TEXT' type='string'/>" 166 : " <Option name='METADATA_LINK_*_TYPE' type='string'/>" 167 : " <Option name='METADATA_NAME' type='string'/>" 168 : " <Option name='METADATA_TIME' type='string'/>" 169 : " <Option name='CREATOR' type='string'/>" 170 1776 : "</CreationOptionList>"); 171 : 172 1776 : poDriver->SetMetadataItem( 173 : GDAL_DS_LAYER_CREATIONOPTIONLIST, 174 : "<LayerCreationOptionList>" 175 : " <Option name='FORCE_GPX_TRACK' type='boolean' description='Whether " 176 : "to force layers with geometries of type wkbLineString as tracks' " 177 : "default='NO'/>" 178 : " <Option name='FORCE_GPX_ROUTE' type='boolean' description='Whether " 179 : "to force layers with geometries of type wkbMultiLineString (with " 180 : "single line string in them) as routes' default='NO'/>" 181 1776 : "</LayerCreationOptionList>"); 182 : 183 1776 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 184 1776 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 185 : 186 1776 : poDriver->pfnIdentify = OGRGPXDriverIdentify; 187 1776 : poDriver->pfnOpen = OGRGPXDriverOpen; 188 1776 : poDriver->pfnCreate = OGRGPXDriverCreate; 189 1776 : poDriver->pfnDelete = OGRGPXDriverDelete; 190 : 191 1776 : GetGDALDriverManager()->RegisterDriver(poDriver); 192 : }