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;
104 : int nLength;
105 : char *pszData;
106 :
107 : static int ReadPhysicalLine(VSILFILE *fp, char *pszLine);
108 :
109 : public:
110 : explicit NTFRecord(VSILFILE *);
111 : ~NTFRecord();
112 :
113 0 : int GetType()
114 : {
115 0 : return nType;
116 : }
117 :
118 0 : int GetLength()
119 : {
120 0 : return nLength;
121 : }
122 :
123 0 : const char *GetData()
124 : {
125 0 : return pszData;
126 : }
127 :
128 : const char *GetField(int, int);
129 : };
130 :
131 : /************************************************************************/
132 : /* NTFGenericClass */
133 : /************************************************************************/
134 :
135 : class NTFGenericClass
136 : {
137 : public:
138 : int nFeatureCount;
139 :
140 : int b3D;
141 : int nAttrCount;
142 : char **papszAttrNames;
143 : char **papszAttrFormats;
144 : int *panAttrMaxWidth;
145 : int *pabAttrMultiple;
146 :
147 : NTFGenericClass();
148 : ~NTFGenericClass();
149 :
150 : void CheckAddAttr(const char *, const char *, int);
151 : void SetMultiple(const char *);
152 : };
153 :
154 : /************************************************************************/
155 : /* NTFCodeList */
156 : /************************************************************************/
157 :
158 : class NTFCodeList
159 : {
160 : public:
161 : explicit NTFCodeList(NTFRecord *);
162 : ~NTFCodeList();
163 :
164 : const char *Lookup(const char *);
165 :
166 : char szValType[3]; /* attribute code for list, i.e. AC */
167 : char szFInter[6]; /* format of code values */
168 :
169 : int nNumCode;
170 : char **papszCodeVal; /* Short code value */
171 : char **papszCodeDes; /* Long description of code */
172 : };
173 :
174 : /************************************************************************/
175 : /* NTFAttDesc */
176 : /************************************************************************/
177 : typedef struct
178 : {
179 : char val_type[2 + 1];
180 : char fwidth[3 + 1];
181 : char finter[5 + 1];
182 : char att_name[100];
183 :
184 : NTFCodeList *poCodeList;
185 :
186 : } NTFAttDesc;
187 :
188 : class OGRNTFLayer;
189 : class OGRNTFRasterLayer;
190 : class OGRNTFDataSource;
191 : class NTFFileReader;
192 :
193 : #define MAX_REC_GROUP 100
194 : typedef OGRFeature *(*NTFFeatureTranslator)(NTFFileReader *, OGRNTFLayer *,
195 : NTFRecord **);
196 : typedef int (*NTFRecordGrouper)(NTFFileReader *, NTFRecord **, NTFRecord *);
197 :
198 : /************************************************************************/
199 : /* NTFFileReader */
200 : /************************************************************************/
201 :
202 : class NTFFileReader
203 : {
204 : char *pszFilename;
205 : OGRNTFDataSource *poDS;
206 :
207 : VSILFILE *fp;
208 :
209 : // feature class list.
210 : int nFCCount;
211 : char **papszFCNum;
212 : char **papszFCName;
213 :
214 : // attribute definitions
215 : int nAttCount;
216 : NTFAttDesc *pasAttDesc;
217 :
218 : char *pszTileName;
219 : int nCoordWidth;
220 : int nZWidth;
221 : int nNTFLevel;
222 :
223 : double dfXYMult;
224 : double dfZMult;
225 :
226 : double dfXOrigin;
227 : double dfYOrigin;
228 :
229 : double dfTileXSize;
230 : double dfTileYSize;
231 :
232 : double dfScale;
233 : double dfPaperToGround;
234 :
235 : vsi_l_offset nStartPos;
236 : vsi_l_offset nPreSavedPos;
237 : vsi_l_offset nPostSavedPos;
238 : NTFRecord *poSavedRecord;
239 :
240 : long nSavedFeatureId;
241 : long nBaseFeatureId;
242 : long nFeatureCount;
243 :
244 : NTFRecord *apoCGroup[MAX_REC_GROUP + 1];
245 :
246 : char *pszProduct;
247 : char *pszPVName;
248 : int nProduct;
249 :
250 : void EstablishLayers();
251 :
252 : void ClearCGroup();
253 : void ClearDefs();
254 :
255 : OGRNTFLayer *apoTypeTranslation[100];
256 :
257 : NTFRecordGrouper pfnRecordGrouper;
258 :
259 : int anIndexSize[100];
260 : NTFRecord **apapoRecordIndex[100];
261 : int bIndexBuilt;
262 : int bIndexNeeded;
263 :
264 : void EstablishRasterAccess();
265 : int nRasterXSize;
266 : int nRasterYSize;
267 : int nRasterDataType;
268 : double adfGeoTransform[6];
269 :
270 : OGRNTFRasterLayer *poRasterLayer;
271 :
272 : vsi_l_offset *panColumnOffset;
273 :
274 : int bCacheLines;
275 : int nLineCacheSize;
276 : OGRGeometry **papoLineCache;
277 :
278 : void AddToIndexGroup(NTFRecord *poRecord);
279 :
280 : public:
281 : explicit NTFFileReader(OGRNTFDataSource *);
282 : ~NTFFileReader();
283 :
284 : int Open(const char *pszFilename = nullptr);
285 : void Close();
286 :
287 0 : VSILFILE *GetFP()
288 : {
289 0 : return fp;
290 : }
291 :
292 : void GetFPPos(vsi_l_offset *pnPos, long *pnFeatureId);
293 : int SetFPPos(vsi_l_offset nPos, long nFeatureId);
294 : void Reset();
295 : void SetBaseFID(long nFeatureId);
296 :
297 : OGRGeometry *ProcessGeometry(NTFRecord *, int * = nullptr);
298 : OGRGeometry *ProcessGeometry3D(NTFRecord *, int * = nullptr);
299 : static int ProcessAttDesc(NTFRecord *, NTFAttDesc *);
300 : int ProcessAttRec(NTFRecord *, int *, char ***, char ***);
301 : int ProcessAttRecGroup(NTFRecord **, char ***, char ***);
302 :
303 : NTFAttDesc *GetAttDesc(const char *);
304 :
305 : void ApplyAttributeValues(OGRFeature *, NTFRecord **, ...);
306 :
307 : int ApplyAttributeValue(OGRFeature *, int, const char *, char **, char **);
308 :
309 : int ProcessAttValue(const char *pszValType, const char *pszRawValue,
310 : const char **ppszAttName, const char **ppszAttValue,
311 : const char **ppszCodeDesc);
312 :
313 : int TestForLayer(OGRNTFLayer *);
314 : OGRFeature *ReadOGRFeature(OGRNTFLayer * = nullptr);
315 : NTFRecord **ReadRecordGroup();
316 : NTFRecord *ReadRecord();
317 : void SaveRecord(NTFRecord *);
318 :
319 : void DumpReadable(FILE *);
320 :
321 0 : int GetXYLen()
322 : {
323 0 : return nCoordWidth;
324 : }
325 :
326 0 : double GetXYMult()
327 : {
328 0 : return dfXYMult;
329 : }
330 :
331 0 : double GetXOrigin()
332 : {
333 0 : return dfXOrigin;
334 : }
335 :
336 0 : double GetYOrigin()
337 : {
338 0 : return dfYOrigin;
339 : }
340 :
341 0 : double GetZMult()
342 : {
343 0 : return dfZMult;
344 : }
345 :
346 0 : const char *GetTileName()
347 : {
348 0 : return pszTileName;
349 : }
350 :
351 0 : const char *GetFilename()
352 : {
353 0 : return pszFilename;
354 : }
355 :
356 0 : int GetNTFLevel()
357 : {
358 0 : return nNTFLevel;
359 : }
360 :
361 0 : const char *GetProduct()
362 : {
363 0 : return pszProduct;
364 : }
365 :
366 : const char *GetPVName()
367 : {
368 : return pszPVName;
369 : }
370 :
371 0 : int GetProductId()
372 : {
373 0 : return nProduct;
374 : }
375 :
376 : double GetScale()
377 : {
378 : return dfScale;
379 : }
380 :
381 0 : double GetPaperToGround()
382 : {
383 0 : return dfPaperToGround;
384 : }
385 :
386 0 : int GetFCCount()
387 : {
388 0 : return nFCCount;
389 : }
390 :
391 : int GetFeatureClass(int, char **, char **);
392 :
393 : void OverrideTileName(const char *);
394 :
395 : // Generic file index
396 : void IndexFile();
397 : void FreshenIndex();
398 : void DestroyIndex();
399 : NTFRecord *GetIndexedRecord(int, int);
400 : NTFRecord **GetNextIndexedRecordGroup(NTFRecord **);
401 :
402 : // Line geometry cache
403 : OGRGeometry *CacheGetByGeomId(int);
404 : void CacheAddByGeomId(int, OGRGeometry *);
405 : void CacheClean();
406 : void CacheLineGeometryInGroup(NTFRecord **);
407 :
408 : int FormPolygonFromCache(OGRFeature *);
409 :
410 : // just for use of OGRNTFDatasource
411 : void EstablishLayer(const char *, OGRwkbGeometryType, NTFFeatureTranslator,
412 : int, NTFGenericClass *, ...);
413 :
414 : // Raster related
415 : int IsRasterProduct();
416 :
417 0 : int GetRasterXSize()
418 : {
419 0 : return nRasterXSize;
420 : }
421 :
422 0 : int GetRasterYSize()
423 : {
424 0 : return nRasterYSize;
425 : }
426 :
427 : int GetRasterDataType()
428 : {
429 : return nRasterDataType;
430 : }
431 :
432 0 : double *GetGeoTransform()
433 : {
434 0 : return adfGeoTransform;
435 : }
436 :
437 : CPLErr ReadRasterColumn(int, float *);
438 : };
439 :
440 : /************************************************************************/
441 : /* OGRNTFLayer */
442 : /************************************************************************/
443 :
444 : class OGRNTFLayer final : public OGRLayer
445 : {
446 : OGRFeatureDefn *poFeatureDefn;
447 : NTFFeatureTranslator pfnTranslator;
448 :
449 : OGRNTFDataSource *poDS;
450 :
451 : int iCurrentReader;
452 : vsi_l_offset nCurrentPos;
453 : long nCurrentFID;
454 :
455 : public:
456 : OGRNTFLayer(OGRNTFDataSource *poDS, OGRFeatureDefn *poFeatureDefine,
457 : NTFFeatureTranslator pfnTranslator);
458 :
459 : ~OGRNTFLayer();
460 :
461 : void ResetReading() override;
462 : OGRFeature *GetNextFeature() override;
463 :
464 : #ifdef notdef
465 : OGRFeature *GetFeature(GIntBig nFeatureId);
466 : OGRErr ISetFeature(OGRFeature *poFeature);
467 : OGRErr ICreateFeature(OGRFeature *poFeature);
468 : #endif
469 :
470 0 : OGRFeatureDefn *GetLayerDefn() override
471 : {
472 0 : return poFeatureDefn;
473 : }
474 :
475 : #ifdef notdef
476 : GIntBig GetFeatureCount(int);
477 : #endif
478 :
479 : int TestCapability(const char *) override;
480 :
481 : // special to NTF
482 : OGRFeature *FeatureTranslate(NTFFileReader *, NTFRecord **);
483 : };
484 :
485 : /************************************************************************/
486 : /* OGRNTFFeatureClassLayer */
487 : /************************************************************************/
488 :
489 : class OGRNTFFeatureClassLayer final : public OGRLayer
490 : {
491 : OGRFeatureDefn *poFeatureDefn;
492 : OGRGeometry *poFilterGeom;
493 :
494 : OGRNTFDataSource *poDS;
495 :
496 : GIntBig iCurrentFC;
497 :
498 : public:
499 : explicit OGRNTFFeatureClassLayer(OGRNTFDataSource *poDS);
500 : ~OGRNTFFeatureClassLayer();
501 :
502 0 : OGRGeometry *GetSpatialFilter() override
503 : {
504 0 : return poFilterGeom;
505 : }
506 :
507 : void ResetReading() override;
508 : OGRFeature *GetNextFeature() override;
509 :
510 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
511 :
512 0 : OGRFeatureDefn *GetLayerDefn() override
513 : {
514 0 : return poFeatureDefn;
515 : }
516 :
517 : GIntBig GetFeatureCount(int = TRUE) override;
518 :
519 : int TestCapability(const char *) override;
520 : };
521 :
522 : /************************************************************************/
523 : /* OGRNTFRasterLayer */
524 : /************************************************************************/
525 :
526 : class OGRNTFRasterLayer final : public OGRLayer
527 : {
528 : OGRFeatureDefn *poFeatureDefn;
529 : OGRGeometry *poFilterGeom;
530 :
531 : NTFFileReader *poReader;
532 :
533 : float *pafColumn;
534 : int iColumnOffset;
535 :
536 : GIntBig iCurrentFC;
537 :
538 : int nDEMSample;
539 : GIntBig nFeatureCount;
540 :
541 : public:
542 : OGRNTFRasterLayer(OGRNTFDataSource *poDS, NTFFileReader *poReaderIn);
543 : virtual ~OGRNTFRasterLayer();
544 :
545 0 : OGRGeometry *GetSpatialFilter() override
546 : {
547 0 : return poFilterGeom;
548 : }
549 :
550 : void ResetReading() override;
551 : OGRFeature *GetNextFeature() override;
552 :
553 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
554 :
555 0 : OGRFeatureDefn *GetLayerDefn() override
556 : {
557 0 : return poFeatureDefn;
558 : }
559 :
560 : GIntBig GetFeatureCount(int = TRUE) override;
561 :
562 : int TestCapability(const char *) override;
563 : };
564 :
565 : /************************************************************************/
566 : /* OGRNTFDataSource */
567 : /************************************************************************/
568 :
569 : class OGRNTFDataSource final : public GDALDataset
570 : {
571 : int nLayers;
572 : OGRLayer **papoLayers;
573 :
574 : OGRNTFFeatureClassLayer *poFCLayer;
575 :
576 : int iCurrentFC;
577 : int iCurrentReader;
578 : vsi_l_offset nCurrentPos;
579 : long nCurrentFID;
580 :
581 : int nNTFFileCount;
582 : NTFFileReader **papoNTFFileReader;
583 :
584 : int nFCCount;
585 : char **papszFCNum;
586 : char **papszFCName;
587 :
588 : OGRSpatialReference *poSpatialRef;
589 :
590 : NTFGenericClass aoGenericClass[100];
591 :
592 : char **papszOptions;
593 :
594 : void EnsureTileNameUnique(NTFFileReader *);
595 :
596 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFDataSource)
597 :
598 : public:
599 : OGRNTFDataSource();
600 : ~OGRNTFDataSource();
601 :
602 : void SetOptionList(char **);
603 : const char *GetOption(const char *);
604 :
605 : int Open(const char *pszName, int bTestOpen = FALSE,
606 : char **papszFileList = nullptr);
607 :
608 : int GetLayerCount() override;
609 : OGRLayer *GetLayer(int) override;
610 : int TestCapability(const char *) override;
611 :
612 : // Note: these are specific to NTF for now, but eventually might
613 : // might be available as part of a more object oriented approach to
614 : // features like that in FME or SFCORBA.
615 : virtual void ResetReading() override;
616 : virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
617 : double *pdfProgressPct,
618 : GDALProgressFunc pfnProgress,
619 : void *pProgressData) override;
620 :
621 : // these are only for the use of the NTFFileReader class.
622 : OGRNTFLayer *GetNamedLayer(const char *);
623 : void AddLayer(OGRLayer *);
624 :
625 : // Mainly for OGRNTFLayer class
626 0 : int GetFileCount()
627 : {
628 0 : return nNTFFileCount;
629 : }
630 :
631 0 : NTFFileReader *GetFileReader(int i)
632 : {
633 0 : return papoNTFFileReader[i];
634 : }
635 :
636 0 : int GetFCCount()
637 : {
638 0 : return nFCCount;
639 : }
640 :
641 : int GetFeatureClass(int, char **, char **);
642 :
643 0 : OGRSpatialReference *DSGetSpatialRef()
644 : {
645 0 : return poSpatialRef;
646 : }
647 :
648 0 : NTFGenericClass *GetGClass(int i)
649 : {
650 0 : return aoGenericClass + i;
651 : }
652 :
653 : void WorkupGeneric(NTFFileReader *);
654 : void EstablishGenericLayers();
655 : };
656 :
657 : /************************************************************************/
658 : /* Support functions. */
659 : /************************************************************************/
660 : int NTFArcCenterFromEdgePoints(double x_c0, double y_c0, double x_c1,
661 : double y_c1, double x_c2, double y_c2,
662 : double *x_center, double *y_center);
663 : OGRGeometry *NTFStrokeArcToOGRGeometry_Points(double dfStartX, double dfStartY,
664 : double dfAlongX, double dfAlongY,
665 : double dfEndX, double dfEndY,
666 : int nVertexCount);
667 : OGRGeometry *NTFStrokeArcToOGRGeometry_Angles(double dfCenterX,
668 : double dfCenterY, double dfRadius,
669 : double dfStartAngle,
670 : double dfEndAngle,
671 : int nVertexCount);
672 :
673 : #endif /* ndef NTF_H_INCLUDED */
|