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 SetSpatialFilter(OGRGeometry *) override;
508 :
509 0 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
510 : {
511 0 : OGRLayer::SetSpatialFilter(iGeomField, poGeom);
512 0 : }
513 :
514 : void ResetReading() override;
515 : OGRFeature *GetNextFeature() override;
516 :
517 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
518 :
519 0 : OGRFeatureDefn *GetLayerDefn() override
520 : {
521 0 : return poFeatureDefn;
522 : }
523 :
524 : GIntBig GetFeatureCount(int = TRUE) override;
525 :
526 : int TestCapability(const char *) override;
527 : };
528 :
529 : /************************************************************************/
530 : /* OGRNTFRasterLayer */
531 : /************************************************************************/
532 :
533 : class OGRNTFRasterLayer final : public OGRLayer
534 : {
535 : OGRFeatureDefn *poFeatureDefn;
536 : OGRGeometry *poFilterGeom;
537 :
538 : NTFFileReader *poReader;
539 :
540 : float *pafColumn;
541 : int iColumnOffset;
542 :
543 : GIntBig iCurrentFC;
544 :
545 : int nDEMSample;
546 : GIntBig nFeatureCount;
547 :
548 : public:
549 : OGRNTFRasterLayer(OGRNTFDataSource *poDS, NTFFileReader *poReaderIn);
550 : virtual ~OGRNTFRasterLayer();
551 :
552 0 : OGRGeometry *GetSpatialFilter() override
553 : {
554 0 : return poFilterGeom;
555 : }
556 :
557 : void SetSpatialFilter(OGRGeometry *) override;
558 :
559 0 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
560 : {
561 0 : OGRLayer::SetSpatialFilter(iGeomField, poGeom);
562 0 : }
563 :
564 : void ResetReading() override;
565 : OGRFeature *GetNextFeature() override;
566 :
567 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
568 :
569 0 : OGRFeatureDefn *GetLayerDefn() override
570 : {
571 0 : return poFeatureDefn;
572 : }
573 :
574 : GIntBig GetFeatureCount(int = TRUE) override;
575 :
576 : int TestCapability(const char *) override;
577 : };
578 :
579 : /************************************************************************/
580 : /* OGRNTFDataSource */
581 : /************************************************************************/
582 :
583 : class OGRNTFDataSource final : public GDALDataset
584 : {
585 : int nLayers;
586 : OGRLayer **papoLayers;
587 :
588 : OGRNTFFeatureClassLayer *poFCLayer;
589 :
590 : int iCurrentFC;
591 : int iCurrentReader;
592 : vsi_l_offset nCurrentPos;
593 : long nCurrentFID;
594 :
595 : int nNTFFileCount;
596 : NTFFileReader **papoNTFFileReader;
597 :
598 : int nFCCount;
599 : char **papszFCNum;
600 : char **papszFCName;
601 :
602 : OGRSpatialReference *poSpatialRef;
603 :
604 : NTFGenericClass aoGenericClass[100];
605 :
606 : char **papszOptions;
607 :
608 : void EnsureTileNameUnique(NTFFileReader *);
609 :
610 : CPL_DISALLOW_COPY_ASSIGN(OGRNTFDataSource)
611 :
612 : public:
613 : OGRNTFDataSource();
614 : ~OGRNTFDataSource();
615 :
616 : void SetOptionList(char **);
617 : const char *GetOption(const char *);
618 :
619 : int Open(const char *pszName, int bTestOpen = FALSE,
620 : char **papszFileList = nullptr);
621 :
622 : int GetLayerCount() override;
623 : OGRLayer *GetLayer(int) override;
624 : int TestCapability(const char *) override;
625 :
626 : // Note: these are specific to NTF for now, but eventually might
627 : // might be available as part of a more object oriented approach to
628 : // features like that in FME or SFCORBA.
629 : virtual void ResetReading() override;
630 : virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
631 : double *pdfProgressPct,
632 : GDALProgressFunc pfnProgress,
633 : void *pProgressData) override;
634 :
635 : // these are only for the use of the NTFFileReader class.
636 : OGRNTFLayer *GetNamedLayer(const char *);
637 : void AddLayer(OGRLayer *);
638 :
639 : // Mainly for OGRNTFLayer class
640 0 : int GetFileCount()
641 : {
642 0 : return nNTFFileCount;
643 : }
644 :
645 0 : NTFFileReader *GetFileReader(int i)
646 : {
647 0 : return papoNTFFileReader[i];
648 : }
649 :
650 0 : int GetFCCount()
651 : {
652 0 : return nFCCount;
653 : }
654 :
655 : int GetFeatureClass(int, char **, char **);
656 :
657 0 : OGRSpatialReference *DSGetSpatialRef()
658 : {
659 0 : return poSpatialRef;
660 : }
661 :
662 0 : NTFGenericClass *GetGClass(int i)
663 : {
664 0 : return aoGenericClass + i;
665 : }
666 :
667 : void WorkupGeneric(NTFFileReader *);
668 : void EstablishGenericLayers();
669 : };
670 :
671 : /************************************************************************/
672 : /* Support functions. */
673 : /************************************************************************/
674 : int NTFArcCenterFromEdgePoints(double x_c0, double y_c0, double x_c1,
675 : double y_c1, double x_c2, double y_c2,
676 : double *x_center, double *y_center);
677 : OGRGeometry *NTFStrokeArcToOGRGeometry_Points(double dfStartX, double dfStartY,
678 : double dfAlongX, double dfAlongY,
679 : double dfEndX, double dfEndY,
680 : int nVertexCount);
681 : OGRGeometry *NTFStrokeArcToOGRGeometry_Angles(double dfCenterX,
682 : double dfCenterY, double dfRadius,
683 : double dfStartAngle,
684 : double dfEndAngle,
685 : int nVertexCount);
686 :
687 : #endif /* ndef NTF_H_INCLUDED */
|