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