Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: NTF Translator
4 : * Purpose: Main declarations for NTF translator.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Frank Warmerdam
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef NTF_H_INCLUDED
14 : #define NTF_H_INCLUDED
15 :
16 : #include "cpl_conv.h"
17 : #include "cpl_vsi.h"
18 : #include "ogrsf_frmts.h"
19 :
20 : /* -------------------------------------------------------------------- */
21 : /* Record types. */
22 : /* -------------------------------------------------------------------- */
23 : #define NRT_VHR 1 /* Volume Header Record */
24 : #define NRT_DHR 2 /* Database Header Record */
25 : #define NRT_FCR 5 /* Feature Classification Record */
26 : #define NRT_SHR 7 /* Section Header Record */
27 : #define NRT_NAMEREC 11 /* Name Record */
28 : #define NRT_NAMEPOSTN 12 /* Name Position */
29 : #define NRT_ATTREC 14 /* Attribute Record */
30 : #define NRT_POINTREC 15 /* Point Record */
31 : #define NRT_NODEREC 16 /* Node Record */
32 : #define NRT_GEOMETRY 21 /* Geometry Record */
33 : #define NRT_GEOMETRY3D 22 /* 3D Geometry Record */
34 : #define NRT_LINEREC 23 /* Line Record */
35 : #define NRT_CHAIN 24 /* Chain */
36 : #define NRT_POLYGON 31 /* Polygon */
37 : #define NRT_CPOLY 33 /* Complex Polygon */
38 : #define NRT_COLLECT 34 /* Collection of features */
39 : #define NRT_ADR 40 /* Attribute Description Record */
40 : #define NRT_CODELIST 42 /* Codelist Record (i.e. BL2000) */
41 : #define NRT_TEXTREC 43 /* Text */
42 : #define NRT_TEXTPOS 44 /* Text position */
43 : #define NRT_TEXTREP 45 /* Text representation */
44 : #define NRT_GRIDHREC 50 /* Grid Header Record */
45 : #define NRT_GRIDREC 51 /* Grid Data Record */
46 : #define NRT_COMMENT 90 /* Comment record */
47 : #define NRT_VTR 99 /* Volume Termination Record */
48 :
49 : /* -------------------------------------------------------------------- */
50 : /* Product names (DBNAME) and codes. */
51 : /* -------------------------------------------------------------------- */
52 :
53 : #define NPC_UNKNOWN 0
54 :
55 : #define NPC_LANDLINE 1
56 : #define NPC_LANDLINE99 2
57 : #define NTF_LANDLINE "LAND-LINE.93"
58 : #define NTF_LANDLINE_PLUS "LAND-LINE.93+"
59 :
60 : #define NPC_STRATEGI 3
61 : #define NTF_STRATEGI "Strategi_02.96"
62 :
63 : #define NPC_MERIDIAN 4
64 : #define NTF_MERIDIAN "Meridian_01.95"
65 :
66 : #define NPC_BOUNDARYLINE 5
67 : #define NTF_BOUNDARYLINE "Boundary-Line"
68 :
69 : #define NPC_BASEDATA 6
70 : #define NTF_BASEDATA "BaseData.GB_01.96"
71 :
72 : #define NPC_OSCAR_ASSET 7
73 : #define NPC_OSCAR_TRAFFIC 8
74 : #define NPC_OSCAR_ROUTE 9
75 : #define NPC_OSCAR_NETWORK 10
76 :
77 : #define NPC_ADDRESS_POINT 11
78 :
79 : #define NPC_CODE_POINT 12
80 : #define NPC_CODE_POINT_PLUS 13
81 :
82 : #define NPC_LANDFORM_PROFILE_CONT 14
83 :
84 : #define NPC_LANDRANGER_CONT 15
85 : #define NTF_LANDRANGER_CONT "OS_LANDRANGER_CONT"
86 :
87 : #define NPC_LANDRANGER_DTM 16
88 : #define NPC_LANDFORM_PROFILE_DTM 17
89 :
90 : #define NPC_BL2000 18
91 :
92 : #define NPC_MERIDIAN2 19
93 : #define NTF_MERIDIAN2 "Meridian_02.01"
94 :
95 : constexpr int MAX_LINK = 5000;
96 :
97 : /************************************************************************/
98 : /* NTFRecord */
99 : /************************************************************************/
100 :
101 : class NTFRecord
102 : {
103 : int nType = 99;
104 : std::string osData{};
105 :
106 : CPL_DISALLOW_COPY_ASSIGN(NTFRecord)
107 :
108 : public:
109 : explicit NTFRecord(VSILFILE *);
110 : ~NTFRecord();
111 :
112 0 : int GetType() const
113 : {
114 0 : return nType;
115 : }
116 :
117 0 : int GetLength() const
118 : {
119 0 : return static_cast<int>(osData.size());
120 : }
121 :
122 0 : const char *GetData() const
123 : {
124 0 : return osData.c_str();
125 : }
126 :
127 : const char *GetField(int, int) const;
128 : };
129 :
130 : /************************************************************************/
131 : /* NTFGenericClass */
132 : /************************************************************************/
133 :
134 : class NTFGenericClass
135 : {
136 : CPL_DISALLOW_COPY_ASSIGN(NTFGenericClass)
137 :
138 : public:
139 : int nFeatureCount;
140 :
141 : int b3D;
142 : int nAttrCount;
143 : char **papszAttrNames;
144 : char **papszAttrFormats;
145 : int *panAttrMaxWidth;
146 : int *pabAttrMultiple;
147 :
148 : NTFGenericClass();
149 : ~NTFGenericClass();
150 :
151 : void CheckAddAttr(const char *, const char *, int);
152 : void SetMultiple(const char *);
153 : };
154 :
155 : /************************************************************************/
156 : /* NTFCodeList */
157 : /************************************************************************/
158 :
159 : class NTFCodeList
160 : {
161 : CPL_DISALLOW_COPY_ASSIGN(NTFCodeList)
162 :
163 : public:
164 : explicit NTFCodeList(NTFRecord *);
165 : ~NTFCodeList();
166 :
167 : const char *Lookup(const char *);
168 :
169 : char szValType[3]; /* attribute code for list, i.e. AC */
170 : char szFInter[6]; /* format of code values */
171 :
172 : int nNumCode;
173 : char **papszCodeVal; /* Short code value */
174 : char **papszCodeDes; /* Long description of code */
175 : };
176 :
177 : /************************************************************************/
178 : /* NTFAttDesc */
179 : /************************************************************************/
180 : typedef struct
181 : {
182 : char val_type[2 + 1];
183 : char fwidth[3 + 1];
184 : char finter[5 + 1];
185 : char att_name[100];
186 :
187 : NTFCodeList *poCodeList;
188 :
189 : } NTFAttDesc;
190 :
191 : class OGRNTFLayer;
192 : class OGRNTFRasterLayer;
193 : class OGRNTFDataSource;
194 : class NTFFileReader;
195 :
196 : #define MAX_REC_GROUP 100
197 : typedef OGRFeature *(*NTFFeatureTranslator)(NTFFileReader *, OGRNTFLayer *,
198 : NTFRecord **);
199 : typedef int (*NTFRecordGrouper)(NTFFileReader *, NTFRecord **, NTFRecord *);
200 :
201 : /************************************************************************/
202 : /* NTFFileReader */
203 : /************************************************************************/
204 :
205 : class NTFFileReader
206 : {
207 : char *pszFilename;
208 : OGRNTFDataSource *poDS;
209 :
210 : VSILFILE *fp;
211 :
212 : // feature class list.
213 : int nFCCount;
214 : char **papszFCNum;
215 : char **papszFCName;
216 :
217 : // attribute definitions
218 : int nAttCount;
219 : NTFAttDesc *pasAttDesc;
220 :
221 : char *pszTileName;
222 : int nCoordWidth;
223 : int nZWidth;
224 : int nNTFLevel;
225 :
226 : double dfXYMult;
227 : double dfZMult;
228 :
229 : double dfXOrigin;
230 : double dfYOrigin;
231 :
232 : double dfTileXSize;
233 : double dfTileYSize;
234 :
235 : double dfScale;
236 : double dfPaperToGround;
237 :
238 : vsi_l_offset nStartPos;
239 : vsi_l_offset nPreSavedPos;
240 : vsi_l_offset nPostSavedPos;
241 : NTFRecord *poSavedRecord;
242 :
243 : long nSavedFeatureId;
244 : long nBaseFeatureId;
245 : long nFeatureCount;
246 :
247 : NTFRecord *apoCGroup[MAX_REC_GROUP + 1];
248 :
249 : char *pszProduct;
250 : char *pszPVName;
251 : int nProduct;
252 :
253 : void EstablishLayers();
254 :
255 : void ClearCGroup();
256 : void ClearDefs();
257 :
258 : OGRNTFLayer *apoTypeTranslation[100];
259 :
260 : NTFRecordGrouper pfnRecordGrouper;
261 :
262 : int anIndexSize[100];
263 : NTFRecord **apapoRecordIndex[100];
264 : int bIndexBuilt;
265 : int bIndexNeeded;
266 :
267 : void EstablishRasterAccess();
268 : int nRasterXSize;
269 : int nRasterYSize;
270 : int nRasterDataType;
271 : double adfGeoTransform[6];
272 :
273 : OGRNTFRasterLayer *poRasterLayer;
274 :
275 : vsi_l_offset *panColumnOffset;
276 :
277 : int bCacheLines;
278 : int nLineCacheSize;
279 : OGRGeometry **papoLineCache;
280 :
281 : void AddToIndexGroup(NTFRecord *poRecord);
282 :
283 : CPL_DISALLOW_COPY_ASSIGN(NTFFileReader)
284 :
285 : public:
286 : explicit NTFFileReader(OGRNTFDataSource *);
287 : ~NTFFileReader();
288 :
289 : int Open(const char *pszFilename = nullptr);
290 : void Close();
291 :
292 0 : VSILFILE *GetFP()
293 : {
294 0 : return fp;
295 : }
296 :
297 : void GetFPPos(vsi_l_offset *pnPos, long *pnFeatureId);
298 : int SetFPPos(vsi_l_offset nPos, long nFeatureId);
299 : void Reset();
300 : void SetBaseFID(long nFeatureId);
301 :
302 : OGRGeometry *ProcessGeometry(NTFRecord *, int * = nullptr);
303 : OGRGeometry *ProcessGeometry3D(NTFRecord *, int * = nullptr);
304 : static int ProcessAttDesc(NTFRecord *, NTFAttDesc *);
305 : int ProcessAttRec(NTFRecord *, int *, char ***, char ***);
306 : int ProcessAttRecGroup(NTFRecord **, char ***, char ***);
307 :
308 : NTFAttDesc *GetAttDesc(const char *);
309 :
310 : void ApplyAttributeValues(OGRFeature *, NTFRecord **, ...);
311 :
312 : int ApplyAttributeValue(OGRFeature *, int, const char *, char **, char **);
313 :
314 : int ProcessAttValue(const char *pszValType, const char *pszRawValue,
315 : const char **ppszAttName, const char **ppszAttValue,
316 : const char **ppszCodeDesc);
317 :
318 : int TestForLayer(OGRNTFLayer *);
319 : OGRFeature *ReadOGRFeature(OGRNTFLayer * = nullptr);
320 : NTFRecord **ReadRecordGroup();
321 : NTFRecord *ReadRecord();
322 : void SaveRecord(NTFRecord *);
323 :
324 : void DumpReadable(FILE *);
325 :
326 0 : int GetXYLen()
327 : {
328 0 : return nCoordWidth;
329 : }
330 :
331 0 : double GetXYMult()
332 : {
333 0 : return dfXYMult;
334 : }
335 :
336 0 : double GetXOrigin()
337 : {
338 0 : return dfXOrigin;
339 : }
340 :
341 0 : double GetYOrigin()
342 : {
343 0 : return dfYOrigin;
344 : }
345 :
346 0 : double GetZMult()
347 : {
348 0 : return dfZMult;
349 : }
350 :
351 0 : const char *GetTileName()
352 : {
353 0 : return pszTileName;
354 : }
355 :
356 0 : const char *GetFilename()
357 : {
358 0 : return pszFilename;
359 : }
360 :
361 0 : int GetNTFLevel()
362 : {
363 0 : return nNTFLevel;
364 : }
365 :
366 0 : const char *GetProduct()
367 : {
368 0 : return pszProduct;
369 : }
370 :
371 : const char *GetPVName()
372 : {
373 : return pszPVName;
374 : }
375 :
376 0 : int GetProductId()
377 : {
378 0 : return nProduct;
379 : }
380 :
381 : double GetScale()
382 : {
383 : return dfScale;
384 : }
385 :
386 0 : double GetPaperToGround()
387 : {
388 0 : return dfPaperToGround;
389 : }
390 :
391 0 : int GetFCCount()
392 : {
393 0 : return nFCCount;
394 : }
395 :
396 : int GetFeatureClass(int, char **, char **);
397 :
398 : void OverrideTileName(const char *);
399 :
400 : // Generic file index
401 : void IndexFile();
402 : void FreshenIndex();
403 : void DestroyIndex();
404 : NTFRecord *GetIndexedRecord(int, int);
405 : NTFRecord **GetNextIndexedRecordGroup(NTFRecord **);
406 :
407 : // Line geometry cache
408 : OGRGeometry *CacheGetByGeomId(int);
409 : void CacheAddByGeomId(int, OGRGeometry *);
410 : void CacheClean();
411 : void CacheLineGeometryInGroup(NTFRecord **);
412 :
413 : int FormPolygonFromCache(OGRFeature *);
414 :
415 : // just for use of OGRNTFDatasource
416 : void EstablishLayer(const char *, OGRwkbGeometryType, NTFFeatureTranslator,
417 : int, NTFGenericClass *, ...);
418 :
419 : // Raster related
420 : int IsRasterProduct();
421 :
422 0 : int GetRasterXSize()
423 : {
424 0 : return nRasterXSize;
425 : }
426 :
427 0 : int GetRasterYSize()
428 : {
429 0 : return nRasterYSize;
430 : }
431 :
432 : int GetRasterDataType()
433 : {
434 : return nRasterDataType;
435 : }
436 :
437 0 : double *GetGeoTransform()
438 : {
439 0 : return adfGeoTransform;
440 : }
441 :
442 : CPLErr ReadRasterColumn(int, float *);
443 : };
444 :
445 : /************************************************************************/
446 : /* OGRNTFLayer */
447 : /************************************************************************/
448 :
449 : class OGRNTFLayer final : public OGRLayer
450 : {
451 : OGRFeatureDefn *poFeatureDefn;
452 : NTFFeatureTranslator pfnTranslator;
453 :
454 : OGRNTFDataSource *poDS;
455 :
456 : int iCurrentReader;
457 : vsi_l_offset nCurrentPos;
458 : long nCurrentFID;
459 :
460 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFLayer)
461 :
462 : public:
463 : OGRNTFLayer(OGRNTFDataSource *poDS, OGRFeatureDefn *poFeatureDefine,
464 : NTFFeatureTranslator pfnTranslator);
465 :
466 : ~OGRNTFLayer() override;
467 :
468 : void ResetReading() override;
469 : OGRFeature *GetNextFeature() override;
470 :
471 : #ifdef notdef
472 : OGRFeature *GetFeature(GIntBig nFeatureId);
473 : OGRErr ISetFeature(OGRFeature *poFeature);
474 : OGRErr ICreateFeature(OGRFeature *poFeature);
475 : #endif
476 :
477 0 : OGRFeatureDefn *GetLayerDefn() const override
478 : {
479 0 : return poFeatureDefn;
480 : }
481 :
482 : #ifdef notdef
483 : GIntBig GetFeatureCount(int);
484 : #endif
485 :
486 : int TestCapability(const char *) const override;
487 :
488 : // special to NTF
489 : OGRFeature *FeatureTranslate(NTFFileReader *, NTFRecord **);
490 : };
491 :
492 : /************************************************************************/
493 : /* OGRNTFFeatureClassLayer */
494 : /************************************************************************/
495 :
496 : class OGRNTFFeatureClassLayer final : public OGRLayer
497 : {
498 : OGRFeatureDefn *poFeatureDefn;
499 : OGRGeometry *poFilterGeom;
500 :
501 : OGRNTFDataSource *poDS;
502 :
503 : GIntBig iCurrentFC;
504 :
505 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFFeatureClassLayer)
506 :
507 : public:
508 : explicit OGRNTFFeatureClassLayer(OGRNTFDataSource *poDS);
509 : ~OGRNTFFeatureClassLayer() override;
510 :
511 0 : OGRGeometry *GetSpatialFilter() override
512 : {
513 0 : return poFilterGeom;
514 : }
515 :
516 : void ResetReading() override;
517 : OGRFeature *GetNextFeature() override;
518 :
519 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
520 :
521 0 : OGRFeatureDefn *GetLayerDefn() const override
522 : {
523 0 : return poFeatureDefn;
524 : }
525 :
526 : GIntBig GetFeatureCount(int = TRUE) override;
527 :
528 : int TestCapability(const char *) const override;
529 : };
530 :
531 : /************************************************************************/
532 : /* OGRNTFRasterLayer */
533 : /************************************************************************/
534 :
535 : class OGRNTFRasterLayer final : public OGRLayer
536 : {
537 : OGRFeatureDefn *poFeatureDefn;
538 : OGRGeometry *poFilterGeom;
539 :
540 : NTFFileReader *poReader;
541 :
542 : float *pafColumn;
543 : int iColumnOffset;
544 :
545 : GIntBig iCurrentFC;
546 :
547 : int nDEMSample;
548 : GIntBig nFeatureCount;
549 :
550 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFRasterLayer)
551 :
552 : public:
553 : OGRNTFRasterLayer(OGRNTFDataSource *poDS, NTFFileReader *poReaderIn);
554 : ~OGRNTFRasterLayer() override;
555 :
556 0 : OGRGeometry *GetSpatialFilter() override
557 : {
558 0 : return poFilterGeom;
559 : }
560 :
561 : void ResetReading() override;
562 : OGRFeature *GetNextFeature() override;
563 :
564 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
565 :
566 0 : OGRFeatureDefn *GetLayerDefn() const override
567 : {
568 0 : return poFeatureDefn;
569 : }
570 :
571 : GIntBig GetFeatureCount(int = TRUE) override;
572 :
573 : int TestCapability(const char *) const override;
574 : };
575 :
576 : /************************************************************************/
577 : /* OGRNTFDataSource */
578 : /************************************************************************/
579 :
580 : class OGRNTFDataSource final : public GDALDataset
581 : {
582 : int nLayers;
583 : OGRLayer **papoLayers;
584 :
585 : OGRNTFFeatureClassLayer *poFCLayer;
586 :
587 : int iCurrentFC;
588 : int iCurrentReader;
589 : vsi_l_offset nCurrentPos;
590 : long nCurrentFID;
591 :
592 : int nNTFFileCount;
593 : NTFFileReader **papoNTFFileReader;
594 :
595 : int nFCCount;
596 : char **papszFCNum;
597 : char **papszFCName;
598 :
599 : OGRSpatialReference *poSpatialRef;
600 :
601 : NTFGenericClass aoGenericClass[100];
602 :
603 : char **papszOptions;
604 :
605 : void EnsureTileNameUnique(NTFFileReader *);
606 :
607 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFDataSource)
608 :
609 : public:
610 : OGRNTFDataSource();
611 : ~OGRNTFDataSource() override;
612 :
613 : void SetOptionList(char **);
614 : const char *GetOption(const char *);
615 :
616 : int Open(const char *pszName, int bTestOpen = FALSE,
617 : char **papszFileList = nullptr);
618 :
619 : int GetLayerCount() const override;
620 : OGRLayer *GetLayer(int) const override;
621 : int TestCapability(const char *) const override;
622 :
623 : // Note: these are specific to NTF for now, but eventually might
624 : // might be available as part of a more object oriented approach to
625 : // features like that in FME or SFCORBA.
626 : void ResetReading() override;
627 : OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
628 : double *pdfProgressPct,
629 : GDALProgressFunc pfnProgress,
630 : void *pProgressData) override;
631 :
632 : // these are only for the use of the NTFFileReader class.
633 : OGRNTFLayer *GetNamedLayer(const char *);
634 : void AddLayer(OGRLayer *);
635 :
636 : // Mainly for OGRNTFLayer class
637 0 : int GetFileCount()
638 : {
639 0 : return nNTFFileCount;
640 : }
641 :
642 0 : NTFFileReader *GetFileReader(int i)
643 : {
644 0 : return papoNTFFileReader[i];
645 : }
646 :
647 0 : int GetFCCount()
648 : {
649 0 : return nFCCount;
650 : }
651 :
652 : int GetFeatureClass(int, char **, char **);
653 :
654 0 : OGRSpatialReference *DSGetSpatialRef()
655 : {
656 0 : return poSpatialRef;
657 : }
658 :
659 0 : NTFGenericClass *GetGClass(int i)
660 : {
661 0 : return aoGenericClass + i;
662 : }
663 :
664 : void WorkupGeneric(NTFFileReader *);
665 : void EstablishGenericLayers();
666 : };
667 :
668 : /************************************************************************/
669 : /* Support functions. */
670 : /************************************************************************/
671 : int NTFArcCenterFromEdgePoints(double x_c0, double y_c0, double x_c1,
672 : double y_c1, double x_c2, double y_c2,
673 : double *x_center, double *y_center);
674 : OGRGeometry *NTFStrokeArcToOGRGeometry_Points(double dfStartX, double dfStartY,
675 : double dfAlongX, double dfAlongY,
676 : double dfEndX, double dfEndY,
677 : int nVertexCount);
678 : OGRGeometry *NTFStrokeArcToOGRGeometry_Angles(double dfCenterX,
679 : double dfCenterY, double dfRadius,
680 : double dfStartAngle,
681 : double dfEndAngle,
682 : int nVertexCount);
683 :
684 : #endif /* ndef NTF_H_INCLUDED */
|