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