/src/gdal/ogr/ogrsf_frmts/wfs/ogrwfsdriver.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /******************************************************************************  | 
2  |  |  *  | 
3  |  |  * Project:  WFS Translator  | 
4  |  |  * Purpose:  Implements OGRWFSDriver.  | 
5  |  |  * Author:   Even Rouault, even dot rouault at spatialys.com  | 
6  |  |  *  | 
7  |  |  ******************************************************************************  | 
8  |  |  * Copyright (c) 2010, Even Rouault <even dot rouault at spatialys.com>  | 
9  |  |  *  | 
10  |  |  * SPDX-License-Identifier: MIT  | 
11  |  |  ****************************************************************************/  | 
12  |  |  | 
13  |  | #include "ogr_wfs.h"  | 
14  |  | #include "cpl_conv.h"  | 
15  |  |  | 
16  |  | // g++ -fPIC -g -Wall ogr/ogrsf_frmts/wfs/*.cpp -shared -o ogr_WFS.so -Iport  | 
17  |  | // -Igcore -Iogr -Iogr/ogrsf_frmts -Iogr/ogrsf_frmts/gml -Iogr/ogrsf_frmts/wfs  | 
18  |  | // -L. -lgdal  | 
19  |  |  | 
20  |  | extern "C" void RegisterOGRWFS();  | 
21  |  |  | 
22  |  | /************************************************************************/  | 
23  |  | /*                             Identify()                               */  | 
24  |  | /************************************************************************/  | 
25  |  |  | 
26  |  | static int OGRWFSDriverIdentify(GDALOpenInfo *poOpenInfo)  | 
27  |  |  | 
28  | 98.2k  | { | 
29  | 98.2k  |     if (!STARTS_WITH_CI(poOpenInfo->pszFilename, "WFS:"))  | 
30  | 97.9k  |     { | 
31  | 97.9k  |         const bool bIsSingleDriver = poOpenInfo->IsSingleAllowedDriver("WFS"); | 
32  | 97.9k  |         if (bIsSingleDriver &&  | 
33  | 97.9k  |             (STARTS_WITH(poOpenInfo->pszFilename, "http://") ||  | 
34  | 0  |              STARTS_WITH(poOpenInfo->pszFilename, "https://")))  | 
35  | 0  |         { | 
36  | 0  |             return true;  | 
37  | 0  |         }  | 
38  |  |  | 
39  | 97.9k  |         if (poOpenInfo->fpL == nullptr)  | 
40  | 47.4k  |             return FALSE;  | 
41  |  |  | 
42  | 50.5k  |         const char *pszHeader =  | 
43  | 50.5k  |             reinterpret_cast<const char *>(poOpenInfo->pabyHeader);  | 
44  | 50.5k  |         if (!STARTS_WITH_CI(pszHeader, "<OGRWFSDataSource>") &&  | 
45  | 50.5k  |             strstr(pszHeader, "<WFS_Capabilities") == nullptr &&  | 
46  | 50.5k  |             strstr(pszHeader, "<wfs:WFS_Capabilities") == nullptr)  | 
47  | 46.8k  |         { | 
48  | 46.8k  |             if (bIsSingleDriver)  | 
49  | 0  |             { | 
50  | 0  |                 while (*pszHeader != 0 &&  | 
51  | 0  |                        std::isspace(static_cast<unsigned char>(*pszHeader)))  | 
52  | 0  |                     ++pszHeader;  | 
53  | 0  |                 return *pszHeader == '<';  | 
54  | 0  |             }  | 
55  |  |  | 
56  | 46.8k  |             return FALSE;  | 
57  | 46.8k  |         }  | 
58  | 50.5k  |     }  | 
59  | 3.98k  |     return TRUE;  | 
60  | 98.2k  | }  | 
61  |  |  | 
62  |  | /************************************************************************/  | 
63  |  | /*                                Open()                                */  | 
64  |  | /************************************************************************/  | 
65  |  |  | 
66  |  | static GDALDataset *OGRWFSDriverOpen(GDALOpenInfo *poOpenInfo)  | 
67  |  |  | 
68  | 1.99k  | { | 
69  | 1.99k  |     if (!OGRWFSDriverIdentify(poOpenInfo))  | 
70  | 0  |         return nullptr;  | 
71  |  |  | 
72  | 1.99k  |     OGRWFSDataSource *poDS = new OGRWFSDataSource();  | 
73  |  |  | 
74  | 1.99k  |     if (!poDS->Open(poOpenInfo->pszFilename, poOpenInfo->eAccess == GA_Update,  | 
75  | 1.99k  |                     poOpenInfo->papszOpenOptions))  | 
76  | 1.87k  |     { | 
77  | 1.87k  |         delete poDS;  | 
78  | 1.87k  |         poDS = nullptr;  | 
79  | 1.87k  |     }  | 
80  |  |  | 
81  | 1.99k  |     return poDS;  | 
82  | 1.99k  | }  | 
83  |  |  | 
84  |  | /************************************************************************/  | 
85  |  | /*                           RegisterOGRWFS()                           */  | 
86  |  | /************************************************************************/  | 
87  |  |  | 
88  |  | void RegisterOGRWFS()  | 
89  |  |  | 
90  | 24  | { | 
91  | 24  |     if (GDALGetDriverByName("WFS") != nullptr) | 
92  | 0  |         return;  | 
93  |  |  | 
94  | 24  |     GDALDriver *poDriver = new GDALDriver();  | 
95  |  |  | 
96  | 24  |     poDriver->SetDescription("WFS"); | 
97  | 24  |     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");  | 
98  | 24  |     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,  | 
99  | 24  |                               "OGC WFS (Web Feature Service)");  | 
100  | 24  |     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/wfs.html");  | 
101  |  |  | 
102  | 24  |     poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "WFS:");  | 
103  |  |  | 
104  | 24  |     poDriver->SetMetadataItem(  | 
105  | 24  |         GDAL_DMD_OPENOPTIONLIST,  | 
106  | 24  |         "<OpenOptionList>"  | 
107  | 24  |         "  <Option name='URL' type='string' description='URL to the WFS server "  | 
108  | 24  |         "endpoint' required='true'/>"  | 
109  | 24  |         "  <Option name='TRUST_CAPABILITIES_BOUNDS' type='boolean' "  | 
110  | 24  |         "description='Whether to trust layer bounds declared in "  | 
111  | 24  |         "GetCapabilities response' default='NO'/>"  | 
112  | 24  |         "  <Option name='EMPTY_AS_NULL' type='boolean' description='Force "  | 
113  | 24  |         "empty fields to be reported as NULL. Set to NO so that not-nullable "  | 
114  | 24  |         "fields can be exposed' default='YES'/>"  | 
115  | 24  |         "  <Option name='INVERT_AXIS_ORDER_IF_LAT_LONG' type='boolean' "  | 
116  | 24  |         "description='Whether to present SRS and coordinate ordering in "  | 
117  | 24  |         "traditional GIS order' default='YES'/>"  | 
118  | 24  |         "  <Option name='CONSIDER_EPSG_AS_URN' type='string-select' "  | 
119  | 24  |         "description='Whether to consider srsName like EPSG:XXXX as respecting "  | 
120  | 24  |         "EPSG axis order' default='AUTO'>"  | 
121  | 24  |         "    <Value>AUTO</Value>"  | 
122  | 24  |         "    <Value>YES</Value>"  | 
123  | 24  |         "    <Value>NO</Value>"  | 
124  | 24  |         "  </Option>"  | 
125  | 24  |         "  <Option name='EXPOSE_GML_ID' type='boolean' description='Whether to "  | 
126  | 24  |         "make feature gml:id as a gml_id attribute.' default='YES'/>"  | 
127  | 24  |         "</OpenOptionList>");  | 
128  |  |  | 
129  | 24  |     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");  | 
130  | 24  |     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");  | 
131  |  |  | 
132  | 24  |     poDriver->pfnIdentify = OGRWFSDriverIdentify;  | 
133  | 24  |     poDriver->pfnOpen = OGRWFSDriverOpen;  | 
134  |  |  | 
135  | 24  |     GetGDALDriverManager()->RegisterDriver(poDriver);  | 
136  | 24  | }  |