/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 | } |