1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  Implements OGROSMDriver class.
5  * Author:   Even Rouault, <even dot rouault at spatialys.com>
6  *
7  ******************************************************************************
8  * Copyright (c) 2012, 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 "ogr_osm.h"
30 
31 #include <cstring>
32 
33 #include "cpl_conv.h"
34 #include "cpl_port.h"
35 #include "gdal.h"
36 #include "gdal_priv.h"
37 #include "ogr_core.h"
38 
39 
40 /* g++ -DHAVE_EXPAT -fPIC -g -Wall ogr/ogrsf_frmts/osm/ogrosmdriver.cpp ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp ogr/ogrsf_frmts/osm/ogrosmlayer.cpp -Iport -Igcore -Iogr -Iogr/ogrsf_frmts/osm -Iogr/ogrsf_frmts/mitab -Iogr/ogrsf_frmts -shared -o ogr_OSM.so -L. -lgdal */
41 
42 CPL_CVSID("$Id: ogrosmdriver.cpp 1761acd90777d5bcc49eddbc13c193098f0ed40b 2020-10-01 12:12:00 +0200 Even Rouault $")
43 
44 /************************************************************************/
45 /*                      OGROSMDriverIdentify()                          */
46 /************************************************************************/
47 
OGROSMDriverIdentify(GDALOpenInfo * poOpenInfo)48 static int OGROSMDriverIdentify( GDALOpenInfo* poOpenInfo )
49 
50 {
51     if( poOpenInfo->fpL == nullptr || poOpenInfo->nHeaderBytes == 0 )
52         return GDAL_IDENTIFY_FALSE;
53 
54     if( strstr((const char*)poOpenInfo->pabyHeader, "<osm") != nullptr )
55     {
56         return GDAL_IDENTIFY_TRUE;
57     }
58 
59     const int nLimitI =
60         poOpenInfo->nHeaderBytes - static_cast<int>(strlen("OSMHeader"));
61     for(int i = 0; i < nLimitI; i++)
62     {
63         if( memcmp( poOpenInfo->pabyHeader + i, "OSMHeader",
64                     strlen("OSMHeader") ) == 0 )
65         {
66             return GDAL_IDENTIFY_TRUE;
67         }
68     }
69 
70     return GDAL_IDENTIFY_FALSE;
71 }
72 
73 /************************************************************************/
74 /*                                Open()                                */
75 /************************************************************************/
76 
OGROSMDriverOpen(GDALOpenInfo * poOpenInfo)77 static GDALDataset *OGROSMDriverOpen( GDALOpenInfo* poOpenInfo )
78 
79 {
80     if( poOpenInfo->eAccess == GA_Update )
81         return nullptr;
82     if( OGROSMDriverIdentify(poOpenInfo) == FALSE )
83         return nullptr;
84 
85     OGROSMDataSource *poDS = new OGROSMDataSource();
86 
87     if( !poDS->Open( poOpenInfo->pszFilename, poOpenInfo->papszOpenOptions ) )
88     {
89         delete poDS;
90         poDS = nullptr;
91     }
92 
93     return poDS;
94 }
95 
96 /************************************************************************/
97 /*                        RegisterOGROSM()                           */
98 /************************************************************************/
99 
RegisterOGROSM()100 void RegisterOGROSM()
101 {
102     if( !GDAL_CHECK_VERSION("OGR/OSM driver") )
103         return;
104 
105     if( GDALGetDriverByName( "OSM" ) != nullptr )
106         return;
107 
108     GDALDriver *poDriver = new GDALDriver();
109 
110     poDriver->SetDescription( "OSM" );
111     poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
112     poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "OpenStreetMap XML and PBF" );
113     poDriver->SetMetadataItem( GDAL_DMD_EXTENSIONS, "osm pbf" );
114     poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drivers/vector/osm.html" );
115     poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
116 
117     poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST,
118 "<OpenOptionList>"
119 "  <Option name='CONFIG_FILE' type='string' description='Configuration filename.'/>"
120 "  <Option name='USE_CUSTOM_INDEXING' type='boolean' description='Whether to enable custom indexing.' default='YES'/>"
121 "  <Option name='COMPRESS_NODES' type='boolean' description='Whether to compress nodes in temporary DB.' default='NO'/>"
122 "  <Option name='MAX_TMPFILE_SIZE' type='int' description='Maximum size in MB of in-memory temporary file. If it exceeds that value, it will go to disk' default='100'/>"
123 "  <Option name='INTERLEAVED_READING' type='boolean' description='Whether to enable interleaved reading.' default='NO'/>"
124 "</OpenOptionList>" );
125 
126     poDriver->pfnOpen = OGROSMDriverOpen;
127     poDriver->pfnIdentify = OGROSMDriverIdentify;
128 
129     GetGDALDriverManager()->RegisterDriver( poDriver );
130 }
131