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