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 10 : GFSTemplateItem *GetFirst()
65 : {
66 10 : return pFirst;
67 : }
68 :
69 5 : bool HaveSequentialLayers()
70 : {
71 5 : 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 /* non final */
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::string m_osLastGeomPathInCurFeature{};
130 : std::map<std::string, CPLXMLNode *> m_oMapElementToSubstitute{};
131 :
132 : int m_nDepth = 0;
133 : int m_nDepthFeature = 0;
134 : int m_nUnlimitedDepth = -1; // -1 unknown, 0=false, 1=true
135 :
136 : int m_inBoundedByDepth = 0;
137 :
138 : char *m_pszCityGMLGenericAttrName = nullptr;
139 : int m_inCityGMLGenericAttrDepth = 0;
140 :
141 : bool m_bReportHref = false;
142 : char *m_pszHref = nullptr;
143 : char *m_pszUom = nullptr;
144 : char *m_pszValue = nullptr;
145 : char *m_pszKieli = nullptr;
146 :
147 : GeometryNamesStruct *pasGeometryNames = nullptr;
148 :
149 : std::vector<NodeLastChild> apsXMLNode{};
150 :
151 : int m_nSRSDimensionIfMissing = 0;
152 :
153 : OGRErr startElementTop(const char *pszName, int nLenName, void *attr);
154 :
155 : OGRErr endElementIgnoredFeature();
156 :
157 : OGRErr startElementBoundedBy(const char *pszName, int nLenName, void *attr);
158 : OGRErr endElementBoundedBy();
159 :
160 : OGRErr endElementBoundedByInFeature();
161 :
162 : OGRErr startElementFeatureAttribute(const char *pszName, int nLenName,
163 : void *attr);
164 : OGRErr endElementFeature();
165 :
166 : OGRErr startElementCityGMLGenericAttr(const char *pszName, int nLenName,
167 : void *attr);
168 : OGRErr endElementCityGMLGenericAttr();
169 :
170 : OGRErr startElementGeometry(const char *pszName, int nLenName, void *attr);
171 : void ParseAIXMElevationProperties(const CPLXMLNode *);
172 : CPLXMLNode *ParseAIXMElevationPoint(CPLXMLNode *);
173 : OGRErr endElementGeometry();
174 : OGRErr dataHandlerGeometry(const char *data, int nLen);
175 :
176 : OGRErr endElementAttribute();
177 : OGRErr dataHandlerAttribute(const char *data, int nLen);
178 :
179 : OGRErr startElementDefault(const char *pszName, int nLenName, void *attr);
180 : OGRErr endElementDefault();
181 :
182 : OGRErr startElementFeatureProperty(const char *pszName, int nLenName,
183 : void *attr);
184 : OGRErr endElementFeatureProperty();
185 :
186 : void DealWithAttributes(const char *pszName, int nLenName, void *attr);
187 : bool IsConditionMatched(const char *pszCondition, void *attr);
188 : int FindRealPropertyByCheckingConditions(int nIdx, void *attr);
189 :
190 : CPL_DISALLOW_COPY_ASSIGN(GMLHandler)
191 :
192 : protected:
193 : explicit GMLHandler(GMLReader *poReader);
194 :
195 : GMLReader *m_poReader = nullptr;
196 : GMLAppSchemaType eAppSchemaType = APPSCHEMA_GENERIC;
197 :
198 : int nStackDepth = 0;
199 : HandlerState stateStack[STACK_SIZE];
200 :
201 : CPLString m_osFID{};
202 : virtual const char *GetFID(void *attr) = 0;
203 :
204 : virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) = 0;
205 :
206 : OGRErr startElement(const char *pszName, int nLenName, void *attr);
207 : OGRErr endElement();
208 : OGRErr dataHandler(const char *data, int nLen);
209 :
210 : bool IsGeometryElement(const char *pszElement);
211 :
212 : public:
213 : virtual ~GMLHandler();
214 :
215 : virtual char *GetAttributeValue(void *attr,
216 : const char *pszAttributeName) = 0;
217 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
218 : char **ppszKey) = 0;
219 :
220 5 : GMLAppSchemaType GetAppSchemaType() const
221 : {
222 5 : return eAppSchemaType;
223 : }
224 : };
225 :
226 : #if defined(HAVE_XERCES)
227 :
228 : /************************************************************************/
229 : /* GMLXercesHandler */
230 : /************************************************************************/
231 : class GMLXercesHandler final : public DefaultHandler, public GMLHandler
232 : {
233 : int m_nEntityCounter = 0;
234 : CPLString m_osElement{};
235 : CPLString m_osCharacters{};
236 : CPLString m_osAttrName{};
237 : CPLString m_osAttrValue{};
238 :
239 : public:
240 : explicit GMLXercesHandler(GMLReader *poReader);
241 :
242 : void startElement(const XMLCh *const uri, const XMLCh *const localname,
243 : const XMLCh *const qname,
244 : const Attributes &attrs) override;
245 : void endElement(const XMLCh *const uri, const XMLCh *const localname,
246 : const XMLCh *const qname) override;
247 : void characters(const XMLCh *const chars, const XMLSize_t length) override;
248 :
249 : void fatalError(const SAXParseException &) override;
250 :
251 : void startEntity(const XMLCh *const name) override;
252 :
253 : const char *GetFID(void *attr) override;
254 : CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
255 : virtual char *GetAttributeValue(void *attr,
256 : const char *pszAttributeName) override;
257 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
258 : char **ppszKey) override;
259 : };
260 :
261 : #endif
262 :
263 : #if defined(HAVE_EXPAT)
264 :
265 : #include "ogr_expat.h"
266 :
267 : /************************************************************************/
268 : /* GMLExpatHandler */
269 : /************************************************************************/
270 : class GMLExpatHandler final : public GMLHandler
271 : {
272 : XML_Parser m_oParser = nullptr;
273 : bool m_bStopParsing = false;
274 : int m_nDataHandlerCounter = 0;
275 :
276 : void DealWithError(OGRErr eErr);
277 :
278 : CPL_DISALLOW_COPY_ASSIGN(GMLExpatHandler)
279 :
280 : public:
281 : GMLExpatHandler(GMLReader *poReader, XML_Parser oParser);
282 :
283 600 : bool HasStoppedParsing()
284 : {
285 600 : return m_bStopParsing;
286 : }
287 :
288 605 : void ResetDataHandlerCounter()
289 : {
290 605 : m_nDataHandlerCounter = 0;
291 605 : }
292 :
293 : const char *GetFID(void *attr) override;
294 : CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
295 : virtual char *GetAttributeValue(void *attr,
296 : const char *pszAttributeName) override;
297 : virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
298 : char **ppszKey) override;
299 :
300 : static void XMLCALL startElementCbk(void *pUserData, const char *pszName,
301 : const char **ppszAttr);
302 :
303 : static void XMLCALL endElementCbk(void *pUserData, const char *pszName);
304 :
305 : static void XMLCALL dataHandlerCbk(void *pUserData, const char *data,
306 : int nLen);
307 : };
308 :
309 : #endif
310 :
311 : /************************************************************************/
312 : /* GMLReadState */
313 : /************************************************************************/
314 :
315 : class GMLReadState
316 : {
317 : std::vector<std::string> aosPathComponents{};
318 :
319 : CPL_DISALLOW_COPY_ASSIGN(GMLReadState)
320 :
321 : public:
322 939 : GMLReadState() = default;
323 939 : ~GMLReadState() = default;
324 :
325 : void PushPath(const char *pszElement, int nLen = -1);
326 : void PopPath();
327 :
328 6331 : const char *GetLastComponent() const
329 : {
330 6331 : return (m_nPathLength == 0)
331 6331 : ? ""
332 6331 : : aosPathComponents[m_nPathLength - 1].c_str();
333 : }
334 :
335 6147 : size_t GetLastComponentLen() const
336 : {
337 6147 : return (m_nPathLength == 0)
338 6147 : ? 0
339 6147 : : aosPathComponents[m_nPathLength - 1].size();
340 : }
341 :
342 : void Reset();
343 :
344 : GMLFeature *m_poFeature = nullptr;
345 : GMLReadState *m_poParentState = nullptr;
346 :
347 : std::string osPath{}; // element path ... | as separator.
348 : int m_nPathLength = 0;
349 : };
350 :
351 : /************************************************************************/
352 : /* GMLReader */
353 : /************************************************************************/
354 :
355 : class GMLReader final : public IGMLReader
356 : {
357 : private:
358 : bool m_bClassListLocked = false;
359 :
360 : int m_nClassCount = 0;
361 : GMLFeatureClass **m_papoClass = nullptr;
362 : bool m_bLookForClassAtAnyLevel = false;
363 :
364 : char *m_pszFilename = nullptr;
365 :
366 : #ifndef HAVE_XERCES
367 : bool bUseExpatReader = true;
368 : #else
369 : bool bUseExpatReader = false;
370 : #endif
371 :
372 : GMLHandler *m_poGMLHandler = nullptr;
373 :
374 : #if defined(HAVE_XERCES)
375 : SAX2XMLReader *m_poSAXReader = nullptr;
376 : XMLPScanToken m_oToFill{};
377 : GMLFeature *m_poCompleteFeature = nullptr;
378 : InputSource *m_GMLInputSource = nullptr;
379 : bool m_bEOF = false;
380 : bool m_bXercesInitialized = false;
381 : bool SetupParserXerces();
382 : GMLFeature *NextFeatureXerces();
383 : #endif
384 :
385 : #if defined(HAVE_EXPAT)
386 : XML_Parser oParser = nullptr;
387 : GMLFeature **ppoFeatureTab = nullptr;
388 : int nFeatureTabLength = 0;
389 : int nFeatureTabIndex = 0;
390 : int nFeatureTabAlloc = 0;
391 : bool SetupParserExpat();
392 : GMLFeature *NextFeatureExpat();
393 : char *pabyBuf = nullptr;
394 : CPLString m_osErrorMessage{};
395 : #endif
396 :
397 : VSILFILE *fpGML = nullptr;
398 : bool m_bReadStarted = false;
399 :
400 : GMLReadState *m_poState = nullptr;
401 : GMLReadState *m_poRecycledState = nullptr;
402 :
403 : bool m_bStopParsing = false;
404 :
405 : bool SetupParser();
406 : void CleanupParser();
407 :
408 : bool m_bFetchAllGeometries = false;
409 :
410 : bool m_bInvertAxisOrderIfLatLong = false;
411 : bool m_bConsiderEPSGAsURN = false;
412 : GMLSwapCoordinatesEnum m_eSwapCoordinates = GML_SWAP_AUTO;
413 : bool m_bGetSecondaryGeometryOption = false;
414 :
415 : int ParseFeatureType(CPLXMLNode *psSchemaNode, const char *pszName,
416 : const char *pszType);
417 :
418 : char *m_pszGlobalSRSName = nullptr;
419 : bool m_bCanUseGlobalSRSName = false;
420 :
421 : char *m_pszFilteredClassName = nullptr;
422 : int m_nFilteredClassIndex = -1;
423 :
424 : int m_nHasSequentialLayers = -1;
425 :
426 : std::string osElemPath{};
427 :
428 : bool m_bFaceHoleNegative = false;
429 :
430 : bool m_bSetWidthFlag = true;
431 :
432 : bool m_bReportAllAttributes = false;
433 :
434 : bool m_bIsWFSJointLayer = false;
435 :
436 : bool m_bEmptyAsNull = true;
437 :
438 : bool m_bUseBBOX = false;
439 :
440 : bool ParseXMLHugeFile(const char *pszOutputFilename,
441 : const bool bSqliteIsTempFile,
442 : const int iSqliteCacheMB);
443 :
444 : CPL_DISALLOW_COPY_ASSIGN(GMLReader)
445 :
446 : public:
447 : GMLReader(bool bExpatReader, bool bInvertAxisOrderIfLatLong,
448 : bool bConsiderEPSGAsURN, GMLSwapCoordinatesEnum eSwapCoordinates,
449 : bool bGetSecondaryGeometryOption);
450 : ~GMLReader() override;
451 :
452 0 : bool IsClassListLocked() const override
453 : {
454 0 : return m_bClassListLocked;
455 : }
456 :
457 466 : void SetClassListLocked(bool bFlag) override
458 : {
459 466 : m_bClassListLocked = bFlag;
460 466 : }
461 :
462 : void SetSourceFile(const char *pszFilename) override;
463 : void SetFP(VSILFILE *fp) override;
464 : const char *GetSourceFileName() override;
465 :
466 3713 : int GetClassCount() const override
467 : {
468 3713 : return m_nClassCount;
469 : }
470 :
471 : GMLFeatureClass *GetClass(int i) const override;
472 : GMLFeatureClass *GetClass(const char *pszName) const override;
473 :
474 : int AddClass(GMLFeatureClass *poClass) override;
475 : void ClearClasses() override;
476 :
477 : GMLFeature *NextFeature() override;
478 :
479 : bool LoadClasses(const char *pszFile = nullptr) override;
480 : bool SaveClasses(const char *pszFile = nullptr) override;
481 :
482 : bool ResolveXlinks(const char *pszFile, bool *pbOutIsTempFile,
483 : char **papszSkip = nullptr,
484 : const bool bStrict = false) override;
485 :
486 : bool HugeFileResolver(const char *pszFile, bool bSqliteIsTempFile,
487 : int iSqliteCacheMB) override;
488 :
489 : bool PrescanForSchema(bool bGetExtents = true,
490 : bool bOnlyDetectSRS = false) override;
491 : bool PrescanForTemplate() override;
492 : bool ReArrangeTemplateClasses(GFSTemplateList *pCC);
493 : void ResetReading() override;
494 :
495 : // ---
496 :
497 68340 : GMLReadState *GetState() const
498 : {
499 68340 : return m_poState;
500 : }
501 :
502 : void PopState();
503 : void PushState(GMLReadState *);
504 :
505 6984 : bool ShouldLookForClassAtAnyLevel()
506 : {
507 6984 : return m_bLookForClassAtAnyLevel;
508 : }
509 :
510 : int GetFeatureElementIndex(const char *pszElement, int nLen,
511 : GMLAppSchemaType eAppSchemaType);
512 : int GetAttributeElementIndex(const char *pszElement, int nLen,
513 : const char *pszAttrKey = nullptr);
514 : bool IsCityGMLGenericAttributeElement(const char *pszElement, void *attr);
515 :
516 : void PushFeature(const char *pszElement, const char *pszFID,
517 : int nClassIndex);
518 :
519 : void SetFeaturePropertyDirectly(const char *pszElement, char *pszValue,
520 : int iPropertyIn,
521 : GMLPropertyType eType = GMLPT_Untyped);
522 :
523 8 : void SetWidthFlag(bool bFlag)
524 : {
525 8 : m_bSetWidthFlag = bFlag;
526 8 : }
527 :
528 121 : bool HasStoppedParsing() override
529 : {
530 121 : return m_bStopParsing;
531 : }
532 :
533 4965 : bool FetchAllGeometries()
534 : {
535 4965 : return m_bFetchAllGeometries;
536 : }
537 :
538 : void SetGlobalSRSName(const char *pszGlobalSRSName) override;
539 :
540 519 : const char *GetGlobalSRSName() override
541 : {
542 519 : return m_pszGlobalSRSName;
543 : }
544 :
545 1103 : bool CanUseGlobalSRSName() override
546 : {
547 1103 : return m_bCanUseGlobalSRSName;
548 : }
549 :
550 : bool SetFilteredClassName(const char *pszClassName) override;
551 :
552 4328 : const char *GetFilteredClassName() override
553 : {
554 4328 : return m_pszFilteredClassName;
555 : }
556 :
557 49 : int GetFilteredClassIndex()
558 : {
559 49 : return m_nFilteredClassIndex;
560 : }
561 :
562 88 : bool IsSequentialLayers() const override
563 : {
564 88 : return m_nHasSequentialLayers == TRUE;
565 : }
566 :
567 457 : void SetReportAllAttributes(bool bFlag)
568 : {
569 457 : m_bReportAllAttributes = bFlag;
570 457 : }
571 :
572 511 : bool ReportAllAttributes() const
573 : {
574 511 : return m_bReportAllAttributes;
575 : }
576 :
577 457 : void SetIsWFSJointLayer(bool bFlag)
578 : {
579 457 : m_bIsWFSJointLayer = bFlag;
580 457 : }
581 :
582 29386 : bool IsWFSJointLayer() const
583 : {
584 29386 : return m_bIsWFSJointLayer;
585 : }
586 :
587 457 : void SetEmptyAsNull(bool bFlag)
588 : {
589 457 : m_bEmptyAsNull = bFlag;
590 457 : }
591 :
592 70 : bool IsEmptyAsNull() const
593 : {
594 70 : return m_bEmptyAsNull;
595 : }
596 :
597 457 : void SetUseBBOX(bool bFlag)
598 : {
599 457 : m_bUseBBOX = bFlag;
600 457 : }
601 :
602 909 : bool UseBBOX() const
603 : {
604 909 : return m_bUseBBOX;
605 : }
606 :
607 : static CPLMutex *hMutex;
608 : };
609 :
610 : #endif /* CPL_GMLREADERP_H_INCLUDED */
|