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