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 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #ifndef CPL_GMLREADERP_H_INCLUDED
16 : #define CPL_GMLREADERP_H_INCLUDED
17 :
18 : #if defined(HAVE_XERCES)
19 :
20 : #include "xercesc_headers.h"
21 : #include "ogr_xerces.h"
22 :
23 : #endif /* HAVE_XERCES */
24 :
25 : #include "cpl_string.h"
26 : #include "gmlreader.h"
27 : #include "ogr_api.h"
28 : #include "cpl_vsi.h"
29 : #include "cpl_multiproc.h"
30 : #include "gmlutils.h"
31 :
32 : #include <map>
33 : #include <string>
34 : #include <vector>
35 :
36 : #define PARSER_BUF_SIZE (10 * 8192)
37 :
38 : class GMLReader;
39 :
40 : typedef struct _GeometryNamesStruct GeometryNamesStruct;
41 :
42 : bool OGRGMLIsGeometryElement(const char *pszElement);
43 :
44 : /************************************************************************/
45 : /* GFSTemplateList */
46 : /************************************************************************/
47 :
48 : class GFSTemplateItem;
49 :
50 : class GFSTemplateList
51 : {
52 : private:
53 : bool m_bSequentialLayers;
54 : GFSTemplateItem *pFirst;
55 : GFSTemplateItem *pLast;
56 : GFSTemplateItem *Insert(const char *pszName);
57 :
58 : CPL_DISALLOW_COPY_ASSIGN(GFSTemplateList)
59 :
60 : public:
61 : GFSTemplateList();
62 : ~GFSTemplateList();
63 : void Update(const char *pszName, int bHasGeom);
64 :
65 6 : GFSTemplateItem *GetFirst()
66 : {
67 6 : return pFirst;
68 : }
69 :
70 3 : bool HaveSequentialLayers()
71 : {
72 3 : return m_bSequentialLayers;
73 : }
74 :
75 : int GetClassCount();
76 : };
77 :
78 : void gmlUpdateFeatureClasses(GFSTemplateList *pCC, GMLReader *pReader,
79 : int *pnHasSequentialLayers);
80 :
81 : /************************************************************************/
82 : /* GMLHandler */
83 : /************************************************************************/
84 :
85 : #define STACK_SIZE 5
86 :
87 : typedef enum
88 : {
89 : STATE_TOP,
90 : STATE_DEFAULT,
91 : STATE_FEATURE,
92 : STATE_PROPERTY,
93 : STATE_FEATUREPROPERTY,
94 : STATE_GEOMETRY,
95 : STATE_IGNORED_FEATURE,
96 : STATE_BOUNDED_BY,
97 : STATE_BOUNDED_BY_IN_FEATURE,
98 : STATE_CITYGML_ATTRIBUTE
99 : } HandlerState;
100 :
101 : typedef struct
102 : {
103 : CPLXMLNode *psNode;
104 : CPLXMLNode *psLastChild;
105 : } NodeLastChild;
106 :
107 : typedef enum
108 : {
109 : APPSCHEMA_GENERIC,
110 : APPSCHEMA_CITYGML,
111 : APPSCHEMA_AIXM,
112 : APPSCHEMA_MTKGML /* format of National Land Survey Finnish */
113 : } GMLAppSchemaType;
114 :
115 : class GMLHandler
116 : {
117 : char *m_pszCurField = nullptr;
118 : unsigned int m_nCurFieldAlloc = 0;
119 : unsigned int m_nCurFieldLen = 0;
120 : bool m_bInCurField = false;
121 : int m_nAttributeIndex = -1;
122 : int m_nAttributeDepth = 0;
123 :
124 : char *m_pszGeometry = nullptr;
125 : unsigned int m_nGeomAlloc = 0;
126 : unsigned int m_nGeomLen = 0;
127 : int m_nGeometryDepth = 0;
128 : bool m_bAlreadyFoundGeometry = false;
129 : int m_nGeometryPropertyIndex = 0;
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 : 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 512 : bool HasStoppedParsing()
282 : {
283 512 : return m_bStopParsing;
284 : }
285 :
286 517 : void ResetDataHandlerCounter()
287 : {
288 517 : m_nDataHandlerCounter = 0;
289 517 : }
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 802 : GMLReadState() = default;
321 802 : ~GMLReadState() = default;
322 :
323 : void PushPath(const char *pszElement, int nLen = -1);
324 : void PopPath();
325 :
326 5362 : const char *GetLastComponent() const
327 : {
328 5362 : return (m_nPathLength == 0)
329 5362 : ? ""
330 5362 : : aosPathComponents[m_nPathLength - 1].c_str();
331 : }
332 :
333 5178 : size_t GetLastComponentLen() const
334 : {
335 5178 : return (m_nPathLength == 0)
336 5178 : ? 0
337 5178 : : 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 401 : void SetClassListLocked(bool bFlag) override
456 : {
457 401 : m_bClassListLocked = bFlag;
458 401 : }
459 :
460 : void SetSourceFile(const char *pszFilename) override;
461 : void SetFP(VSILFILE *fp) override;
462 : const char *GetSourceFileName() override;
463 :
464 3358 : int GetClassCount() const override
465 : {
466 3358 : 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 53727 : GMLReadState *GetState() const
496 : {
497 53727 : return m_poState;
498 : }
499 :
500 : void PopState();
501 : void PushState(GMLReadState *);
502 :
503 6011 : bool ShouldLookForClassAtAnyLevel()
504 : {
505 6011 : 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 93 : bool HasStoppedParsing() override
527 : {
528 93 : return m_bStopParsing;
529 : }
530 :
531 3710 : bool FetchAllGeometries()
532 : {
533 3710 : return m_bFetchAllGeometries;
534 : }
535 :
536 : void SetGlobalSRSName(const char *pszGlobalSRSName) override;
537 :
538 468 : const char *GetGlobalSRSName() override
539 : {
540 468 : return m_pszGlobalSRSName;
541 : }
542 :
543 1009 : bool CanUseGlobalSRSName() override
544 : {
545 1009 : return m_bCanUseGlobalSRSName;
546 : }
547 :
548 : bool SetFilteredClassName(const char *pszClassName) override;
549 :
550 3594 : const char *GetFilteredClassName() override
551 : {
552 3594 : return m_pszFilteredClassName;
553 : }
554 :
555 49 : int GetFilteredClassIndex()
556 : {
557 49 : return m_nFilteredClassIndex;
558 : }
559 :
560 81 : bool IsSequentialLayers() const override
561 : {
562 81 : return m_nHasSequentialLayers == TRUE;
563 : }
564 :
565 396 : void SetReportAllAttributes(bool bFlag)
566 : {
567 396 : m_bReportAllAttributes = bFlag;
568 396 : }
569 :
570 433 : bool ReportAllAttributes() const
571 : {
572 433 : return m_bReportAllAttributes;
573 : }
574 :
575 396 : void SetIsWFSJointLayer(bool bFlag)
576 : {
577 396 : m_bIsWFSJointLayer = bFlag;
578 396 : }
579 :
580 23830 : bool IsWFSJointLayer() const
581 : {
582 23830 : return m_bIsWFSJointLayer;
583 : }
584 :
585 396 : void SetEmptyAsNull(bool bFlag)
586 : {
587 396 : m_bEmptyAsNull = bFlag;
588 396 : }
589 :
590 31 : bool IsEmptyAsNull() const
591 : {
592 31 : return m_bEmptyAsNull;
593 : }
594 :
595 396 : void SetUseBBOX(bool bFlag)
596 : {
597 396 : m_bUseBBOX = bFlag;
598 396 : }
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 */
|