Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: JML Translator
4 : * Purpose: Implements OGRJMLDataset class
5 : * Author: Even Rouault, even dot rouault at spatialys dot com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys dot 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_conv.h"
30 : #include "cpl_string.h"
31 : #include "ogr_jml.h"
32 : #include "ogrsf_frmts.h"
33 :
34 : // g++ -DHAVE_EXPAT -fPIC -shared -Wall -g -DDEBUG ogr/ogrsf_frmts/jml/*.cpp -o
35 : // ogr_JML.so -Iport -Igcore -Iogr -Iogr/ogrsf_frmts -Iogr/ogrsf_frmts/jml -L.
36 : // -lgdal
37 :
38 : /************************************************************************/
39 : /* OGRJMLDataset() */
40 : /************************************************************************/
41 :
42 82 : OGRJMLDataset::OGRJMLDataset()
43 82 : : poLayer(nullptr), fp(nullptr), bWriteMode(false)
44 : {
45 82 : }
46 :
47 : /************************************************************************/
48 : /* ~OGRJMLDataset() */
49 : /************************************************************************/
50 :
51 164 : OGRJMLDataset::~OGRJMLDataset()
52 :
53 : {
54 82 : delete poLayer;
55 :
56 82 : if (fp != nullptr)
57 80 : VSIFCloseL(fp);
58 164 : }
59 :
60 : /************************************************************************/
61 : /* TestCapability() */
62 : /************************************************************************/
63 :
64 57 : int OGRJMLDataset::TestCapability(const char *pszCap)
65 :
66 : {
67 57 : if (EQUAL(pszCap, ODsCCreateLayer))
68 34 : return bWriteMode && poLayer == nullptr;
69 23 : if (EQUAL(pszCap, ODsCZGeometries))
70 2 : return true;
71 :
72 21 : return false;
73 : }
74 :
75 : /************************************************************************/
76 : /* GetLayer() */
77 : /************************************************************************/
78 :
79 33 : OGRLayer *OGRJMLDataset::GetLayer(int iLayer)
80 :
81 : {
82 33 : if (iLayer != 0)
83 3 : return nullptr;
84 :
85 30 : return poLayer;
86 : }
87 :
88 : /************************************************************************/
89 : /* Identify() */
90 : /************************************************************************/
91 :
92 42077 : int OGRJMLDataset::Identify(GDALOpenInfo *poOpenInfo)
93 : {
94 44168 : return poOpenInfo->nHeaderBytes != 0 &&
95 2091 : strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader),
96 42077 : "<JCSDataFile") != nullptr;
97 : }
98 :
99 : /************************************************************************/
100 : /* Open() */
101 : /************************************************************************/
102 :
103 42 : GDALDataset *OGRJMLDataset::Open(GDALOpenInfo *poOpenInfo)
104 :
105 : {
106 84 : if (!Identify(poOpenInfo) || poOpenInfo->fpL == nullptr ||
107 42 : poOpenInfo->eAccess == GA_Update)
108 0 : return nullptr;
109 :
110 : #ifndef HAVE_EXPAT
111 : CPLError(CE_Failure, CPLE_NotSupported,
112 : "OGR/JML driver has not been built with read support. "
113 : "Expat library required");
114 : return nullptr;
115 : #else
116 42 : OGRJMLDataset *poDS = new OGRJMLDataset();
117 42 : poDS->SetDescription(poOpenInfo->pszFilename);
118 :
119 42 : poDS->fp = poOpenInfo->fpL;
120 42 : poOpenInfo->fpL = nullptr;
121 :
122 42 : poDS->poLayer = new OGRJMLLayer(CPLGetBasename(poOpenInfo->pszFilename),
123 42 : poDS, poDS->fp);
124 :
125 42 : return poDS;
126 : #endif
127 : }
128 :
129 : /************************************************************************/
130 : /* Create() */
131 : /************************************************************************/
132 :
133 40 : GDALDataset *OGRJMLDataset::Create(const char *pszFilename, int /* nXSize */,
134 : int /* nYSize */, int /* nBands */,
135 : GDALDataType /* eDT */,
136 : char ** /* papszOptions */)
137 : {
138 40 : if (strcmp(pszFilename, "/dev/stdout") == 0)
139 0 : pszFilename = "/vsistdout/";
140 :
141 : /* -------------------------------------------------------------------- */
142 : /* Do not override exiting file. */
143 : /* -------------------------------------------------------------------- */
144 : VSIStatBufL sStatBuf;
145 :
146 40 : if (VSIStatL(pszFilename, &sStatBuf) == 0)
147 : {
148 0 : CPLError(CE_Failure, CPLE_NotSupported,
149 : "You have to delete %s before being able to create it "
150 : "with the JML driver",
151 : pszFilename);
152 0 : return nullptr;
153 : }
154 :
155 40 : OGRJMLDataset *poDS = new OGRJMLDataset();
156 :
157 : /* -------------------------------------------------------------------- */
158 : /* Create the output file. */
159 : /* -------------------------------------------------------------------- */
160 40 : poDS->bWriteMode = true;
161 40 : poDS->SetDescription(pszFilename);
162 :
163 40 : poDS->fp = VSIFOpenL(pszFilename, "w");
164 40 : if (poDS->fp == nullptr)
165 : {
166 2 : CPLError(CE_Failure, CPLE_OpenFailed, "Failed to create JML file %s.",
167 : pszFilename);
168 2 : delete poDS;
169 2 : return nullptr;
170 : }
171 :
172 38 : return poDS;
173 : }
174 :
175 : /************************************************************************/
176 : /* ICreateLayer() */
177 : /************************************************************************/
178 :
179 54 : OGRLayer *OGRJMLDataset::ICreateLayer(const char *pszLayerName,
180 : const OGRGeomFieldDefn *poGeomFieldDefn,
181 : CSLConstList papszOptions)
182 : {
183 54 : if (!bWriteMode || poLayer != nullptr)
184 16 : return nullptr;
185 :
186 38 : bool bAddRGBField = CPLTestBool(
187 : CSLFetchNameValueDef(papszOptions, "CREATE_R_G_B_FIELD", "YES"));
188 38 : bool bAddOGRStyleField = CPLTestBool(
189 : CSLFetchNameValueDef(papszOptions, "CREATE_OGR_STYLE_FIELD", "NO"));
190 : bool bClassicGML =
191 38 : CPLTestBool(CSLFetchNameValueDef(papszOptions, "CLASSIC_GML", "NO"));
192 38 : OGRSpatialReference *poSRSClone = nullptr;
193 : const auto poSRS =
194 38 : poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
195 38 : if (poSRS)
196 : {
197 1 : poSRSClone = poSRS->Clone();
198 1 : poSRSClone->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
199 : }
200 38 : poLayer =
201 : new OGRJMLWriterLayer(pszLayerName, poSRSClone, this, fp, bAddRGBField,
202 38 : bAddOGRStyleField, bClassicGML);
203 38 : if (poSRSClone)
204 1 : poSRSClone->Release();
205 :
206 38 : return poLayer;
207 : }
208 :
209 : /************************************************************************/
210 : /* RegisterOGRJML() */
211 : /************************************************************************/
212 :
213 1520 : void RegisterOGRJML()
214 : {
215 1520 : if (GDALGetDriverByName("JML") != nullptr)
216 301 : return;
217 :
218 1219 : GDALDriver *poDriver = new GDALDriver();
219 :
220 1219 : poDriver->SetDescription("JML");
221 1219 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
222 1219 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
223 1219 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
224 1219 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
225 1219 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "OpenJUMP JML");
226 1219 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "jml");
227 1219 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/jml.html");
228 :
229 1219 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
230 1219 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES, "YES");
231 1219 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_READ, "YES");
232 1219 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_WRITE, "YES");
233 1219 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
234 :
235 1219 : poDriver->SetMetadataItem(
236 : GDAL_DS_LAYER_CREATIONOPTIONLIST,
237 : "<LayerCreationOptionList>"
238 : " <Option name='CREATE_R_G_B_FIELD' type='boolean' "
239 : "description='Whether to create a R_G_B field' default='YES'/>"
240 : " <Option name='CREATE_OGR_STYLE_FIELD' type='boolean' "
241 : "description='Whether to create a OGR_STYLE field' default='NO'/>"
242 1219 : "</LayerCreationOptionList>");
243 :
244 1219 : poDriver->SetMetadataItem(GDAL_DMD_CREATIONOPTIONLIST,
245 1219 : "<CreationOptionList/>");
246 :
247 1219 : poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
248 1219 : "Integer Integer64 Real String Date DateTime");
249 :
250 1219 : poDriver->pfnOpen = OGRJMLDataset::Open;
251 1219 : poDriver->pfnIdentify = OGRJMLDataset::Identify;
252 1219 : poDriver->pfnCreate = OGRJMLDataset::Create;
253 :
254 1219 : GetGDALDriverManager()->RegisterDriver(poDriver);
255 : }
|