Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: S-101 driver
4 : * Purpose: Header file
5 : * Author: Even Rouault <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef OGR_S101_H_INCLUDED
14 : #define OGR_S101_H_INCLUDED
15 :
16 : #include "ogrsf_frmts.h"
17 : #include "iso8211.h"
18 : #include "ddfrecordindex.h"
19 :
20 : #include "cpl_int_wrapper.h"
21 : #include "cpl_string.h"
22 :
23 : #include <map>
24 : #include <set>
25 : #include <string_view>
26 :
27 : /************************************************************************/
28 : /* OGRS101Reader */
29 : /************************************************************************/
30 :
31 : class OGRS101FeatureCatalog;
32 :
33 : namespace OGRS101FeatureCatalogTypes
34 : {
35 : struct InformationType;
36 : struct FeatureType;
37 : } // namespace OGRS101FeatureCatalogTypes
38 :
39 710 : class OGRS101Reader
40 : {
41 : public:
42 : struct CRSIdTag
43 : {
44 : };
45 :
46 : using CRSId = cpl::IntWrapper<CRSIdTag>;
47 :
48 : static constexpr CRSId INVALID_CRS_ID{-1};
49 : static constexpr CRSId HORIZONTAL_CRS_ID{1};
50 :
51 : struct RecordNameTag
52 : {
53 : };
54 :
55 : // Record "name" is a poor naming from the S100 spec. It is actually
56 : // a numeric value
57 : using RecordName = cpl::IntWrapper<RecordNameTag>;
58 :
59 : private:
60 : /////////////////////////////////////////////////////////////////////////
61 : // Members
62 : /////////////////////////////////////////////////////////////////////////
63 :
64 : bool m_bStrict = true;
65 : std::string m_osFilename{};
66 : std::unique_ptr<DDFModule> m_poModule{};
67 :
68 : CPLStringList m_aosMetadata{};
69 :
70 : // DSSI field
71 : static constexpr double S101_SHIFT = 0;
72 : double m_dfXShift = S101_SHIFT; // DCOX
73 : double m_dfYShift = S101_SHIFT; // DCOY
74 : double m_dfZShift = S101_SHIFT; // DCOZ
75 : static constexpr int S101_XSCALE = 10000000;
76 : int m_nXScale = S101_XSCALE; // CMFX
77 : static constexpr int S101_YSCALE = 10000000;
78 : int m_nYScale = S101_YSCALE; // CMFY
79 : static constexpr int S101_ZSCALE = 10;
80 : int m_nZScale = S101_ZSCALE; // CMFZ
81 : int m_nCountInformationRecord = 0; // NOIR
82 : int m_nCountPointRecord = 0; // NOPN
83 : int m_nCountMultiPointRecord = 0; // NOMN
84 : int m_nCountCurveRecord = 0; // NOCN
85 : int m_nCountCompositeCurveRecord = 0; // NOXN
86 : int m_nCountSurfaceRecord = 0; // NOSN
87 : int m_nCountFeatureTypeRecord = 0; // NOFR
88 :
89 : struct AttrCodeTag
90 : {
91 : };
92 :
93 : using AttrCode = cpl::IntWrapper<AttrCodeTag>;
94 : // from ATCS field
95 : std::map<AttrCode, std::string> m_attributeCodes{};
96 :
97 : struct InfoTypeCodeTag
98 : {
99 : };
100 :
101 : using InfoTypeCode = cpl::IntWrapper<InfoTypeCodeTag>;
102 : // from ITCS field
103 : std::map<InfoTypeCode, std::string> m_informationTypeCodes{};
104 :
105 : struct FeatureTypeCodeTag
106 : {
107 : };
108 :
109 : using FeatureTypeCode = cpl::IntWrapper<FeatureTypeCodeTag>;
110 : // from FTCS field
111 : std::map<FeatureTypeCode, std::string> m_featureTypeCodes{};
112 :
113 : struct InfoAssocCodeTag
114 : {
115 : };
116 :
117 : using InfoAssocCode = cpl::IntWrapper<InfoAssocCodeTag>;
118 : // from IACS field
119 : std::map<InfoAssocCode, std::string> m_informationAssociationCodes{};
120 :
121 : struct FeatureAssocCodeTag
122 : {
123 : };
124 :
125 : using FeatureAssocCode = cpl::IntWrapper<FeatureAssocCodeTag>;
126 : // from FACS field
127 : std::map<FeatureAssocCode, std::string> m_featureAssociationCodes{};
128 :
129 : struct AssocRoleCodeTag
130 : {
131 : };
132 :
133 : using AssocRoleCode = cpl::IntWrapper<AssocRoleCodeTag>;
134 : // from ARCS field
135 : std::map<AssocRoleCode, std::string> m_associationRoleCodes{};
136 :
137 : static constexpr RecordName PSEUDO_RECORD_NAME_NO_GEOM{-1111111111};
138 :
139 : /** Triple (feature type code, geometry type, CRS Id) */
140 : struct FeatureTypeKey
141 : {
142 : FeatureTypeCode nFeatureTypeCode{0};
143 : RecordName nGeometryType{PSEUDO_RECORD_NAME_NO_GEOM};
144 : CRSId nCRSId{INVALID_CRS_ID};
145 :
146 : // I'd wish I could use C++20
147 2946 : inline bool operator<(const FeatureTypeKey &other) const
148 : {
149 2946 : return toTuple() < other.toTuple();
150 : }
151 :
152 : private:
153 5892 : inline std::tuple<int, int, int> toTuple() const
154 : {
155 0 : return std::make_tuple(static_cast<int>(nFeatureTypeCode),
156 5892 : static_cast<int>(nGeometryType),
157 17676 : static_cast<int>(nCRSId));
158 : }
159 : };
160 :
161 : // key is the crs index (CRIX). 1: Horizontal CRS. >= 2: CompoundCRS
162 : std::map<CRSId, OGRSpatialReference> m_oMapSRS{};
163 :
164 : DDFRecordIndex m_oInformationTypeRecordIndex{};
165 : DDFRecordIndex m_oPointRecordIndex{};
166 : DDFRecordIndex m_oMultiPointRecordIndex{};
167 : DDFRecordIndex m_oCurveRecordIndex{};
168 : DDFRecordIndex m_oCompositeCurveRecordIndex{};
169 : DDFRecordIndex m_oSurfaceRecordIndex{};
170 : DDFRecordIndex m_oFeatureTypeRecordIndex{};
171 :
172 : OGRFeatureDefnRefCountedPtr m_poFeatureDefnInformationType{};
173 :
174 : std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapPointFeatureDefn{};
175 : std::map<CRSId, std::vector<int>> m_oMapCRSIdToPointRecordIdx{};
176 :
177 : std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapMultiPointFeatureDefn{};
178 : std::map<CRSId, std::vector<int>> m_oMapCRSIdToMultiPointRecordIdx{};
179 :
180 : OGRFeatureDefnRefCountedPtr m_poFeatureDefnCurve{};
181 : OGRFeatureDefnRefCountedPtr m_poFeatureDefnCompositeCurve{};
182 : OGRFeatureDefnRefCountedPtr m_poFeatureDefnSurface{};
183 :
184 : struct LayerDef
185 : {
186 : OGRFeatureDefnRefCountedPtr poFeatureDefn{};
187 : std::string osName{};
188 : std::string osDefinition{};
189 : std::string osAlias{};
190 : std::vector<int> anRecordIndices{};
191 : };
192 :
193 : std::map<FeatureTypeKey, LayerDef> m_oMapFeatureKeyToLayerDef{};
194 : std::map<int, const OGRFeatureDefn *> m_oMapFeatureTypeIdToFDefn{};
195 :
196 : std::map<std::string, std::unique_ptr<OGRFieldDomain>> m_oMapFieldDomains{};
197 :
198 : const OGRS101FeatureCatalog *m_poFeatureCatalog = nullptr;
199 :
200 : /////////////////////////////////////////////////////////////////////////
201 : // Methods
202 : /////////////////////////////////////////////////////////////////////////
203 :
204 : bool CheckFieldDefinitions() const;
205 : bool CheckField0000Definition() const;
206 :
207 : bool ReadDatasetGeneralInformationRecord(const DDFRecord *poRecord);
208 : bool ReadDSID(const DDFRecord *poRecord);
209 : bool ReadDSSI(const DDFRecord *poRecord);
210 :
211 : template <class CodeType>
212 : bool ReadGenericCodeAssociation(const DDFRecord *poRecord,
213 : const char *pszFieldName,
214 : const char *pszSubField0Name,
215 : const char *pszSubField1Name,
216 : std::map<CodeType, std::string> &map) const;
217 :
218 : bool ReadATCS(const DDFRecord *poRecord);
219 : bool ReadITCS(const DDFRecord *poRecord);
220 : bool ReadFTCS(const DDFRecord *poRecord);
221 : bool ReadIACS(const DDFRecord *poRecord);
222 : bool ReadFACS(const DDFRecord *poRecord);
223 : bool ReadARCS(const DDFRecord *poRecord);
224 :
225 : bool ReadCSID(const DDFRecord *poRecord);
226 :
227 : bool IngestRecords(const DDFRecord *poRecordIn);
228 :
229 : // Type for PAIX subfield (parent index)
230 : struct AttrIndexTag
231 : {
232 : };
233 :
234 : using AttrIndex = cpl::IntWrapper<AttrIndexTag>;
235 :
236 : // Type for ATIX subfield (attribute index)
237 : struct AttrRepeatTag
238 : {
239 : };
240 :
241 : using AttrRepeat = cpl::IntWrapper<AttrRepeatTag>;
242 :
243 : using PathElement = std::pair<AttrCode, AttrRepeat>;
244 : using PathVector = std::vector<PathElement>;
245 :
246 : // Capture essential information for a repetition of the ATTR field
247 : struct S101AttrDef
248 : {
249 : PathVector oReversedPath{}; // ordered from child to root
250 : std::string osVal{};
251 : int iField = 0;
252 : bool bMultipleFields = false;
253 : bool bIsParent = false;
254 : };
255 :
256 : bool ReadFeatureCatalog();
257 :
258 : std::string BuildFieldName(const PathVector &oReversedPath,
259 : const char *pszAttrFieldName, int iField,
260 : bool bMultipleFields,
261 : const char *pszIDFieldName) const;
262 :
263 : bool CreateInformationTypeFeatureDefn();
264 : bool CreatePointFeatureDefns();
265 : bool CreateMultiPointFeatureDefns();
266 : bool CreateCurveFeatureDefn();
267 : bool CreateCompositeCurveFeatureDefn();
268 : bool CreateSurfaceFeatureDefn();
269 : bool CreateFeatureTypeFeatureDefns();
270 :
271 : bool InferFeatureDefn(
272 : const DDFRecordIndex &oIndex, const char *pszIDFieldName,
273 : const char *pszAttrFieldName, const std::vector<int> &anRecordIndices,
274 : OGRFeatureDefn &oFeatureDefn,
275 : std::map<std::string, std::unique_ptr<OGRFieldDomain>>
276 : &oMapFieldDomains,
277 : const OGRS101FeatureCatalogTypes::InformationType *psInformationType =
278 : nullptr,
279 : const OGRS101FeatureCatalogTypes::FeatureType *psFeatureType =
280 : nullptr) const;
281 :
282 : bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
283 : const char *pszIDFieldName,
284 : const char *pszAttrFieldName,
285 : const DDFField *poATTRField, int iField,
286 : bool bMultipleFields,
287 : std::vector<S101AttrDef> &asS101AttrDefs) const;
288 :
289 : bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
290 : const char *pszIDFieldName,
291 : const char *pszAttrFieldName,
292 : std::vector<S101AttrDef> &asS101AttrDefs) const;
293 :
294 : bool FillFeatureAttributes(const DDFRecordIndex &oIndex, int iRecord,
295 : const char *pszAttrFieldName,
296 : OGRFeature &oFeature) const;
297 :
298 : CRSId GetCRSIdForPointRecord(const DDFRecord *poRecord, int iRecord,
299 : int nRecordID) const;
300 :
301 : std::map<OGRS101Reader::CRSId, std::vector<int>>
302 : CreateMapCRSIdToRecordIdxForPoints(bool &bError) const;
303 :
304 : CRSId GetCRSIdForMultiPointRecord(const DDFRecord *poRecord, int iRecord,
305 : int nRecordID) const;
306 :
307 : std::map<OGRS101Reader::CRSId, std::vector<int>>
308 : CreateMapCRSIdToRecordIdxForMultiPoints(bool &bError) const;
309 :
310 : bool FillFeatureWithNonAttrAssocSubfields(const DDFRecord *poRecord,
311 : int iRecord,
312 : const char *pszAttrFieldName,
313 : OGRFeature &oFeature) const;
314 :
315 : std::unique_ptr<OGRPoint> ReadPointGeometryInternal(
316 : const DDFRecord *poRecord, int iRecord, int nRecordID, int iPnt,
317 : const OGRSpatialReference *poSRS, const bool bIs3D,
318 : const DDFField *poCoordField, const char *pszRecordFieldName) const;
319 :
320 : std::unique_ptr<OGRPoint>
321 : ReadPointGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
322 : const OGRSpatialReference *poSRS) const;
323 :
324 : std::unique_ptr<OGRMultiPoint>
325 : ReadMultiPointGeometry(const DDFRecord *poRecord, int iRecord,
326 : int nRecordID,
327 : const OGRSpatialReference *poSRS) const;
328 :
329 : std::unique_ptr<OGRLineString>
330 : ReadCurveGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
331 : const OGRSpatialReference *poSRS) const;
332 :
333 : std::unique_ptr<OGRLineString> ReadCompositeCurveGeometryInternal(
334 : const DDFRecord *poRecord, int iRecord, int nRecordID,
335 : const OGRSpatialReference *poSRS,
336 : std::set<int> &oSetAlreadyVisitedCompositeCurveRecords) const;
337 :
338 : std::unique_ptr<OGRLineString>
339 : ReadCompositeCurveGeometry(const DDFRecord *poRecord, int iRecord,
340 : int nRecordID,
341 : const OGRSpatialReference *poSRS) const;
342 :
343 : std::unique_ptr<OGRPolygon>
344 : ReadSurfaceGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
345 : const OGRSpatialReference *poSRS) const;
346 :
347 : template <typename T, typename GeomReaderMethodType>
348 : bool ReadGeometry(const DDFRecordIndex &oIndex, const char *pszErrorContext,
349 : int nGeomRecordID, const char *pszGeomType, bool bReverse,
350 : OGRFeature &oFeature,
351 : std::unique_ptr<OGRGeometryCollection> &poMultiGeom,
352 : GeomReaderMethodType geomReaderMethod,
353 : int iGeomField = 0) const;
354 :
355 : bool FillFeatureTypeGeometry(const DDFRecord *poRecord, int iRecord,
356 : OGRFeature &oFeature) const;
357 :
358 : bool FillFeatureTypeMask(const DDFRecord *poRecord, int iRecord,
359 : OGRFeature &oFeature) const;
360 :
361 : static std::string LaunderCRSName(const OGRSpatialReference &oSRS);
362 : static std::string GetPointLayerName(const OGRSpatialReference &oSRS);
363 : static std::string GetMultiPointLayerName(const OGRSpatialReference &oSRS);
364 :
365 : OGRS101Reader(const OGRS101Reader &) = delete;
366 : OGRS101Reader &operator=(const OGRS101Reader &) = delete;
367 :
368 : protected:
369 : friend class OGRS101FeatureCatalog;
370 : static bool EmitErrorOrWarning(const char *pszFile, const char *pszFunc,
371 : int nLine, const char *pszMsg, bool bError,
372 : bool bRecoverable);
373 :
374 : public:
375 : OGRS101Reader();
376 : ~OGRS101Reader();
377 :
378 : bool Load(GDALOpenInfo *poOpenInfo);
379 :
380 : /** Return feature catalog, or null. */
381 2 : const OGRS101FeatureCatalog *GetFeatureCatalog() const
382 : {
383 2 : return m_poFeatureCatalog;
384 : }
385 :
386 : /** Return dataset metadata from the DSID field. */
387 242 : const CPLStringList &GetMetadata() const
388 : {
389 242 : return m_aosMetadata;
390 : }
391 :
392 : /** Return InformationType records */
393 156 : const DDFRecordIndex &GetInformationTypeRecords() const
394 : {
395 156 : return m_oInformationTypeRecordIndex;
396 : }
397 :
398 : /** Return Point records */
399 150 : const DDFRecordIndex &GetPointRecords() const
400 : {
401 150 : return m_oPointRecordIndex;
402 : }
403 :
404 : /** Return MultiPoint records */
405 56 : const DDFRecordIndex &GetMultiPointRecords() const
406 : {
407 56 : return m_oMultiPointRecordIndex;
408 : }
409 :
410 : /** Return Curve records */
411 106 : const DDFRecordIndex &GetCurveRecords() const
412 : {
413 106 : return m_oCurveRecordIndex;
414 : }
415 :
416 : /** Return CompositeCurve records */
417 81 : const DDFRecordIndex &GetCompositeCurveRecords() const
418 : {
419 81 : return m_oCompositeCurveRecordIndex;
420 : }
421 :
422 : /** Return Surface records */
423 63 : const DDFRecordIndex &GetSurfaceRecords() const
424 : {
425 63 : return m_oSurfaceRecordIndex;
426 : }
427 :
428 : /** Return FeatureType records */
429 282 : const DDFRecordIndex &GetFeatureTypeRecords() const
430 : {
431 282 : return m_oFeatureTypeRecordIndex;
432 : }
433 :
434 : /** Return (and steal) the layer definition for InformationType features */
435 242 : OGRFeatureDefnRefCountedPtr StealInformationTypeFeatureDefn()
436 : {
437 242 : return std::move(m_poFeatureDefnInformationType);
438 : }
439 :
440 : /** Return a map from a CRSId to the layer definition for Point features */
441 242 : std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealPointFeatureDefns()
442 : {
443 242 : return m_oMapPointFeatureDefn;
444 : }
445 :
446 : /** Return a map from a CRSId to the layer definition for MultiPoint features */
447 242 : std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealMultiPointFeatureDefns()
448 : {
449 242 : return m_oMapMultiPointFeatureDefn;
450 : }
451 :
452 : /** Return (and steal) a map from a feature type key to the layer definition */
453 242 : std::map<FeatureTypeKey, LayerDef> &StealFeatureTypeLayerDefs()
454 : {
455 242 : return m_oMapFeatureKeyToLayerDef;
456 : }
457 :
458 : /** Return (and steal) the layer definition for curve records */
459 242 : OGRFeatureDefnRefCountedPtr StealCurveFeatureDefn()
460 : {
461 242 : return std::move(m_poFeatureDefnCurve);
462 : }
463 :
464 : /** Return (and steal) the layer definition for composite curve records */
465 242 : OGRFeatureDefnRefCountedPtr StealCompositeCurveFeatureDefn()
466 : {
467 242 : return std::move(m_poFeatureDefnCompositeCurve);
468 : }
469 :
470 : /** Return (and steal) the layer definition for surface records */
471 242 : OGRFeatureDefnRefCountedPtr StealSurfaceFeatureDefn()
472 : {
473 242 : return std::move(m_poFeatureDefnSurface);
474 : }
475 :
476 : /** Return the map from CRS id to indexes of Point records */
477 : const std::map<OGRS101Reader::CRSId, std::vector<int>> &
478 150 : GetMapCRSIdToRecordIdxForPoints() const
479 : {
480 150 : return m_oMapCRSIdToPointRecordIdx;
481 : }
482 :
483 : /** Return the map from CRS id to indexes of MultiPoint records */
484 : const std::map<OGRS101Reader::CRSId, std::vector<int>> &
485 56 : GetMapCRSIdToRecordIdxForMultiPoints() const
486 : {
487 56 : return m_oMapCRSIdToMultiPointRecordIdx;
488 : }
489 :
490 : /** Return (and steal) the field domains */
491 242 : std::map<std::string, std::unique_ptr<OGRFieldDomain>> &StealFieldDomains()
492 : {
493 242 : return m_oMapFieldDomains;
494 : }
495 :
496 : bool FillFeatureInformationType(const DDFRecordIndex &oIndex, int iRecord,
497 : OGRFeature &oFeature) const;
498 :
499 : bool FillFeaturePoint(const DDFRecordIndex &oIndex, int iRecord,
500 : OGRFeature &oFeature) const;
501 :
502 : bool FillFeatureMultiPoint(const DDFRecordIndex &oIndex, int iRecord,
503 : OGRFeature &oFeature) const;
504 :
505 : bool FillFeatureCurve(const DDFRecordIndex &oIndex, int iRecord,
506 : OGRFeature &oFeature) const;
507 :
508 : bool FillFeatureCompositeCurve(const DDFRecordIndex &oIndex, int iRecord,
509 : OGRFeature &oFeature) const;
510 :
511 : bool FillFeatureSurface(const DDFRecordIndex &oIndex, int iRecord,
512 : OGRFeature &oFeature) const;
513 :
514 : bool FillFeatureFeatureType(const DDFRecordIndex &oIndex, int iRecord,
515 : OGRFeature &oFeature) const;
516 : };
517 :
518 : /** Emit an error in strict mode (and return false),
519 : * or an error in non-strict mode (and return true) */
520 : #define EMIT_ERROR_OR_WARNING(msg) \
521 : EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, m_bStrict, true)
522 :
523 : /** Emit an error */
524 : #define EMIT_ERROR(msg) \
525 : EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, true, false)
526 :
527 : /************************************************************************/
528 : /* OGRS101Dataset */
529 : /************************************************************************/
530 :
531 : class OGRS101Dataset final : public GDALDataset
532 : {
533 : std::unique_ptr<OGRS101Reader> m_poReader{};
534 : std::vector<std::unique_ptr<OGRLayer>> m_apoLayers{};
535 :
536 : public:
537 355 : OGRS101Dataset() = default;
538 :
539 : int GetLayerCount() const override;
540 : OGRLayer *GetLayer(int) const override;
541 :
542 3002 : const OGRS101Reader &GetReader() const
543 : {
544 3002 : return *m_poReader;
545 : }
546 :
547 : int TestCapability(const char *) const override;
548 :
549 : static GDALDataset *Open(GDALOpenInfo *poOpenInfo);
550 : static void UnloadDriver(GDALDriver *);
551 : };
552 :
553 : /************************************************************************/
554 : /* OGRS101Layer() */
555 : /************************************************************************/
556 :
557 894 : class OGRS101Layer /* non final */ : public OGRLayer
558 : {
559 : public:
560 : OGRS101Layer(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
561 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
562 : ~OGRS101Layer() override;
563 :
564 13932 : const OGRFeatureDefn *GetLayerDefn() const override
565 : {
566 13932 : return m_poFeatureDefn.get();
567 : }
568 :
569 : void ResetReading() override;
570 :
571 : int TestCapability(const char *) const override;
572 :
573 : GIntBig GetFeatureCount(int bForce) override;
574 :
575 : protected:
576 : const OGRS101Dataset &m_oDS;
577 : const DDFRecordIndex &m_oIndex;
578 : const OGRFeatureDefnRefCountedPtr m_poFeatureDefn{};
579 : int m_nRecordIdx = 0;
580 :
581 : private:
582 : CPL_DISALLOW_COPY_ASSIGN(OGRS101Layer)
583 : };
584 :
585 : /************************************************************************/
586 : /* OGRS101LayerInformationType() */
587 : /************************************************************************/
588 :
589 : class OGRS101LayerInformationType final
590 : : public OGRS101Layer,
591 : OGRGetNextFeatureThroughRaw<OGRS101LayerInformationType>
592 : {
593 : public:
594 : OGRS101LayerInformationType(OGRS101Dataset &oDS,
595 : const DDFRecordIndex &oIndex,
596 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
597 :
598 : OGRFeature *GetNextRawFeature();
599 :
600 : OGRFeature *GetFeature(GIntBig nFID) override;
601 :
602 569 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerInformationType)
603 : };
604 :
605 : /************************************************************************/
606 : /* OGRS101LayerPoint() */
607 : /************************************************************************/
608 :
609 : class OGRS101LayerPoint final : public OGRS101Layer,
610 : OGRGetNextFeatureThroughRaw<OGRS101LayerPoint>
611 : {
612 : public:
613 : OGRS101LayerPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
614 : const std::vector<int> &anRecordIndices,
615 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
616 :
617 : OGRFeature *GetNextRawFeature();
618 :
619 : GIntBig GetFeatureCount(int bForce) override;
620 :
621 : OGRFeature *GetFeature(GIntBig nFID) override;
622 :
623 891 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerPoint)
624 :
625 : private:
626 : const std::vector<int> &m_anRecordIndices;
627 : };
628 :
629 : /************************************************************************/
630 : /* OGRS101LayerMultiPoint() */
631 : /************************************************************************/
632 :
633 : class OGRS101LayerMultiPoint final
634 : : public OGRS101Layer,
635 : OGRGetNextFeatureThroughRaw<OGRS101LayerMultiPoint>
636 : {
637 : public:
638 : OGRS101LayerMultiPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
639 : const std::vector<int> &anRecordIndices,
640 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
641 :
642 : OGRFeature *GetNextRawFeature();
643 :
644 : GIntBig GetFeatureCount(int bForce) override;
645 :
646 : OGRFeature *GetFeature(GIntBig nFID) override;
647 :
648 309 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerMultiPoint)
649 :
650 : private:
651 : const std::vector<int> &m_anRecordIndices;
652 : };
653 :
654 : /************************************************************************/
655 : /* OGRS101LayerCurve() */
656 : /************************************************************************/
657 :
658 : class OGRS101LayerCurve final : public OGRS101Layer,
659 : OGRGetNextFeatureThroughRaw<OGRS101LayerCurve>
660 : {
661 : public:
662 : OGRS101LayerCurve(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
663 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
664 :
665 : OGRFeature *GetNextRawFeature();
666 :
667 : OGRFeature *GetFeature(GIntBig nFID) override;
668 :
669 625 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCurve)
670 : };
671 :
672 : /************************************************************************/
673 : /* OGRS101LayerCompositeCurve() */
674 : /************************************************************************/
675 :
676 : class OGRS101LayerCompositeCurve final
677 : : public OGRS101Layer,
678 : OGRGetNextFeatureThroughRaw<OGRS101LayerCompositeCurve>
679 : {
680 : public:
681 : OGRS101LayerCompositeCurve(OGRS101Dataset &oDS,
682 : const DDFRecordIndex &oIndex,
683 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
684 :
685 : OGRFeature *GetNextRawFeature();
686 :
687 : OGRFeature *GetFeature(GIntBig nFID) override;
688 :
689 379 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCompositeCurve)
690 : };
691 :
692 : /************************************************************************/
693 : /* OGRS101LayerSurface() */
694 : /************************************************************************/
695 :
696 : class OGRS101LayerSurface final
697 : : public OGRS101Layer,
698 : OGRGetNextFeatureThroughRaw<OGRS101LayerSurface>
699 : {
700 : public:
701 : OGRS101LayerSurface(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
702 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
703 :
704 : OGRFeature *GetNextRawFeature();
705 :
706 : OGRFeature *GetFeature(GIntBig nFID) override;
707 :
708 213 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerSurface)
709 : };
710 :
711 : /************************************************************************/
712 : /* OGRS101LayerFeatureType() */
713 : /************************************************************************/
714 :
715 : class OGRS101LayerFeatureType final
716 : : public OGRS101Layer,
717 : OGRGetNextFeatureThroughRaw<OGRS101LayerFeatureType>
718 : {
719 : public:
720 : OGRS101LayerFeatureType(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
721 : const std::vector<int> &anRecordIndices,
722 : OGRFeatureDefnRefCountedPtr poFeatureDefn);
723 :
724 : OGRFeature *GetNextRawFeature();
725 :
726 : GIntBig GetFeatureCount(int bForce) override;
727 :
728 : OGRFeature *GetFeature(GIntBig nFID) override;
729 :
730 999 : DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerFeatureType)
731 :
732 : private:
733 : const std::vector<int> &m_anRecordIndices;
734 : };
735 :
736 : #endif // OGR_S101_H_INCLUDED
|