1 /******************************************************************************
2  * $Id: ntf.h 842d122d2f23aaebb28362e083b52d6bc7dbcde2 2019-08-11 17:42:34 +0200 Even Rouault $
3  *
4  * Project:  NTF Translator
5  * Purpose:  Main declarations for NTF translator.
6  * Author:   Frank Warmerdam, warmerdam@pobox.com
7  *
8  ******************************************************************************
9  * Copyright (c) 1999, Frank Warmerdam
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #ifndef NTF_H_INCLUDED
31 #define NTF_H_INCLUDED
32 
33 #include "cpl_conv.h"
34 #include "cpl_vsi.h"
35 #include "ogrsf_frmts.h"
36 
37 /* -------------------------------------------------------------------- */
38 /*      Record types.                                                   */
39 /* -------------------------------------------------------------------- */
40 #define NRT_VHR       1                /* Volume Header Record */
41 #define NRT_DHR       2                /* Database Header Record */
42 #define NRT_FCR       5                /* Feature Classification Record */
43 #define NRT_SHR       7                /* Section Header Record */
44 #define NRT_NAMEREC  11                /* Name Record */
45 #define NRT_NAMEPOSTN 12               /* Name Position */
46 #define NRT_ATTREC   14                /* Attribute Record */
47 #define NRT_POINTREC 15                /* Point Record */
48 #define NRT_NODEREC  16                /* Node Record */
49 #define NRT_GEOMETRY 21                /* Geometry Record */
50 #define NRT_GEOMETRY3D 22              /* 3D Geometry Record */
51 #define NRT_LINEREC  23                /* Line Record */
52 #define NRT_CHAIN    24                /* Chain */
53 #define NRT_POLYGON  31                /* Polygon */
54 #define NRT_CPOLY    33                /* Complex Polygon */
55 #define NRT_COLLECT  34                /* Collection of features */
56 #define NRT_ADR      40                /* Attribute Description Record */
57 #define NRT_CODELIST 42                /* Codelist Record (i.e. BL2000) */
58 #define NRT_TEXTREC  43                /* Text */
59 #define NRT_TEXTPOS  44                /* Text position */
60 #define NRT_TEXTREP  45                /* Text representation */
61 #define NRT_GRIDHREC 50                /* Grid Header Record */
62 #define NRT_GRIDREC  51                /* Grid Data Record */
63 #define NRT_COMMENT  90                /* Comment record */
64 #define NRT_VTR      99                /* Volume Termination Record */
65 
66 /* -------------------------------------------------------------------- */
67 /*      Product names (DBNAME) and codes.                               */
68 /* -------------------------------------------------------------------- */
69 
70 #define NPC_UNKNOWN             0
71 
72 #define NPC_LANDLINE            1
73 #define NPC_LANDLINE99          2
74 #define NTF_LANDLINE            "LAND-LINE.93"
75 #define NTF_LANDLINE_PLUS       "LAND-LINE.93+"
76 
77 #define NPC_STRATEGI            3
78 #define NTF_STRATEGI            "Strategi_02.96"
79 
80 #define NPC_MERIDIAN            4
81 #define NTF_MERIDIAN            "Meridian_01.95"
82 
83 #define NPC_BOUNDARYLINE        5
84 #define NTF_BOUNDARYLINE        "Boundary-Line"
85 
86 #define NPC_BASEDATA            6
87 #define NTF_BASEDATA            "BaseData.GB_01.96"
88 
89 #define NPC_OSCAR_ASSET         7
90 #define NPC_OSCAR_TRAFFIC       8
91 #define NPC_OSCAR_ROUTE         9
92 #define NPC_OSCAR_NETWORK       10
93 
94 #define NPC_ADDRESS_POINT       11
95 
96 #define NPC_CODE_POINT          12
97 #define NPC_CODE_POINT_PLUS     13
98 
99 #define NPC_LANDFORM_PROFILE_CONT 14
100 
101 #define NPC_LANDRANGER_CONT     15
102 #define NTF_LANDRANGER_CONT     "OS_LANDRANGER_CONT"
103 
104 #define NPC_LANDRANGER_DTM      16
105 #define NPC_LANDFORM_PROFILE_DTM 17
106 
107 #define NPC_BL2000              18
108 
109 #define NPC_MERIDIAN2           19
110 #define NTF_MERIDIAN2           "Meridian_02.01"
111 
112 /************************************************************************/
113 /*                              NTFRecord                               */
114 /************************************************************************/
115 
116 class NTFRecord
117 {
118     int      nType;
119     int      nLength;
120     char    *pszData;
121 
122     static int      ReadPhysicalLine( VSILFILE *fp, char *pszLine );
123 
124   public:
125     explicit  NTFRecord( VSILFILE * );
126              ~NTFRecord();
127 
GetType()128     int      GetType() { return nType; }
GetLength()129     int      GetLength() { return nLength; }
GetData()130     const char *GetData() { return pszData; }
131 
132     const char *GetField( int, int );
133 };
134 
135 /************************************************************************/
136 /*                           NTFGenericClass                            */
137 /************************************************************************/
138 
139 class NTFGenericClass
140 {
141 public:
142     int         nFeatureCount;
143 
144     int         b3D;
145     int         nAttrCount;
146     char        **papszAttrNames;
147     char        **papszAttrFormats;
148     int         *panAttrMaxWidth;
149     int         *pabAttrMultiple;
150 
151                 NTFGenericClass();
152                 ~NTFGenericClass();
153 
154     void        CheckAddAttr( const char *, const char *, int );
155     void        SetMultiple( const char * );
156 };
157 
158 /************************************************************************/
159 /*                             NTFCodeList                              */
160 /************************************************************************/
161 
162 class NTFCodeList
163 {
164 public:
165     explicit     NTFCodeList( NTFRecord * );
166                 ~NTFCodeList();
167 
168     const char  *Lookup( const char * );
169 
170     char        szValType[3];   /* attribute code for list, i.e. AC */
171     char        szFInter[6];    /* format of code values */
172 
173     int         nNumCode;
174     char        **papszCodeVal; /* Short code value */
175     char        **papszCodeDes; /* Long description of code */
176 };
177 
178 /************************************************************************/
179 /*                              NTFAttDesc                              */
180 /************************************************************************/
181 typedef struct
182 {
183   char  val_type     [ 2 +1];
184   char  fwidth       [ 3 +1];
185   char  finter       [ 5 +1];
186   char  att_name     [ 100 ];
187 
188   NTFCodeList *poCodeList;
189 
190 } NTFAttDesc;
191 
192 class OGRNTFLayer;
193 class OGRNTFRasterLayer;
194 class OGRNTFDataSource;
195 class NTFFileReader;
196 
197 #define MAX_REC_GROUP   100
198 typedef OGRFeature *(*NTFFeatureTranslator)(NTFFileReader *,
199                                             OGRNTFLayer *,
200                                             NTFRecord **);
201 typedef int (*NTFRecordGrouper)(NTFFileReader *, NTFRecord **, NTFRecord *);
202 
203 /************************************************************************/
204 /*                            NTFFileReader                             */
205 /************************************************************************/
206 
207 class NTFFileReader
208 {
209     char             *pszFilename;
210     OGRNTFDataSource *poDS;
211 
212     VSILFILE         *fp;
213 
214     // feature class list.
215     int               nFCCount;
216     char            **papszFCNum;
217     char            **papszFCName;
218 
219     // attribute definitions
220     int               nAttCount;
221     NTFAttDesc       *pasAttDesc;
222 
223     char             *pszTileName;
224     int               nCoordWidth;
225     int               nZWidth;
226     int               nNTFLevel;
227 
228     double            dfXYMult;
229     double            dfZMult;
230 
231     double            dfXOrigin;
232     double            dfYOrigin;
233 
234     double            dfTileXSize;
235     double            dfTileYSize;
236 
237     double            dfScale;
238     double            dfPaperToGround;
239 
240     vsi_l_offset      nStartPos;
241     vsi_l_offset      nPreSavedPos;
242     vsi_l_offset      nPostSavedPos;
243     NTFRecord        *poSavedRecord;
244 
245     long              nSavedFeatureId;
246     long              nBaseFeatureId;
247     long              nFeatureCount;
248 
249     NTFRecord         *apoCGroup[MAX_REC_GROUP+1];
250 
251     char             *pszProduct;
252     char             *pszPVName;
253     int               nProduct;
254 
255     void              EstablishLayers();
256 
257     void              ClearCGroup();
258     void              ClearDefs();
259 
260     OGRNTFLayer       *apoTypeTranslation[100];
261 
262     NTFRecordGrouper  pfnRecordGrouper;
263 
264     int               anIndexSize[100];
265     NTFRecord         **apapoRecordIndex[100];
266     int               bIndexBuilt;
267     int               bIndexNeeded;
268 
269     void              EstablishRasterAccess();
270     int               nRasterXSize;
271     int               nRasterYSize;
272     int               nRasterDataType;
273     double            adfGeoTransform[6];
274 
275     OGRNTFRasterLayer *poRasterLayer;
276 
277     vsi_l_offset     *panColumnOffset;
278 
279     int               bCacheLines;
280     int               nLineCacheSize;
281     OGRGeometry     **papoLineCache;
282 
283     void              AddToIndexGroup( NTFRecord * poRecord );
284 
285   public:
286     explicit           NTFFileReader( OGRNTFDataSource * );
287                       ~NTFFileReader();
288 
289     int               Open( const char * pszFilename = nullptr );
290     void              Close();
GetFP()291     VSILFILE         *GetFP() { return fp; }
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 *,
308                                            char **, char ** );
309 
310     int               ProcessAttValue( const char *pszValType,
311                                        const char *pszRawValue,
312                                        const char **ppszAttName,
313                                        const char **ppszAttValue,
314                                        const char **ppszCodeDesc );
315 
316     int               TestForLayer( OGRNTFLayer * );
317     OGRFeature       *ReadOGRFeature( OGRNTFLayer * = nullptr );
318     NTFRecord       **ReadRecordGroup();
319     NTFRecord        *ReadRecord();
320     void              SaveRecord( NTFRecord * );
321 
322     void              DumpReadable( FILE * );
323 
GetXYLen()324     int               GetXYLen() { return nCoordWidth; }
GetXYMult()325     double            GetXYMult() { return dfXYMult; }
GetXOrigin()326     double            GetXOrigin() { return dfXOrigin; }
GetYOrigin()327     double            GetYOrigin() { return dfYOrigin; }
GetZMult()328     double            GetZMult() { return dfZMult; }
GetTileName()329     const char       *GetTileName() { return pszTileName; }
GetFilename()330     const char       *GetFilename() { return pszFilename; }
GetNTFLevel()331     int               GetNTFLevel() { return nNTFLevel; }
GetProduct()332     const char       *GetProduct() { return pszProduct; }
GetPVName()333     const char       *GetPVName() { return pszPVName; }
GetProductId()334     int               GetProductId() { return nProduct; }
GetScale()335     double            GetScale() { return dfScale; }
GetPaperToGround()336     double            GetPaperToGround() { return dfPaperToGround; }
337 
GetFCCount()338     int               GetFCCount() { return nFCCount; }
339     int               GetFeatureClass( int, char **, char ** );
340 
341     void              OverrideTileName( const char * );
342 
343     // Generic file index
344     void              IndexFile();
345     void              FreshenIndex();
346     void              DestroyIndex();
347     NTFRecord        *GetIndexedRecord( int, int );
348     NTFRecord       **GetNextIndexedRecordGroup( NTFRecord ** );
349 
350     // Line geometry cache
351     OGRGeometry      *CacheGetByGeomId( int );
352     void              CacheAddByGeomId( int, OGRGeometry * );
353     void              CacheClean();
354     void              CacheLineGeometryInGroup( NTFRecord ** );
355 
356     int               FormPolygonFromCache( OGRFeature * );
357 
358     // just for use of OGRNTFDatasource
359     void              EstablishLayer( const char *, OGRwkbGeometryType,
360                                       NTFFeatureTranslator, int,
361                                       NTFGenericClass *, ... );
362 
363     // Raster related
364     int               IsRasterProduct();
GetRasterXSize()365     int               GetRasterXSize() { return nRasterXSize; }
GetRasterYSize()366     int               GetRasterYSize() { return nRasterYSize; }
GetRasterDataType()367     int               GetRasterDataType() { return nRasterDataType; }
GetGeoTransform()368     double           *GetGeoTransform() { return adfGeoTransform; }
369     CPLErr            ReadRasterColumn( int, float * );
370 
371 };
372 
373 /************************************************************************/
374 /*                             OGRNTFLayer                              */
375 /************************************************************************/
376 
377 class OGRNTFLayer final: public OGRLayer
378 {
379     OGRFeatureDefn     *poFeatureDefn;
380     NTFFeatureTranslator pfnTranslator;
381 
382     OGRNTFDataSource   *poDS;
383 
384     int                 iCurrentReader;
385     vsi_l_offset        nCurrentPos;
386     long                nCurrentFID;
387 
388   public:
389                         OGRNTFLayer( OGRNTFDataSource * poDS,
390                                      OGRFeatureDefn * poFeatureDefine,
391                                      NTFFeatureTranslator pfnTranslator );
392 
393                         ~OGRNTFLayer();
394 
395     void                ResetReading() override;
396     OGRFeature *        GetNextFeature() override;
397 
398 #ifdef notdef
399     OGRFeature         *GetFeature( GIntBig nFeatureId );
400     OGRErr              ISetFeature( OGRFeature *poFeature );
401     OGRErr              ICreateFeature( OGRFeature *poFeature );
402 #endif
403 
GetLayerDefn()404     OGRFeatureDefn *    GetLayerDefn() override { return poFeatureDefn; }
405 
406 #ifdef notdef
407     GIntBig             GetFeatureCount( int );
408 #endif
409 
410     int                 TestCapability( const char * ) override;
411 
412     // special to NTF
413     OGRFeature         *FeatureTranslate( NTFFileReader *, NTFRecord ** );
414 };
415 
416 /************************************************************************/
417 /*                       OGRNTFFeatureClassLayer                        */
418 /************************************************************************/
419 
420 class OGRNTFFeatureClassLayer final: public OGRLayer
421 {
422     OGRFeatureDefn     *poFeatureDefn;
423     OGRGeometry        *poFilterGeom;
424 
425     OGRNTFDataSource   *poDS;
426 
427     GIntBig            iCurrentFC;
428 
429   public:
430     explicit             OGRNTFFeatureClassLayer( OGRNTFDataSource * poDS );
431                         ~OGRNTFFeatureClassLayer();
432 
GetSpatialFilter()433     OGRGeometry *       GetSpatialFilter() override { return poFilterGeom; }
434     void                SetSpatialFilter( OGRGeometry * ) override;
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)435     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override
436                 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); }
437 
438     void                ResetReading() override;
439     OGRFeature *        GetNextFeature() override;
440 
441     OGRFeature         *GetFeature( GIntBig nFeatureId ) override;
442 
GetLayerDefn()443     OGRFeatureDefn *    GetLayerDefn() override { return poFeatureDefn; }
444 
445     GIntBig             GetFeatureCount( int = TRUE ) override;
446 
447     int                 TestCapability( const char * ) override;
448 };
449 
450 /************************************************************************/
451 /*                          OGRNTFRasterLayer                           */
452 /************************************************************************/
453 
454 class OGRNTFRasterLayer final: public OGRLayer
455 {
456     OGRFeatureDefn     *poFeatureDefn;
457     OGRGeometry        *poFilterGeom;
458 
459     NTFFileReader      *poReader;
460 
461     float              *pafColumn;
462     int                 iColumnOffset;
463 
464     GIntBig             iCurrentFC;
465 
466     int                 nDEMSample;
467     GIntBig             nFeatureCount;
468 
469   public:
470                         OGRNTFRasterLayer( OGRNTFDataSource * poDS,
471                                            NTFFileReader * poReaderIn );
472                         virtual ~OGRNTFRasterLayer();
473 
GetSpatialFilter()474     OGRGeometry *       GetSpatialFilter() override { return poFilterGeom; }
475     void                SetSpatialFilter( OGRGeometry * ) override;
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)476     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override
477                 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); }
478 
479     void                ResetReading() override;
480     OGRFeature *        GetNextFeature() override;
481 
482     OGRFeature         *GetFeature( GIntBig nFeatureId ) override;
483 
GetLayerDefn()484     OGRFeatureDefn *    GetLayerDefn() override { return poFeatureDefn; }
485 
486     GIntBig             GetFeatureCount( int = TRUE ) override;
487 
488     int                 TestCapability( const char * ) override;
489 };
490 
491 /************************************************************************/
492 /*                           OGRNTFDataSource                           */
493 /************************************************************************/
494 
495 class OGRNTFDataSource final: public OGRDataSource
496 {
497     char                *pszName;
498 
499     int                 nLayers;
500     OGRLayer            **papoLayers;
501 
502     OGRNTFFeatureClassLayer *poFCLayer;
503 
504     int                 iCurrentFC;
505     int                 iCurrentReader;
506     vsi_l_offset        nCurrentPos;
507     long                nCurrentFID;
508 
509     int                 nNTFFileCount;
510     NTFFileReader       **papoNTFFileReader;
511 
512     int                 nFCCount;
513     char              **papszFCNum;
514     char              **papszFCName;
515 
516     OGRSpatialReference *poSpatialRef;
517 
518     NTFGenericClass     aoGenericClass[100];
519 
520     char                **papszOptions;
521 
522     void                EnsureTileNameUnique( NTFFileReader * );
523 
524     CPL_DISALLOW_COPY_ASSIGN(OGRNTFDataSource)
525 
526   public:
527                         OGRNTFDataSource();
528                         ~OGRNTFDataSource();
529 
530     void                SetOptionList( char ** );
531     const char         *GetOption( const char * );
532 
533     int                 Open( const char * pszName, int bTestOpen = FALSE,
534                               char ** papszFileList = nullptr );
535 
GetName()536     const char          *GetName() override { return pszName; }
537     int                 GetLayerCount() override;
538     OGRLayer            *GetLayer( int ) override;
539     int                 TestCapability( const char * ) override;
540 
541     // Note: these are specific to NTF for now, but eventually might
542     // might be available as part of a more object oriented approach to
543     // features like that in FME or SFCORBA.
544     virtual void        ResetReading() override;
545     virtual OGRFeature* GetNextFeature( OGRLayer** ppoBelongingLayer,
546                                         double* pdfProgressPct,
547                                         GDALProgressFunc pfnProgress,
548                                         void* pProgressData ) override;
549 
550     // these are only for the use of the NTFFileReader class.
551     OGRNTFLayer         *GetNamedLayer( const char * );
552     void                 AddLayer( OGRLayer * );
553 
554     // Mainly for OGRNTFLayer class
GetFileCount()555     int                  GetFileCount() { return nNTFFileCount; }
GetFileReader(int i)556     NTFFileReader       *GetFileReader(int i) { return papoNTFFileReader[i]; }
557 
GetFCCount()558     int                  GetFCCount() { return nFCCount; }
559     int                  GetFeatureClass( int, char **, char ** );
560 
DSGetSpatialRef()561     OGRSpatialReference *DSGetSpatialRef() { return poSpatialRef; }
562 
GetGClass(int i)563     NTFGenericClass     *GetGClass( int i ) { return aoGenericClass + i; }
564     void                WorkupGeneric( NTFFileReader * );
565     void                EstablishGenericLayers();
566 };
567 
568 /************************************************************************/
569 /*                          Support functions.                          */
570 /************************************************************************/
571 int NTFArcCenterFromEdgePoints( double x_c0, double y_c0,
572                                 double x_c1, double y_c1,
573                                 double x_c2, double y_c2,
574                                 double *x_center, double *y_center );
575 OGRGeometry *
576 NTFStrokeArcToOGRGeometry_Points( double dfStartX, double dfStartY,
577                                   double dfAlongX, double dfAlongY,
578                                   double dfEndX, double dfEndY,
579                                   int nVertexCount );
580 OGRGeometry *
581 NTFStrokeArcToOGRGeometry_Angles( double dfCenterX, double dfCenterY,
582                                   double dfRadius,
583                                   double dfStartAngle, double dfEndAngle,
584                                   int nVertexCount );
585 
586 #endif /* ndef NTF_H_INCLUDED */
587