Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: GML Reader
5 : * Purpose: Private Declarations for OGR free GML Reader code.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam
10 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #ifndef CPL_GMLREADERP_H_INCLUDED
32 : #define CPL_GMLREADERP_H_INCLUDED
33 :
34 : #if defined(HAVE_XERCES)
35 :
36 : #include "xercesc_headers.h"
37 : #include "ogr_xerces.h"
38 :
39 : #endif /* HAVE_XERCES */
40 :
41 : #include "cpl_string.h"
42 : #include "gmlreader.h"
43 : #include "ogr_api.h"
44 : #include "cpl_vsi.h"
45 : #include "cpl_multiproc.h"
46 : #include "gmlutils.h"
47 :
48 : #include <map>
49 : #include <string>
50 : #include <vector>
51 :
52 : #define PARSER_BUF_SIZE (10 * 8192)
53 :
54 : class GMLReader;
55 :
56 : typedef struct _GeometryNamesStruct GeometryNamesStruct;
57 :
58 : bool OGRGMLIsGeometryElement(const char *pszElement);
59 :
60 : /************************************************************************/
61 : /* GFSTemplateList */
62 : /************************************************************************/
63 :
64 : class GFSTemplateItem;
65 :
66 : class GFSTemplateList
67 : {
68 : private:
69 : bool m_bSequentialLayers;
70 : GFSTemplateItem *pFirst;
71 : GFSTemplateItem *pLast;
72 : GFSTemplateItem *Insert(const char *pszName);
73 :
74 : public:
75 : GFSTemplateList();
76 : ~GFSTemplateList();
77 : void Update(const char *pszName, int bHasGeom);
78 :
79 4 : GFSTemplateItem *GetFirst()
80 : {
81 4 : return pFirst;
82 : }
83 :
84 2 : bool HaveSequentialLayers()
85 : {
86 2 : return m_bSequentialLayers;
87 : }
88 :
89 : int GetClassCount();
90 : };
91 :
92 : void gmlUpdateFeatureClasses(GFSTemplateList *pCC, GMLReader *pReader,
93 : int *pnHasSequentialLayers);
94 :
95 : /************************************************************************/
96 : /* GMLHandler */
97 : /************************************************************************/
98 :
99 : #define STACK_SIZE 5
100 :
101 : typedef enum
102 : {
103 : STATE_TOP,
104 : STATE_DEFAULT,
105 : STATE_FEATURE,
106 : STATE_PROPERTY,
107 : STATE_FEATUREPROPERTY,
108 : STATE_GEOMETRY,
109 : STATE_IGNORED_FEATURE,
110 : STATE_BOUNDED_BY,
111 : STATE_BOUNDED_BY_IN_FEATURE,
112 : STATE_CITYGML_ATTRIBUTE
113 : } HandlerState;
114 :
115 : typedef struct
116 : {
117 : CPLXMLNode *psNode;
118 : CPLXMLNode *psLastChild;
119 : } NodeLastChild;
120 :
121 : typedef enum
122 : {
123 : APPSCHEMA_GENERIC,
124 : APPSCHEMA_CITYGML,
125 : APPSCHEMA_AIXM,
126 : APPSCHEMA_MTKGML /* format of National Land Survey Finnish */
127 : } GMLAppSchemaType;
128 :
129 : class GMLHandler
130 : {
131 : char *m_pszCurField;
132 : unsigned int m_nCurFieldAlloc;
133 : unsigned int m_nCurFieldLen;
134 : bool m_bInCurField;
135 : int m_nAttributeIndex;
136 : int m_nAttributeDepth;
137 :
138 : char *m_pszGeometry;
139 : unsigned int m_nGeomAlloc;
140 : unsigned int m_nGeomLen;
141 : int m_nGeometryDepth;
142 : bool m_bAlreadyFoundGeometry;
143 : int m_nGeometryPropertyIndex;
144 : std::map<std::string, CPLXMLNode *> m_oMapElementToSubstitute{};
145 :
146 : int m_nDepth;
147 : int m_nDepthFeature;
148 : int m_nUnlimitedDepth = -1; // -1 unknown, 0=false, 1=true
149 :
150 : int m_inBoundedByDepth;
151 :
152 : char *m_pszCityGMLGenericAttrName;
153 : int m_inCityGMLGenericAttrDepth;
154 :
155 : bool m_bReportHref;
156 : char *m_pszHref;
157 : char *m_pszUom;
158 : char *m_pszValue;
159 : char *m_pszKieli;
160 :
161 : GeometryNamesStruct *pasGeometryNames;
162 :
163 : std::vector<NodeLastChild> apsXMLNode;
164 :
165 : int m_nSRSDimensionIfMissing;
166 :
167 : OGRErr startElementTop(const char *pszName, int nLenName, void *attr);
168 :
169 : OGRErr endElementIgnoredFeature();
170 :
171 : OGRErr startElementBoundedBy(const char *pszName, int nLenName, void *attr);
172 : OGRErr endElementBoundedBy();
173 :
174 : OGRErr endElementBoundedByInFeature();
175 :
176 : OGRErr startElementFeatureAttribute(const char *pszName, int nLenName,
177 : void *attr);
178 : OGRErr endElementFeature();
179 :
180 : OGRErr startElementCityGMLGenericAttr(const char *pszName, int nLenName,
181 : void *attr);
182 : OGRErr endElementCityGMLGenericAttr();
183 :
184 : OGRErr startElementGeometry(const char *pszName, int nLenName, void *attr);
185 : CPLXMLNode *ParseAIXMElevationPoint(CPLXMLNode *);
186 : OGRErr endElementGeometry();
187 : OGRErr dataHandlerGeometry(const char *data, int nLen);
188 :
189 : OGRErr endElementAttribute();
190 : OGRErr dataHandlerAttribute(const char *data, int nLen);
191 :
192 : OGRErr startElementDefault(const char *pszName, int nLenName, void *attr);
193 : OGRErr endElementDefault();
194 :
195 : OGRErr startElementFeatureProperty(const char *pszName, int nLenName,
196 : void *attr);
197 : OGRErr endElementFeatureProperty();
198 :
199 : void DealWithAttributes(const char *pszName, int nLenName, void *attr);
200 : bool IsConditionMatched(const char *pszCondition, void *attr);
201 : int FindRealPropertyByCheckingConditions(int nIdx, void *attr);
202 :
203 : protected:
204 : GMLReader *m_poReader;
205 : GMLAppSchemaType eAppSchemaType;
206 :
207 : int nStackDepth;
208 : HandlerState stateStack[STACK_SIZE];
209 :
210 : CPLString m_osFID;
211 : virtual const char *GetFID(void *attr) = 0;
212 :
213 : virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) = 0;
214 :
215 : OGRErr startElement(const char *pszName, int nLenName, void *attr);
216 : OGRErr endElement();
217 : OGRErr dataHandler(const char *data, int nLen);
218 :
219 : bool IsGeometryElement(const char *pszElement);
220 :
221 : public:
222 : explicit GMLHandler(GMLReader *poReader);
223 : virtual ~GMLHandler();
224 :
225 : virtual char *GetAttributeValue(void *attr,
226 : const char *pszAttributeName) = 0;
227 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
228 : char **ppszKey) = 0;
229 : };
230 :
231 : #if defined(HAVE_XERCES)
232 :
233 : /************************************************************************/
234 : /* GMLXercesHandler */
235 : /************************************************************************/
236 : class GMLXercesHandler final : public DefaultHandler, public GMLHandler
237 : {
238 : int m_nEntityCounter;
239 : CPLString m_osElement;
240 : CPLString m_osCharacters;
241 : CPLString m_osAttrName;
242 : CPLString m_osAttrValue;
243 :
244 : public:
245 : explicit GMLXercesHandler(GMLReader *poReader);
246 :
247 : void startElement(const XMLCh *const uri, const XMLCh *const localname,
248 : const XMLCh *const qname,
249 : const Attributes &attrs) override;
250 : void endElement(const XMLCh *const uri, const XMLCh *const localname,
251 : const XMLCh *const qname) override;
252 : void characters(const XMLCh *const chars, const XMLSize_t length) override;
253 :
254 : void fatalError(const SAXParseException &) override;
255 :
256 : void startEntity(const XMLCh *const name) override;
257 :
258 : virtual const char *GetFID(void *attr) override;
259 : virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
260 : virtual char *GetAttributeValue(void *attr,
261 : const char *pszAttributeName) override;
262 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
263 : char **ppszKey) override;
264 : };
265 :
266 : #endif
267 :
268 : #if defined(HAVE_EXPAT)
269 :
270 : #include "ogr_expat.h"
271 :
272 : /************************************************************************/
273 : /* GMLExpatHandler */
274 : /************************************************************************/
275 : class GMLExpatHandler final : public GMLHandler
276 : {
277 : XML_Parser m_oParser;
278 : bool m_bStopParsing;
279 : int m_nDataHandlerCounter;
280 :
281 : void DealWithError(OGRErr eErr);
282 :
283 : public:
284 : GMLExpatHandler(GMLReader *poReader, XML_Parser oParser);
285 :
286 510 : bool HasStoppedParsing()
287 : {
288 510 : return m_bStopParsing;
289 : }
290 :
291 514 : void ResetDataHandlerCounter()
292 : {
293 514 : m_nDataHandlerCounter = 0;
294 514 : }
295 :
296 : virtual const char *GetFID(void *attr) override;
297 : virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
298 : virtual char *GetAttributeValue(void *attr,
299 : const char *pszAttributeName) override;
300 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
301 : char **ppszKey) override;
302 :
303 : static void XMLCALL startElementCbk(void *pUserData, const char *pszName,
304 : const char **ppszAttr);
305 :
306 : static void XMLCALL endElementCbk(void *pUserData, const char *pszName);
307 :
308 : static void XMLCALL dataHandlerCbk(void *pUserData, const char *data,
309 : int nLen);
310 : };
311 :
312 : #endif
313 :
314 : /************************************************************************/
315 : /* GMLReadState */
316 : /************************************************************************/
317 :
318 : class GMLReadState
319 : {
320 : std::vector<std::string> aosPathComponents;
321 :
322 : public:
323 : GMLReadState();
324 : ~GMLReadState();
325 :
326 : void PushPath(const char *pszElement, int nLen = -1);
327 : void PopPath();
328 :
329 5275 : const char *GetLastComponent() const
330 : {
331 5275 : return (m_nPathLength == 0)
332 5275 : ? ""
333 5275 : : aosPathComponents[m_nPathLength - 1].c_str();
334 : }
335 :
336 5124 : size_t GetLastComponentLen() const
337 : {
338 5124 : return (m_nPathLength == 0)
339 5124 : ? 0
340 5124 : : aosPathComponents[m_nPathLength - 1].size();
341 : }
342 :
343 : void Reset();
344 :
345 : GMLFeature *m_poFeature;
346 : GMLReadState *m_poParentState;
347 :
348 : std::string osPath; // element path ... | as separator.
349 : int m_nPathLength;
350 : };
351 :
352 : /************************************************************************/
353 : /* GMLReader */
354 : /************************************************************************/
355 :
356 : class GMLReader final : public IGMLReader
357 : {
358 : private:
359 : bool m_bClassListLocked;
360 :
361 : int m_nClassCount;
362 : GMLFeatureClass **m_papoClass;
363 : bool m_bLookForClassAtAnyLevel;
364 :
365 : char *m_pszFilename;
366 :
367 : bool bUseExpatReader;
368 :
369 : GMLHandler *m_poGMLHandler;
370 :
371 : #if defined(HAVE_XERCES)
372 : SAX2XMLReader *m_poSAXReader;
373 : XMLPScanToken m_oToFill;
374 : GMLFeature *m_poCompleteFeature;
375 : InputSource *m_GMLInputSource;
376 : bool m_bEOF;
377 : bool m_bXercesInitialized;
378 : bool SetupParserXerces();
379 : GMLFeature *NextFeatureXerces();
380 : #endif
381 :
382 : #if defined(HAVE_EXPAT)
383 : XML_Parser oParser;
384 : GMLFeature **ppoFeatureTab;
385 : int nFeatureTabLength;
386 : int nFeatureTabIndex;
387 : int nFeatureTabAlloc;
388 : bool SetupParserExpat();
389 : GMLFeature *NextFeatureExpat();
390 : char *pabyBuf;
391 : CPLString m_osErrorMessage{};
392 : #endif
393 :
394 : VSILFILE *fpGML;
395 : bool m_bReadStarted;
396 :
397 : GMLReadState *m_poState;
398 : GMLReadState *m_poRecycledState;
399 :
400 : bool m_bStopParsing;
401 :
402 : bool SetupParser();
403 : void CleanupParser();
404 :
405 : bool m_bFetchAllGeometries;
406 :
407 : bool m_bInvertAxisOrderIfLatLong;
408 : bool m_bConsiderEPSGAsURN;
409 : GMLSwapCoordinatesEnum m_eSwapCoordinates;
410 : bool m_bGetSecondaryGeometryOption;
411 :
412 : int ParseFeatureType(CPLXMLNode *psSchemaNode, const char *pszName,
413 : const char *pszType);
414 :
415 : char *m_pszGlobalSRSName;
416 : bool m_bCanUseGlobalSRSName;
417 :
418 : char *m_pszFilteredClassName;
419 : int m_nFilteredClassIndex;
420 :
421 : int m_nHasSequentialLayers;
422 :
423 : std::string osElemPath;
424 :
425 : bool m_bFaceHoleNegative;
426 :
427 : bool m_bSetWidthFlag;
428 :
429 : bool m_bReportAllAttributes;
430 :
431 : bool m_bIsWFSJointLayer;
432 :
433 : bool m_bEmptyAsNull;
434 :
435 : bool m_bUseBBOX = false;
436 :
437 : bool ParseXMLHugeFile(const char *pszOutputFilename,
438 : const bool bSqliteIsTempFile,
439 : const int iSqliteCacheMB);
440 :
441 : public:
442 : GMLReader(bool bExpatReader, bool bInvertAxisOrderIfLatLong,
443 : bool bConsiderEPSGAsURN, GMLSwapCoordinatesEnum eSwapCoordinates,
444 : bool bGetSecondaryGeometryOption);
445 : virtual ~GMLReader();
446 :
447 0 : bool IsClassListLocked() const override
448 : {
449 0 : return m_bClassListLocked;
450 : }
451 :
452 386 : void SetClassListLocked(bool bFlag) override
453 : {
454 386 : m_bClassListLocked = bFlag;
455 386 : }
456 :
457 : void SetSourceFile(const char *pszFilename) override;
458 : void SetFP(VSILFILE *fp) override;
459 : const char *GetSourceFileName() override;
460 :
461 3252 : int GetClassCount() const override
462 : {
463 3252 : return m_nClassCount;
464 : }
465 :
466 : GMLFeatureClass *GetClass(int i) const override;
467 : GMLFeatureClass *GetClass(const char *pszName) const override;
468 :
469 : int AddClass(GMLFeatureClass *poClass) override;
470 : void ClearClasses() override;
471 :
472 : GMLFeature *NextFeature() override;
473 :
474 : bool LoadClasses(const char *pszFile = nullptr) override;
475 : bool SaveClasses(const char *pszFile = nullptr) override;
476 :
477 : bool ResolveXlinks(const char *pszFile, bool *pbOutIsTempFile,
478 : char **papszSkip = nullptr,
479 : const bool bStrict = false) override;
480 :
481 : bool HugeFileResolver(const char *pszFile, bool bSqliteIsTempFile,
482 : int iSqliteCacheMB) override;
483 :
484 : bool PrescanForSchema(bool bGetExtents = true,
485 : bool bOnlyDetectSRS = false) override;
486 : bool PrescanForTemplate() override;
487 : bool ReArrangeTemplateClasses(GFSTemplateList *pCC);
488 : void ResetReading() override;
489 :
490 : // ---
491 :
492 53361 : GMLReadState *GetState() const
493 : {
494 53361 : return m_poState;
495 : }
496 :
497 : void PopState();
498 : void PushState(GMLReadState *);
499 :
500 5957 : bool ShouldLookForClassAtAnyLevel()
501 : {
502 5957 : return m_bLookForClassAtAnyLevel;
503 : }
504 :
505 : int GetFeatureElementIndex(const char *pszElement, int nLen,
506 : GMLAppSchemaType eAppSchemaType);
507 : int GetAttributeElementIndex(const char *pszElement, int nLen,
508 : const char *pszAttrKey = nullptr);
509 : bool IsCityGMLGenericAttributeElement(const char *pszElement, void *attr);
510 :
511 : void PushFeature(const char *pszElement, const char *pszFID,
512 : int nClassIndex);
513 :
514 : void SetFeaturePropertyDirectly(const char *pszElement, char *pszValue,
515 : int iPropertyIn,
516 : GMLPropertyType eType = GMLPT_Untyped);
517 :
518 7 : void SetWidthFlag(bool bFlag)
519 : {
520 7 : m_bSetWidthFlag = bFlag;
521 7 : }
522 :
523 89 : bool HasStoppedParsing() override
524 : {
525 89 : return m_bStopParsing;
526 : }
527 :
528 3687 : bool FetchAllGeometries()
529 : {
530 3687 : return m_bFetchAllGeometries;
531 : }
532 :
533 : void SetGlobalSRSName(const char *pszGlobalSRSName) override;
534 :
535 457 : const char *GetGlobalSRSName() override
536 : {
537 457 : return m_pszGlobalSRSName;
538 : }
539 :
540 987 : bool CanUseGlobalSRSName() override
541 : {
542 987 : return m_bCanUseGlobalSRSName;
543 : }
544 :
545 : bool SetFilteredClassName(const char *pszClassName) override;
546 :
547 3578 : const char *GetFilteredClassName() override
548 : {
549 3578 : return m_pszFilteredClassName;
550 : }
551 :
552 49 : int GetFilteredClassIndex()
553 : {
554 49 : return m_nFilteredClassIndex;
555 : }
556 :
557 77 : bool IsSequentialLayers() const override
558 : {
559 77 : return m_nHasSequentialLayers == TRUE;
560 : }
561 :
562 383 : void SetReportAllAttributes(bool bFlag)
563 : {
564 383 : m_bReportAllAttributes = bFlag;
565 383 : }
566 :
567 432 : bool ReportAllAttributes() const
568 : {
569 432 : return m_bReportAllAttributes;
570 : }
571 :
572 383 : void SetIsWFSJointLayer(bool bFlag)
573 : {
574 383 : m_bIsWFSJointLayer = bFlag;
575 383 : }
576 :
577 23685 : bool IsWFSJointLayer() const
578 : {
579 23685 : return m_bIsWFSJointLayer;
580 : }
581 :
582 383 : void SetEmptyAsNull(bool bFlag)
583 : {
584 383 : m_bEmptyAsNull = bFlag;
585 383 : }
586 :
587 31 : bool IsEmptyAsNull() const
588 : {
589 31 : return m_bEmptyAsNull;
590 : }
591 :
592 383 : void SetUseBBOX(bool bFlag)
593 : {
594 383 : m_bUseBBOX = bFlag;
595 383 : }
596 :
597 903 : bool UseBBOX() const
598 : {
599 903 : return m_bUseBBOX;
600 : }
601 :
602 : static CPLMutex *hMutex;
603 : };
604 :
605 : #endif /* CPL_GMLREADERP_H_INCLUDED */
|