1 : /******************************************************************************
2 : * $Id: ntf_estlayers.cpp 15637 2008-10-29 16:06:38Z warmerdam $
3 : *
4 : * Project: NTF Translator
5 : * Purpose: NTFFileReader methods related to establishing the schemas
6 : * of features that could occur in this product and the functions
7 : * for actually performing the NTFRecord to OGRFeature conversion.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Frank Warmerdam
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include <stdarg.h>
33 : #include "ntf.h"
34 : #include "cpl_string.h"
35 :
36 : CPL_CVSID("$Id: ntf_estlayers.cpp 15637 2008-10-29 16:06:38Z warmerdam $");
37 :
38 : #define MAX_LINK 5000
39 :
40 : /************************************************************************/
41 : /* TranslateCodePoint() */
42 : /* */
43 : /* Used for code point, and code point plus. */
44 : /************************************************************************/
45 :
46 0 : static OGRFeature *TranslateCodePoint( NTFFileReader *poReader,
47 : OGRNTFLayer *poLayer,
48 : NTFRecord **papoGroup )
49 :
50 : {
51 0 : if( CSLCount((char **) papoGroup) < 2
52 0 : || papoGroup[0]->GetType() != NRT_POINTREC
53 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
54 0 : return NULL;
55 :
56 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
57 :
58 : // POINT_ID
59 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
60 :
61 : // Geometry
62 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
63 :
64 : // Attributes
65 0 : if( EQUAL(poLayer->GetLayerDefn()->GetName(),"CODE_POINT") )
66 : poReader->ApplyAttributeValues( poFeature, papoGroup,
67 : "PC", 1, "PQ", 2, "PR", 3, "TP", 4,
68 : "DQ", 5, "RP", 6, "BP", 7, "PD", 8,
69 : "MP", 9, "UM", 10, "RV", 11,
70 0 : NULL );
71 : else
72 : poReader->ApplyAttributeValues( poFeature, papoGroup,
73 : "PC", 1, "PQ", 2, "PR", 3, "TP", 4,
74 : "DQ", 5, "RP", 6, "BP", 7, "PD", 8,
75 : "MP", 9, "UM", 10, "RV", 11,
76 : "RH", 12, "LH", 13, "CC", 14,
77 : "DC", 15, "WC", 16,
78 0 : NULL );
79 :
80 0 : return poFeature;
81 : }
82 :
83 : /************************************************************************/
84 : /* TranslateAddressPoint() */
85 : /************************************************************************/
86 :
87 0 : static OGRFeature *TranslateAddressPoint( NTFFileReader *poReader,
88 : OGRNTFLayer *poLayer,
89 : NTFRecord **papoGroup )
90 :
91 : {
92 0 : if( CSLCount((char **) papoGroup) < 2
93 0 : || papoGroup[0]->GetType() != NRT_POINTREC
94 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
95 0 : return NULL;
96 :
97 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
98 :
99 : // POINT_ID
100 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
101 :
102 : // CHG_TYPE
103 0 : poFeature->SetField( 17, papoGroup[0]->GetField( 22, 22 ) );
104 :
105 : // CHG_DATE
106 0 : poFeature->SetField( 18, papoGroup[0]->GetField( 23, 28 ) );
107 :
108 : // Geometry
109 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
110 :
111 : // Attributes
112 : poReader->ApplyAttributeValues( poFeature, papoGroup,
113 : "OA", 1, "ON", 2, "DP", 3, "PB", 4,
114 : "SB", 5, "BD", 6, "BN", 7, "DR", 8,
115 : "TN", 9, "DD", 10, "DL", 11, "PT", 12,
116 : "CN", 13, "PC", 14, "SF", 15, "RV", 16,
117 0 : NULL );
118 :
119 0 : return poFeature;
120 : }
121 :
122 : /************************************************************************/
123 : /* TranslateOscarPoint() */
124 : /* */
125 : /* Used for OSCAR Traffic and Asset datasets. */
126 : /************************************************************************/
127 :
128 0 : static OGRFeature *TranslateOscarPoint( NTFFileReader *poReader,
129 : OGRNTFLayer *poLayer,
130 : NTFRecord **papoGroup )
131 :
132 : {
133 0 : if( CSLCount((char **) papoGroup) < 2
134 0 : || papoGroup[0]->GetType() != NRT_POINTREC
135 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
136 0 : return NULL;
137 :
138 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
139 :
140 : // POINT_ID
141 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
142 :
143 : // Geometry
144 : int nGeomId;
145 :
146 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
147 0 : &nGeomId));
148 :
149 0 : poFeature->SetField( 1, nGeomId );
150 :
151 : // Attributes
152 : poReader->ApplyAttributeValues( poFeature, papoGroup,
153 : "FC", 2, "OD", 3, "JN", 4, "SN", 5,
154 0 : NULL );
155 :
156 0 : return poFeature;
157 : }
158 :
159 : /************************************************************************/
160 : /* TranslateOscarLine() */
161 : /************************************************************************/
162 :
163 0 : static OGRFeature *TranslateOscarLine( NTFFileReader *poReader,
164 : OGRNTFLayer *poLayer,
165 : NTFRecord **papoGroup )
166 :
167 : {
168 0 : if( CSLCount((char **) papoGroup) < 2
169 0 : || papoGroup[0]->GetType() != NRT_LINEREC
170 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
171 0 : return NULL;
172 :
173 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
174 :
175 : // LINE_ID
176 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
177 :
178 : // Geometry
179 : int nGeomId;
180 :
181 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
182 0 : &nGeomId));
183 :
184 0 : poFeature->SetField( 1, nGeomId );
185 :
186 : // Attributes
187 : poReader->ApplyAttributeValues( poFeature, papoGroup,
188 : "FC", 2, "OD", 3, "PN", 4, "LL", 5,
189 : "SC", 6, "FW", 7, "RN", 8, "TR", 9,
190 0 : NULL );
191 :
192 0 : return poFeature;
193 : }
194 :
195 : /************************************************************************/
196 : /* TranslateOscarRoutePoint() */
197 : /************************************************************************/
198 :
199 0 : static OGRFeature *TranslateOscarRoutePoint( NTFFileReader *poReader,
200 : OGRNTFLayer *poLayer,
201 : NTFRecord **papoGroup )
202 :
203 : {
204 0 : if( CSLCount((char **) papoGroup) < 2
205 0 : || papoGroup[0]->GetType() != NRT_POINTREC
206 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
207 0 : return NULL;
208 :
209 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
210 :
211 : // POINT_ID
212 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
213 :
214 : // Geometry
215 : int nGeomId;
216 :
217 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
218 0 : &nGeomId));
219 :
220 0 : poFeature->SetField( 1, nGeomId );
221 :
222 : // Attributes
223 : poReader->ApplyAttributeValues( poFeature, papoGroup,
224 : "FC", 2, "OD", 3, "JN", 4, "SN", 5,
225 : "NP", 6, "RT", 8,
226 0 : NULL );
227 :
228 : // PARENT_OSODR
229 : char **papszTypes, **papszValues;
230 :
231 0 : if( poReader->ProcessAttRecGroup( papoGroup, &papszTypes, &papszValues ) )
232 : {
233 0 : char **papszOSODRList = NULL;
234 :
235 0 : for( int i = 0; papszTypes != NULL && papszTypes[i] != NULL; i++ )
236 : {
237 0 : if( EQUAL(papszTypes[i],"PO") )
238 0 : papszOSODRList = CSLAddString(papszOSODRList,papszValues[i]);
239 : }
240 :
241 0 : poFeature->SetField( 7, papszOSODRList );
242 : CPLAssert( CSLCount(papszOSODRList) ==
243 : poFeature->GetFieldAsInteger( 6 ) );
244 :
245 0 : CSLDestroy( papszOSODRList );
246 0 : CSLDestroy( papszTypes );
247 0 : CSLDestroy( papszValues );
248 : }
249 :
250 0 : return poFeature;
251 : }
252 :
253 : /************************************************************************/
254 : /* TranslateOscarRouteLine() */
255 : /************************************************************************/
256 :
257 0 : static OGRFeature *TranslateOscarRouteLine( NTFFileReader *poReader,
258 : OGRNTFLayer *poLayer,
259 : NTFRecord **papoGroup )
260 :
261 : {
262 0 : if( CSLCount((char **) papoGroup) < 2
263 0 : || papoGroup[0]->GetType() != NRT_LINEREC
264 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
265 0 : return NULL;
266 :
267 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
268 :
269 : // LINE_ID
270 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
271 :
272 : // Geometry
273 : int nGeomId;
274 :
275 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
276 0 : &nGeomId));
277 :
278 0 : poFeature->SetField( 1, nGeomId );
279 :
280 : // Attributes
281 : poReader->ApplyAttributeValues( poFeature, papoGroup,
282 : "FC", 2, "OD", 3, "PN", 4, "LL", 5,
283 : "RN", 6, "TR", 7, "NP", 8,
284 0 : NULL );
285 :
286 : // PARENT_OSODR
287 : char **papszTypes, **papszValues;
288 :
289 0 : if( poReader->ProcessAttRecGroup( papoGroup, &papszTypes, &papszValues ) )
290 : {
291 0 : char **papszOSODRList = NULL;
292 :
293 0 : for( int i = 0; papszTypes != NULL && papszTypes[i] != NULL; i++ )
294 : {
295 0 : if( EQUAL(papszTypes[i],"PO") )
296 0 : papszOSODRList = CSLAddString(papszOSODRList,papszValues[i]);
297 : }
298 :
299 0 : poFeature->SetField( 9, papszOSODRList );
300 : CPLAssert( CSLCount(papszOSODRList) ==
301 : poFeature->GetFieldAsInteger( 8 ) );
302 :
303 0 : CSLDestroy( papszOSODRList );
304 0 : CSLDestroy( papszTypes );
305 0 : CSLDestroy( papszValues );
306 : }
307 :
308 0 : return poFeature;
309 : }
310 :
311 : /************************************************************************/
312 : /* TranslateOscarComment() */
313 : /************************************************************************/
314 :
315 0 : static OGRFeature *TranslateOscarComment( NTFFileReader *poReader,
316 : OGRNTFLayer *poLayer,
317 : NTFRecord **papoGroup )
318 :
319 : {
320 0 : if( CSLCount((char **) papoGroup) != 1
321 0 : || papoGroup[0]->GetType() != NRT_COMMENT )
322 0 : return NULL;
323 :
324 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
325 :
326 : // RECORD_TYPE
327 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 4 )) );
328 :
329 : // RECORD_ID
330 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 5, 17 ) );
331 :
332 : // CHANGE_TYPE
333 0 : poFeature->SetField( 2, papoGroup[0]->GetField( 18, 18 ) );
334 :
335 0 : return poFeature;
336 : }
337 :
338 : /************************************************************************/
339 : /* TranslateOscarNetworkPoint() */
340 : /************************************************************************/
341 :
342 0 : static OGRFeature *TranslateOscarNetworkPoint( NTFFileReader *poReader,
343 : OGRNTFLayer *poLayer,
344 : NTFRecord **papoGroup )
345 :
346 : {
347 0 : if( CSLCount((char **) papoGroup) < 2
348 0 : || papoGroup[0]->GetType() != NRT_POINTREC
349 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
350 0 : return NULL;
351 :
352 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
353 :
354 : // POINT_ID
355 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
356 :
357 : // Geometry
358 : int nGeomId;
359 :
360 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
361 0 : &nGeomId));
362 :
363 0 : poFeature->SetField( 1, nGeomId );
364 :
365 : // Attributes
366 : poReader->ApplyAttributeValues( poFeature, papoGroup,
367 : "FC", 2, "OD", 3, "JN", 4, "SN", 5,
368 : "RT", 6,
369 0 : NULL );
370 :
371 0 : return poFeature;
372 : }
373 :
374 : /************************************************************************/
375 : /* TranslateOscarNetworkLine() */
376 : /************************************************************************/
377 :
378 0 : static OGRFeature *TranslateOscarNetworkLine( NTFFileReader *poReader,
379 : OGRNTFLayer *poLayer,
380 : NTFRecord **papoGroup )
381 :
382 : {
383 0 : if( CSLCount((char **) papoGroup) < 2
384 0 : || papoGroup[0]->GetType() != NRT_LINEREC
385 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
386 0 : return NULL;
387 :
388 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
389 :
390 : // LINE_ID
391 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
392 :
393 : // Geometry
394 : int nGeomId;
395 :
396 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
397 0 : &nGeomId));
398 :
399 0 : poFeature->SetField( 1, nGeomId );
400 :
401 : // Attributes
402 : poReader->ApplyAttributeValues( poFeature, papoGroup,
403 : "FC", 2, "OD", 3, "PN", 4, "LL", 5,
404 : "RN", 6,
405 0 : NULL );
406 :
407 0 : return poFeature;
408 : }
409 :
410 : /************************************************************************/
411 : /* TranslateBasedataPoint() */
412 : /************************************************************************/
413 :
414 0 : static OGRFeature *TranslateBasedataPoint( NTFFileReader *poReader,
415 : OGRNTFLayer *poLayer,
416 : NTFRecord **papoGroup )
417 :
418 : {
419 0 : if( CSLCount((char **) papoGroup) < 2
420 0 : || papoGroup[0]->GetType() != NRT_POINTREC
421 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
422 0 : return NULL;
423 :
424 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
425 :
426 : // POINT_ID
427 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
428 :
429 : // Geometry
430 : int nGeomId;
431 :
432 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
433 0 : &nGeomId));
434 :
435 : // GEOM_ID
436 0 : poFeature->SetField( 1, nGeomId );
437 :
438 : // Attributes
439 : poReader->ApplyAttributeValues( poFeature, papoGroup,
440 : "FC", 2, "PN", 3, "NU", 4, "CM", 5,
441 : "UN", 6, "OR", 7,
442 0 : NULL );
443 :
444 0 : return poFeature;
445 : }
446 :
447 : /************************************************************************/
448 : /* TranslateBasedataLine() */
449 : /************************************************************************/
450 :
451 0 : static OGRFeature *TranslateBasedataLine( NTFFileReader *poReader,
452 : OGRNTFLayer *poLayer,
453 : NTFRecord **papoGroup )
454 :
455 : {
456 0 : if( CSLCount((char **) papoGroup) < 2
457 0 : || papoGroup[0]->GetType() != NRT_LINEREC
458 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
459 0 : return NULL;
460 :
461 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
462 :
463 : // LINE_ID
464 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
465 :
466 : // Geometry
467 : int nGeomId;
468 :
469 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
470 0 : &nGeomId));
471 :
472 : // GEOM_ID
473 0 : poFeature->SetField( 2, nGeomId );
474 :
475 : // Attributes
476 : poReader->ApplyAttributeValues( poFeature, papoGroup,
477 : "FC", 1, "PN", 3, "NU", 4, "RB", 5,
478 0 : NULL );
479 :
480 0 : return poFeature;
481 : }
482 :
483 : /************************************************************************/
484 : /* TranslateBoundarylineCollection() */
485 : /************************************************************************/
486 :
487 0 : static OGRFeature *TranslateBoundarylineCollection( NTFFileReader *poReader,
488 : OGRNTFLayer *poLayer,
489 : NTFRecord **papoGroup )
490 :
491 : {
492 0 : if( CSLCount((char **) papoGroup) != 2
493 0 : || papoGroup[0]->GetType() != NRT_COLLECT
494 0 : || papoGroup[1]->GetType() != NRT_ATTREC )
495 0 : return NULL;
496 :
497 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
498 :
499 : // COLL_ID
500 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
501 :
502 : // NUM_PARTS
503 0 : int nNumLinks = atoi(papoGroup[0]->GetField( 9, 12 ));
504 :
505 0 : if( nNumLinks > MAX_LINK )
506 : {
507 : CPLError( CE_Failure, CPLE_AppDefined,
508 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
509 0 : return poFeature;
510 : }
511 :
512 0 : poFeature->SetField( 1, nNumLinks );
513 :
514 : // POLY_ID
515 : int i, anList[MAX_LINK];
516 :
517 0 : for( i = 0; i < nNumLinks; i++ )
518 0 : anList[i] = atoi(papoGroup[0]->GetField( 15+i*8, 20+i*8 ));
519 :
520 0 : poFeature->SetField( 2, nNumLinks, anList );
521 :
522 : // Attributes
523 : poReader->ApplyAttributeValues( poFeature, papoGroup,
524 : "AI", 3, "OP", 4, "NM", 5,
525 0 : NULL );
526 :
527 0 : return poFeature;
528 : }
529 :
530 : /************************************************************************/
531 : /* TranslateBoundarylinePoly() */
532 : /************************************************************************/
533 :
534 0 : static OGRFeature *TranslateBoundarylinePoly( NTFFileReader *poReader,
535 : OGRNTFLayer *poLayer,
536 : NTFRecord **papoGroup )
537 :
538 : {
539 : /* ==================================================================== */
540 : /* Traditional POLYGON record groups. */
541 : /* ==================================================================== */
542 0 : if( CSLCount((char **) papoGroup) == 4
543 0 : && papoGroup[0]->GetType() == NRT_POLYGON
544 0 : && papoGroup[1]->GetType() == NRT_ATTREC
545 0 : && papoGroup[2]->GetType() == NRT_CHAIN
546 0 : && papoGroup[3]->GetType() == NRT_GEOMETRY )
547 : {
548 :
549 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
550 :
551 : // POLY_ID
552 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
553 :
554 : // NUM_PARTS
555 0 : int nNumLinks = atoi(papoGroup[2]->GetField( 9, 12 ));
556 :
557 0 : if( nNumLinks > MAX_LINK )
558 : {
559 : CPLError( CE_Failure, CPLE_AppDefined,
560 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
561 0 : return poFeature;
562 : }
563 :
564 0 : poFeature->SetField( 4, nNumLinks );
565 :
566 : // DIR
567 : int i, anList[MAX_LINK];
568 :
569 0 : for( i = 0; i < nNumLinks; i++ )
570 0 : anList[i] = atoi(papoGroup[2]->GetField( 19+i*7, 19+i*7 ));
571 :
572 0 : poFeature->SetField( 5, nNumLinks, anList );
573 :
574 : // GEOM_ID_OF_LINK
575 0 : for( i = 0; i < nNumLinks; i++ )
576 0 : anList[i] = atoi(papoGroup[2]->GetField( 13+i*7, 18+i*7 ));
577 :
578 0 : poFeature->SetField( 6, nNumLinks, anList );
579 :
580 : // RingStart
581 0 : int nRingList = 0;
582 0 : poFeature->SetField( 7, 1, &nRingList );
583 :
584 : // Attributes
585 : poReader->ApplyAttributeValues( poFeature, papoGroup,
586 : "FC", 1, "PI", 2, "HA", 3,
587 0 : NULL );
588 :
589 : // Read point geometry
590 : poFeature->SetGeometryDirectly(
591 0 : poReader->ProcessGeometry(papoGroup[3]));
592 :
593 : // Try to assemble polygon geometry.
594 0 : poReader->FormPolygonFromCache( poFeature );
595 :
596 0 : return poFeature;
597 : }
598 :
599 : /* ==================================================================== */
600 : /* CPOLYGON Group */
601 : /* ==================================================================== */
602 :
603 : /* -------------------------------------------------------------------- */
604 : /* First we do validation of the grouping. */
605 : /* -------------------------------------------------------------------- */
606 : int iRec;
607 :
608 0 : for( iRec = 0;
609 0 : papoGroup[iRec] != NULL && papoGroup[iRec+1] != NULL
610 0 : && papoGroup[iRec]->GetType() == NRT_POLYGON
611 0 : && papoGroup[iRec+1]->GetType() == NRT_CHAIN;
612 : iRec += 2 ) {}
613 :
614 0 : if( CSLCount((char **) papoGroup) != iRec + 3 )
615 0 : return NULL;
616 :
617 0 : if( papoGroup[iRec]->GetType() != NRT_CPOLY
618 0 : || papoGroup[iRec+1]->GetType() != NRT_ATTREC
619 0 : || papoGroup[iRec+2]->GetType() != NRT_GEOMETRY )
620 0 : return NULL;
621 :
622 : /* -------------------------------------------------------------------- */
623 : /* Collect the chains for each of the rings, and just aggregate */
624 : /* these into the master list without any concept of where the */
625 : /* boundaries are. The boundary information will be emmitted */
626 : /* in the RingStart field. */
627 : /* -------------------------------------------------------------------- */
628 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
629 0 : int nNumLink = 0;
630 : int anDirList[MAX_LINK*2], anGeomList[MAX_LINK*2];
631 0 : int anRingStart[MAX_LINK], nRings = 0;
632 :
633 0 : for( iRec = 0;
634 0 : papoGroup[iRec] != NULL && papoGroup[iRec+1] != NULL
635 0 : && papoGroup[iRec]->GetType() == NRT_POLYGON
636 0 : && papoGroup[iRec+1]->GetType() == NRT_CHAIN;
637 : iRec += 2 )
638 : {
639 : int i, nLineCount;
640 :
641 0 : nLineCount = atoi(papoGroup[iRec+1]->GetField(9,12));
642 :
643 0 : anRingStart[nRings++] = nNumLink;
644 :
645 0 : for( i = 0; i < nLineCount && nNumLink < MAX_LINK*2; i++ )
646 : {
647 0 : anDirList[nNumLink] =
648 0 : atoi(papoGroup[iRec+1]->GetField( 19+i*7, 19+i*7 ));
649 0 : anGeomList[nNumLink] =
650 0 : atoi(papoGroup[iRec+1]->GetField( 13+i*7, 18+i*7 ));
651 0 : nNumLink++;
652 : }
653 :
654 0 : if( nNumLink == MAX_LINK*2 )
655 : {
656 : CPLError( CE_Failure, CPLE_AppDefined,
657 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
658 :
659 0 : delete poFeature;
660 0 : return NULL;
661 : }
662 : }
663 :
664 : // NUM_PART
665 0 : poFeature->SetField( 4, nNumLink );
666 :
667 : // DIR
668 0 : poFeature->SetField( 5, nNumLink, anDirList );
669 :
670 : // GEOM_ID_OF_LINK
671 0 : poFeature->SetField( 6, nNumLink, anGeomList );
672 :
673 : // RingStart
674 0 : poFeature->SetField( 7, nRings, anRingStart );
675 :
676 :
677 : /* -------------------------------------------------------------------- */
678 : /* collect information for whole complex polygon. */
679 : /* -------------------------------------------------------------------- */
680 : // POLY_ID
681 0 : poFeature->SetField( 0, atoi(papoGroup[iRec]->GetField( 3, 8 )) );
682 :
683 : // Attributes
684 : poReader->ApplyAttributeValues( poFeature, papoGroup,
685 : "FC", 1, "PI", 2, "HA", 3,
686 0 : NULL );
687 :
688 : // point geometry for seed.
689 : poFeature->SetGeometryDirectly(
690 0 : poReader->ProcessGeometry(papoGroup[iRec+2]));
691 :
692 : // Try to assemble polygon geometry.
693 0 : poReader->FormPolygonFromCache( poFeature );
694 :
695 0 : return poFeature;
696 : }
697 :
698 : /************************************************************************/
699 : /* TranslateBoundarylineLink() */
700 : /************************************************************************/
701 :
702 0 : static OGRFeature *TranslateBoundarylineLink( NTFFileReader *poReader,
703 : OGRNTFLayer *poLayer,
704 : NTFRecord **papoGroup )
705 :
706 : {
707 0 : if( CSLCount((char **) papoGroup) != 2
708 0 : || papoGroup[0]->GetType() != NRT_GEOMETRY
709 0 : || papoGroup[1]->GetType() != NRT_ATTREC )
710 0 : return NULL;
711 :
712 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
713 :
714 : // Geometry
715 : int nGeomId;
716 :
717 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[0],
718 0 : &nGeomId));
719 :
720 : // GEOM_ID
721 0 : poFeature->SetField( 0, nGeomId );
722 :
723 : // Attributes
724 : poReader->ApplyAttributeValues( poFeature, papoGroup,
725 : "FC", 1, "LK", 2, "HW", 3,
726 0 : NULL );
727 :
728 0 : return poFeature;
729 : }
730 :
731 : /************************************************************************/
732 : /* TranslateBL2000Poly() */
733 : /************************************************************************/
734 :
735 0 : static OGRFeature *TranslateBL2000Poly( NTFFileReader *poReader,
736 : OGRNTFLayer *poLayer,
737 : NTFRecord **papoGroup )
738 :
739 : {
740 : /* ==================================================================== */
741 : /* Traditional POLYGON record groups. */
742 : /* ==================================================================== */
743 0 : if( CSLCount((char **) papoGroup) == 3
744 0 : && papoGroup[0]->GetType() == NRT_POLYGON
745 0 : && papoGroup[1]->GetType() == NRT_ATTREC
746 0 : && papoGroup[2]->GetType() == NRT_CHAIN )
747 : {
748 :
749 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
750 :
751 : // POLY_ID
752 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
753 :
754 : // NUM_PARTS
755 0 : int nNumLinks = atoi(papoGroup[2]->GetField( 9, 12 ));
756 :
757 0 : if( nNumLinks > MAX_LINK )
758 : {
759 : CPLError( CE_Failure, CPLE_AppDefined,
760 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
761 :
762 0 : return poFeature;
763 : }
764 :
765 0 : poFeature->SetField( 3, nNumLinks );
766 :
767 : // DIR
768 : int i, anList[MAX_LINK];
769 :
770 0 : for( i = 0; i < nNumLinks; i++ )
771 0 : anList[i] = atoi(papoGroup[2]->GetField( 19+i*7, 19+i*7 ));
772 :
773 0 : poFeature->SetField( 4, nNumLinks, anList );
774 :
775 : // GEOM_ID_OF_LINK
776 0 : for( i = 0; i < nNumLinks; i++ )
777 0 : anList[i] = atoi(papoGroup[2]->GetField( 13+i*7, 18+i*7 ));
778 :
779 0 : poFeature->SetField( 5, nNumLinks, anList );
780 :
781 : // RingStart
782 0 : int nRingList = 0;
783 0 : poFeature->SetField( 6, 1, &nRingList );
784 :
785 : // Attributes
786 : poReader->ApplyAttributeValues( poFeature, papoGroup,
787 : "PI", 1, "HA", 2,
788 0 : NULL );
789 :
790 : // Try to assemble polygon geometry.
791 0 : poReader->FormPolygonFromCache( poFeature );
792 :
793 0 : return poFeature;
794 : }
795 :
796 : /* ==================================================================== */
797 : /* CPOLYGON Group */
798 : /* ==================================================================== */
799 :
800 : /* -------------------------------------------------------------------- */
801 : /* First we do validation of the grouping. */
802 : /* -------------------------------------------------------------------- */
803 : int iRec;
804 :
805 0 : for( iRec = 0;
806 0 : papoGroup[iRec] != NULL && papoGroup[iRec+1] != NULL
807 0 : && papoGroup[iRec]->GetType() == NRT_POLYGON
808 0 : && papoGroup[iRec+1]->GetType() == NRT_CHAIN;
809 : iRec += 2 ) {}
810 :
811 0 : if( CSLCount((char **) papoGroup) != iRec + 2 )
812 0 : return NULL;
813 :
814 0 : if( papoGroup[iRec]->GetType() != NRT_CPOLY
815 0 : || papoGroup[iRec+1]->GetType() != NRT_ATTREC )
816 0 : return NULL;
817 :
818 : /* -------------------------------------------------------------------- */
819 : /* Collect the chains for each of the rings, and just aggregate */
820 : /* these into the master list without any concept of where the */
821 : /* boundaries are. The boundary information will be emmitted */
822 : /* in the RingStart field. */
823 : /* -------------------------------------------------------------------- */
824 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
825 0 : int nNumLink = 0;
826 : int anDirList[MAX_LINK*2], anGeomList[MAX_LINK*2];
827 0 : int anRingStart[MAX_LINK], nRings = 0;
828 :
829 0 : for( iRec = 0;
830 0 : papoGroup[iRec] != NULL && papoGroup[iRec+1] != NULL
831 0 : && papoGroup[iRec]->GetType() == NRT_POLYGON
832 0 : && papoGroup[iRec+1]->GetType() == NRT_CHAIN;
833 : iRec += 2 )
834 : {
835 : int i, nLineCount;
836 :
837 0 : nLineCount = atoi(papoGroup[iRec+1]->GetField(9,12));
838 :
839 0 : anRingStart[nRings++] = nNumLink;
840 :
841 0 : for( i = 0; i < nLineCount && nNumLink < MAX_LINK*2; i++ )
842 : {
843 0 : anDirList[nNumLink] =
844 0 : atoi(papoGroup[iRec+1]->GetField( 19+i*7, 19+i*7 ));
845 0 : anGeomList[nNumLink] =
846 0 : atoi(papoGroup[iRec+1]->GetField( 13+i*7, 18+i*7 ));
847 0 : nNumLink++;
848 : }
849 :
850 0 : if( nNumLink == MAX_LINK*2 )
851 : {
852 : CPLError( CE_Failure, CPLE_AppDefined,
853 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
854 :
855 0 : delete poFeature;
856 0 : return NULL;
857 : }
858 : }
859 :
860 : // NUM_PART
861 0 : poFeature->SetField( 3, nNumLink );
862 :
863 : // DIR
864 0 : poFeature->SetField( 4, nNumLink, anDirList );
865 :
866 : // GEOM_ID_OF_LINK
867 0 : poFeature->SetField( 5, nNumLink, anGeomList );
868 :
869 : // RingStart
870 0 : poFeature->SetField( 6, nRings, anRingStart );
871 :
872 :
873 : /* -------------------------------------------------------------------- */
874 : /* collect information for whole complex polygon. */
875 : /* -------------------------------------------------------------------- */
876 : // POLY_ID
877 0 : poFeature->SetField( 0, atoi(papoGroup[iRec]->GetField( 3, 8 )) );
878 :
879 : // Attributes
880 : poReader->ApplyAttributeValues( poFeature, papoGroup,
881 : "PI", 1, "HA", 2,
882 0 : NULL );
883 :
884 : // Try to assemble polygon geometry.
885 0 : poReader->FormPolygonFromCache( poFeature );
886 :
887 0 : return poFeature;
888 : }
889 :
890 : /************************************************************************/
891 : /* TranslateBL2000Link() */
892 : /************************************************************************/
893 :
894 0 : static OGRFeature *TranslateBL2000Link( NTFFileReader *poReader,
895 : OGRNTFLayer *poLayer,
896 : NTFRecord **papoGroup )
897 :
898 : {
899 0 : if( CSLCount((char **) papoGroup) != 3
900 0 : || papoGroup[0]->GetType() != NRT_LINEREC
901 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY
902 0 : || papoGroup[2]->GetType() != NRT_ATTREC )
903 0 : return NULL;
904 :
905 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
906 :
907 : // LINE_ID
908 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
909 :
910 : // Geometry
911 : int nGeomId;
912 :
913 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
914 0 : &nGeomId));
915 :
916 : // GEOM_ID
917 0 : poFeature->SetField( 1, nGeomId );
918 :
919 : // Attributes
920 : poReader->ApplyAttributeValues( poFeature, papoGroup,
921 : "FC", 2, "LK", 3,
922 0 : NULL );
923 :
924 0 : return poFeature;
925 : }
926 :
927 : /************************************************************************/
928 : /* TranslateBL2000Collection() */
929 : /************************************************************************/
930 :
931 0 : static OGRFeature *TranslateBL2000Collection( NTFFileReader *poReader,
932 : OGRNTFLayer *poLayer,
933 : NTFRecord **papoGroup )
934 :
935 : {
936 0 : if( CSLCount((char **) papoGroup) < 2
937 0 : || papoGroup[0]->GetType() != NRT_COLLECT
938 0 : || papoGroup[1]->GetType() != NRT_ATTREC )
939 0 : return NULL;
940 :
941 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
942 :
943 : // COLL_ID
944 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
945 :
946 : // NUM_PARTS
947 0 : int nNumLinks = atoi(papoGroup[0]->GetField( 9, 12 ));
948 :
949 0 : if( nNumLinks > MAX_LINK )
950 : {
951 : CPLError( CE_Failure, CPLE_AppDefined,
952 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
953 :
954 0 : return poFeature;
955 : }
956 :
957 0 : poFeature->SetField( 1, nNumLinks );
958 :
959 : // POLY_ID / COLL_ID_REFS
960 : int i, anList[MAX_LINK], anCollList[MAX_LINK];
961 0 : int nPolys=0, nCollections=0;
962 :
963 0 : for( i = 0; i < nNumLinks; i++ )
964 : {
965 0 : if( atoi(papoGroup[0]->GetField( 13+i*8, 14+i*8 )) == 34 )
966 0 : anCollList[nCollections++] =
967 0 : atoi(papoGroup[0]->GetField( 15+i*8, 20+i*8 ));
968 : else
969 0 : anList[nPolys++] =
970 0 : atoi(papoGroup[0]->GetField( 15+i*8, 20+i*8 ));
971 : }
972 :
973 0 : poFeature->SetField( 2, nPolys, anList );
974 0 : poFeature->SetField( 10, nCollections, anCollList );
975 :
976 : // Attributes
977 : // Node that _CODE_DESC values are automatically applied if
978 : // the target fields exist.
979 : poReader->ApplyAttributeValues( poFeature, papoGroup,
980 : "AI", 3, "OP", 4, "NM", 5, "TY", 6,
981 : "AC", 7, "NB", 8, "NA", 9,
982 0 : NULL );
983 :
984 0 : return poFeature;
985 : }
986 :
987 : /************************************************************************/
988 : /* TranslateMeridianPoint() */
989 : /************************************************************************/
990 :
991 0 : static OGRFeature *TranslateMeridianPoint( NTFFileReader *poReader,
992 : OGRNTFLayer *poLayer,
993 : NTFRecord **papoGroup )
994 :
995 : {
996 0 : if( CSLCount((char **) papoGroup) < 2
997 0 : || papoGroup[0]->GetType() != NRT_POINTREC
998 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
999 0 : return NULL;
1000 :
1001 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1002 :
1003 : // POINT_ID
1004 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1005 :
1006 : // Geometry
1007 : int nGeomId;
1008 :
1009 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1010 0 : &nGeomId));
1011 :
1012 : // GEOM_ID
1013 0 : poFeature->SetField( 1, nGeomId );
1014 :
1015 : // Attributes
1016 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1017 : "FC", 2, "PN", 3, "OS", 4, "JN", 5,
1018 : "RT", 6, "SI", 7, "PI", 8, "NM", 9,
1019 : "DA", 10,
1020 0 : NULL );
1021 :
1022 0 : return poFeature;
1023 : }
1024 :
1025 : /************************************************************************/
1026 : /* TranslateMeridianLine() */
1027 : /************************************************************************/
1028 :
1029 0 : static OGRFeature *TranslateMeridianLine( NTFFileReader *poReader,
1030 : OGRNTFLayer *poLayer,
1031 : NTFRecord **papoGroup )
1032 :
1033 : {
1034 0 : if( CSLCount((char **) papoGroup) < 2
1035 0 : || papoGroup[0]->GetType() != NRT_LINEREC
1036 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1037 0 : return NULL;
1038 :
1039 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1040 :
1041 : // LINE_ID
1042 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1043 :
1044 : // Geometry
1045 : int nGeomId;
1046 :
1047 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1048 0 : &nGeomId));
1049 :
1050 : // GEOM_ID
1051 0 : poFeature->SetField( 2, nGeomId );
1052 :
1053 : // Attributes
1054 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1055 : "FC", 1, "OM", 3, "RN", 4, "TR", 5,
1056 : "RI", 6, "LC", 7, "RC", 8, "LD", 9,
1057 : "RD", 10,
1058 0 : NULL );
1059 :
1060 0 : return poFeature;
1061 : }
1062 :
1063 : /************************************************************************/
1064 : /* TranslateMeridian2Point() */
1065 : /************************************************************************/
1066 :
1067 409 : static OGRFeature *TranslateMeridian2Point( NTFFileReader *poReader,
1068 : OGRNTFLayer *poLayer,
1069 : NTFRecord **papoGroup )
1070 :
1071 : {
1072 1227 : if( CSLCount((char **) papoGroup) < 2
1073 409 : || papoGroup[0]->GetType() != NRT_POINTREC
1074 409 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1075 0 : return NULL;
1076 :
1077 409 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1078 :
1079 : // POINT_ID
1080 409 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1081 :
1082 : // Geometry
1083 : int nGeomId;
1084 :
1085 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1086 409 : &nGeomId));
1087 :
1088 : // GEOM_ID
1089 409 : poFeature->SetField( 1, nGeomId );
1090 :
1091 : // Attributes
1092 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1093 : "FC", 2, "PN", 3, "OD", 4, "PO", 5,
1094 : "JN", 6, "RT", 7, "SN", 8, "SI", 9,
1095 : "PI", 10, "NM", 11, "DA", 12,
1096 : "WA", 13, "HT", 14, "FA", 15,
1097 409 : NULL );
1098 :
1099 409 : return poFeature;
1100 : }
1101 :
1102 : /************************************************************************/
1103 : /* TranslateMeridian2Line() */
1104 : /************************************************************************/
1105 :
1106 514 : static OGRFeature *TranslateMeridian2Line( NTFFileReader *poReader,
1107 : OGRNTFLayer *poLayer,
1108 : NTFRecord **papoGroup )
1109 :
1110 : {
1111 1542 : if( CSLCount((char **) papoGroup) < 2
1112 514 : || papoGroup[0]->GetType() != NRT_LINEREC
1113 514 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1114 0 : return NULL;
1115 :
1116 514 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1117 :
1118 : // LINE_ID
1119 514 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1120 :
1121 : // Geometry
1122 : int nGeomId;
1123 :
1124 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1125 514 : &nGeomId));
1126 :
1127 : // GEOM_ID
1128 514 : poFeature->SetField( 2, nGeomId );
1129 :
1130 : // Attributes
1131 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1132 : "FC", 1, "OD", 3, "PO", 4, "RN", 5,
1133 : "TR", 6, "PN", 7, "RI", 8, "LC", 9,
1134 : "RC", 10, "LD", 11, "RD", 12, "WI", 14,
1135 514 : NULL );
1136 :
1137 :
1138 514 : return poFeature;
1139 : }
1140 :
1141 : /************************************************************************/
1142 : /* TranslateStrategiNode() */
1143 : /* */
1144 : /* Also used for Meridian, Oscar and BaseData.GB nodes. */
1145 : /************************************************************************/
1146 :
1147 11388 : static OGRFeature *TranslateStrategiNode( NTFFileReader *poReader,
1148 : OGRNTFLayer *poLayer,
1149 : NTFRecord **papoGroup )
1150 :
1151 : {
1152 22776 : if( CSLCount((char **) papoGroup) != 1
1153 11388 : || papoGroup[0]->GetType() != NRT_NODEREC )
1154 0 : return NULL;
1155 :
1156 11388 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1157 :
1158 : // NODE_ID
1159 11388 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1160 :
1161 : // GEOM_ID_OF_POINT
1162 11388 : poFeature->SetField( 1, atoi(papoGroup[0]->GetField( 9, 14 )) );
1163 :
1164 : // NUM_LINKS
1165 11388 : int nNumLinks = atoi(papoGroup[0]->GetField( 15, 18 ));
1166 :
1167 11388 : if( nNumLinks > MAX_LINK )
1168 : {
1169 : CPLError( CE_Failure, CPLE_AppDefined,
1170 0 : "MAX_LINK exceeded in ntf_estlayers.cpp." );
1171 :
1172 0 : return poFeature;
1173 : }
1174 :
1175 11388 : poFeature->SetField( 2, nNumLinks );
1176 :
1177 : // DIR
1178 : int i, anList[MAX_LINK];
1179 :
1180 41521 : for( i = 0; i < nNumLinks; i++ )
1181 30133 : anList[i] = atoi(papoGroup[0]->GetField( 19+i*12, 19+i*12 ));
1182 :
1183 11388 : poFeature->SetField( 3, nNumLinks, anList );
1184 :
1185 : // GEOM_ID_OF_POINT
1186 41521 : for( i = 0; i < nNumLinks; i++ )
1187 30133 : anList[i] = atoi(papoGroup[0]->GetField( 19+i*12+1, 19+i*12+6 ));
1188 :
1189 11388 : poFeature->SetField( 4, nNumLinks, anList );
1190 :
1191 : // LEVEL
1192 41521 : for( i = 0; i < nNumLinks; i++ )
1193 30133 : anList[i] = atoi(papoGroup[0]->GetField( 19+i*12+11, 19+i*12+11 ));
1194 :
1195 11388 : poFeature->SetField( 5, nNumLinks, anList );
1196 :
1197 : // ORIENT (optional)
1198 11388 : if( EQUAL(poFeature->GetDefnRef()->GetFieldDefn(6)->GetNameRef(),
1199 : "ORIENT") )
1200 : {
1201 : double adfList[MAX_LINK];
1202 :
1203 41521 : for( i = 0; i < nNumLinks; i++ )
1204 30133 : adfList[i] =
1205 30133 : atoi(papoGroup[0]->GetField( 19+i*12+7, 19+i*12+10 )) * 0.1;
1206 :
1207 11388 : poFeature->SetField( 6, nNumLinks, adfList );
1208 : }
1209 :
1210 11388 : return poFeature;
1211 : }
1212 :
1213 : /************************************************************************/
1214 : /* TranslateStrategiText() */
1215 : /* */
1216 : /* Also used for Meridian, BaseData and Generic text. */
1217 : /************************************************************************/
1218 :
1219 1342 : static OGRFeature *TranslateStrategiText( NTFFileReader *poReader,
1220 : OGRNTFLayer *poLayer,
1221 : NTFRecord **papoGroup )
1222 :
1223 : {
1224 6710 : if( CSLCount((char **) papoGroup) < 4
1225 1342 : || papoGroup[0]->GetType() != NRT_TEXTREC
1226 1342 : || papoGroup[1]->GetType() != NRT_TEXTPOS
1227 1342 : || papoGroup[2]->GetType() != NRT_TEXTREP
1228 1342 : || papoGroup[3]->GetType() != NRT_GEOMETRY )
1229 0 : return NULL;
1230 :
1231 1342 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1232 :
1233 : // POINT_ID
1234 1342 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1235 :
1236 : // FONT
1237 1342 : poFeature->SetField( 2, atoi(papoGroup[2]->GetField( 9, 12 )) );
1238 :
1239 : // TEXT_HT
1240 1342 : poFeature->SetField( 3, atoi(papoGroup[2]->GetField( 13, 15 )) * 0.1 );
1241 :
1242 : // DIG_POSTN
1243 1342 : poFeature->SetField( 4, atoi(papoGroup[2]->GetField( 16, 16 )) );
1244 :
1245 : // ORIENT
1246 1342 : poFeature->SetField( 5, atoi(papoGroup[2]->GetField( 17, 20 )) * 0.1 );
1247 :
1248 : // TEXT_HT_GROUND
1249 : poFeature->SetField( 7, poFeature->GetFieldAsDouble(3)
1250 1342 : * poReader->GetPaperToGround() );
1251 :
1252 : // Geometry
1253 1342 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[3]));
1254 :
1255 : // Attributes
1256 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1257 : "FC", 1, "TX", 6, "DE", 8,
1258 1342 : NULL );
1259 :
1260 1342 : return poFeature;
1261 : }
1262 :
1263 : /************************************************************************/
1264 : /* TranslateStrategiPoint() */
1265 : /************************************************************************/
1266 :
1267 9194 : static OGRFeature *TranslateStrategiPoint( NTFFileReader *poReader,
1268 : OGRNTFLayer *poLayer,
1269 : NTFRecord **papoGroup )
1270 :
1271 : {
1272 27582 : if( CSLCount((char **) papoGroup) < 2
1273 9194 : || papoGroup[0]->GetType() != NRT_POINTREC
1274 9194 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1275 0 : return NULL;
1276 :
1277 9194 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1278 :
1279 : // POINT_ID
1280 9194 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1281 :
1282 : // Geometry
1283 : int nGeomId;
1284 :
1285 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1286 9194 : &nGeomId));
1287 :
1288 : // GEOM_ID
1289 9194 : poFeature->SetField( 10, nGeomId );
1290 :
1291 : // Attributes
1292 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1293 : "FC", 1, "PN", 2, "NU", 3, "RB", 4,
1294 : "RU", 5, "AN", 6, "AO", 7, "CM", 8,
1295 : "UN", 9, "DE", 11, "DN", 12, "FM", 13,
1296 : "GS", 14, "HI", 15, "HM", 16, "LO", 17,
1297 : "OR", 18, "OW", 19, "RJ", 20, "RL", 21,
1298 : "RM", 22, "RQ", 23, "RW", 24, "RZ", 25,
1299 : "UE", 26,
1300 9194 : NULL );
1301 :
1302 9194 : return poFeature;
1303 : }
1304 :
1305 : /************************************************************************/
1306 : /* TranslateStrategiLine() */
1307 : /************************************************************************/
1308 :
1309 8369 : static OGRFeature *TranslateStrategiLine( NTFFileReader *poReader,
1310 : OGRNTFLayer *poLayer,
1311 : NTFRecord **papoGroup )
1312 :
1313 : {
1314 25107 : if( CSLCount((char **) papoGroup) < 2
1315 8369 : || papoGroup[0]->GetType() != NRT_LINEREC
1316 8369 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1317 0 : return NULL;
1318 :
1319 8369 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1320 :
1321 : // LINE_ID
1322 8369 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1323 :
1324 : // Geometry
1325 : int nGeomId;
1326 :
1327 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1],
1328 8369 : &nGeomId));
1329 :
1330 : // GEOM_ID
1331 8369 : poFeature->SetField( 3, nGeomId );
1332 :
1333 : // Attributes
1334 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1335 : "FC", 1, "PN", 2, "DE", 4, "FE", 5,
1336 : "FF", 6, "FI", 7, "FM", 8, "FP", 9,
1337 : "FR", 10, "FT", 11, "GS", 12, "NU", 13,
1338 : "TX", 14,
1339 8369 : NULL );
1340 :
1341 8369 : return poFeature;
1342 : }
1343 :
1344 : /************************************************************************/
1345 : /* TranslateLandrangerPoint() */
1346 : /************************************************************************/
1347 :
1348 0 : static OGRFeature *TranslateLandrangerPoint( NTFFileReader *poReader,
1349 : OGRNTFLayer *poLayer,
1350 : NTFRecord **papoGroup )
1351 :
1352 : {
1353 0 : if( CSLCount((char **) papoGroup) != 2
1354 0 : || papoGroup[0]->GetType() != NRT_POINTREC
1355 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1356 0 : return NULL;
1357 :
1358 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1359 :
1360 : // POINT_ID
1361 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1362 :
1363 : // FEAT_CODE
1364 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1365 :
1366 : // HEIGHT
1367 0 : poFeature->SetField( 2, atoi(papoGroup[0]->GetField( 11, 16 )) );
1368 :
1369 : // Geometry
1370 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1371 :
1372 0 : return poFeature;
1373 : }
1374 :
1375 : /************************************************************************/
1376 : /* TranslateLandrangerLine() */
1377 : /************************************************************************/
1378 :
1379 0 : static OGRFeature *TranslateLandrangerLine( NTFFileReader *poReader,
1380 : OGRNTFLayer *poLayer,
1381 : NTFRecord **papoGroup )
1382 :
1383 : {
1384 0 : if( CSLCount((char **) papoGroup) != 2
1385 0 : || papoGroup[0]->GetType() != NRT_LINEREC
1386 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1387 0 : return NULL;
1388 :
1389 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1390 :
1391 : // LINE_ID
1392 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1393 :
1394 : // FEAT_CODE
1395 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1396 :
1397 : // HEIGHT
1398 0 : poFeature->SetField( 2, atoi(papoGroup[0]->GetField( 11, 16 )) );
1399 :
1400 : // Geometry
1401 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1402 :
1403 0 : return poFeature;
1404 : }
1405 :
1406 : /************************************************************************/
1407 : /* TranslateProfilePoint() */
1408 : /************************************************************************/
1409 :
1410 0 : static OGRFeature *TranslateProfilePoint( NTFFileReader *poReader,
1411 : OGRNTFLayer *poLayer,
1412 : NTFRecord **papoGroup )
1413 :
1414 : {
1415 0 : if( CSLCount((char **) papoGroup) < 2
1416 0 : || papoGroup[0]->GetType() != NRT_POINTREC
1417 0 : || (papoGroup[1]->GetType() != NRT_GEOMETRY
1418 0 : && papoGroup[1]->GetType() != NRT_GEOMETRY3D) )
1419 0 : return NULL;
1420 :
1421 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1422 :
1423 : // POINT_ID
1424 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1425 :
1426 : // FEAT_CODE
1427 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1428 :
1429 : // Geometry
1430 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1431 :
1432 : // Attributes
1433 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1434 : "HT", 2,
1435 0 : NULL );
1436 :
1437 : // Set HEIGHT/elevation
1438 0 : OGRPoint *poPoint = (OGRPoint *) poFeature->GetGeometryRef();
1439 :
1440 0 : if( poPoint != NULL && poPoint->getCoordinateDimension() == 3 )
1441 : {
1442 0 : poFeature->SetField( 2, poPoint->getZ() );
1443 : }
1444 0 : else if( poPoint != NULL )
1445 : {
1446 0 : poFeature->SetField( 2, poFeature->GetFieldAsDouble(2) * 0.01 );
1447 0 : poPoint->setZ( poFeature->GetFieldAsDouble(2) );
1448 : }
1449 :
1450 0 : return poFeature;
1451 : }
1452 :
1453 : /************************************************************************/
1454 : /* TranslateProfileLine() */
1455 : /************************************************************************/
1456 :
1457 0 : static OGRFeature *TranslateProfileLine( NTFFileReader *poReader,
1458 : OGRNTFLayer *poLayer,
1459 : NTFRecord **papoGroup )
1460 :
1461 : {
1462 0 : if( CSLCount((char **) papoGroup) < 2
1463 0 : || papoGroup[0]->GetType() != NRT_LINEREC
1464 0 : || (papoGroup[1]->GetType() != NRT_GEOMETRY
1465 0 : && papoGroup[1]->GetType() != NRT_GEOMETRY3D) )
1466 0 : return NULL;
1467 :
1468 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1469 :
1470 : // LINE_ID
1471 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1472 :
1473 : // FEAT_CODE
1474 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1475 :
1476 : // Geometry
1477 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1478 :
1479 : // Attributes
1480 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1481 : "HT", 2,
1482 0 : NULL );
1483 :
1484 : // Set HEIGHT/elevation
1485 0 : OGRLineString *poLine = (OGRLineString *) poFeature->GetGeometryRef();
1486 :
1487 0 : poFeature->SetField( 2, poFeature->GetFieldAsDouble(2) * 0.01 );
1488 0 : if( poLine != NULL && poLine->getCoordinateDimension() == 2 )
1489 : {
1490 0 : for( int i = 0; i < poLine->getNumPoints(); i++ )
1491 : {
1492 : poLine->setPoint( i, poLine->getX(i), poLine->getY(i),
1493 0 : poFeature->GetFieldAsDouble(2) );
1494 : }
1495 : }
1496 0 : else if( poLine != NULL )
1497 : {
1498 0 : double dfAccum = 0.0;
1499 :
1500 0 : for( int i = 0; i < poLine->getNumPoints(); i++ )
1501 : {
1502 0 : dfAccum += poLine->getZ(i);
1503 : }
1504 0 : poFeature->SetField( 2, dfAccum / poLine->getNumPoints() );
1505 : }
1506 :
1507 0 : return poFeature;
1508 : }
1509 :
1510 : /************************************************************************/
1511 : /* TranslateLandlinePoint() */
1512 : /************************************************************************/
1513 :
1514 0 : static OGRFeature *TranslateLandlinePoint( NTFFileReader *poReader,
1515 : OGRNTFLayer *poLayer,
1516 : NTFRecord **papoGroup )
1517 :
1518 : {
1519 0 : if( CSLCount((char **) papoGroup) < 2
1520 0 : || papoGroup[0]->GetType() != NRT_POINTREC
1521 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1522 0 : return NULL;
1523 :
1524 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1525 :
1526 : // POINT_ID
1527 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1528 :
1529 : // FEAT_CODE
1530 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1531 :
1532 : // ORIENT
1533 0 : poFeature->SetField( 2, atoi(papoGroup[0]->GetField( 11, 16 )) * 0.1 );
1534 :
1535 : // DISTANCE
1536 : poReader->ApplyAttributeValues( poFeature, papoGroup,
1537 : "DT", 3,
1538 0 : NULL );
1539 :
1540 : // Geometry
1541 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1542 :
1543 : // CHG_DATE (optional)
1544 0 : if( poFeature->GetFieldIndex("CHG_DATE") == 4 )
1545 : {
1546 0 : poFeature->SetField( 4, papoGroup[0]->GetField( 23, 28 ) );
1547 : }
1548 :
1549 : // CHG_TYPE (optional)
1550 0 : if( poFeature->GetFieldIndex("CHG_TYPE") == 5 )
1551 : {
1552 0 : poFeature->SetField( 5, papoGroup[0]->GetField( 22, 22 ) );
1553 : }
1554 :
1555 0 : return poFeature;
1556 : }
1557 :
1558 : /************************************************************************/
1559 : /* TranslateLandlineLine() */
1560 : /************************************************************************/
1561 :
1562 0 : static OGRFeature *TranslateLandlineLine( NTFFileReader *poReader,
1563 : OGRNTFLayer *poLayer,
1564 : NTFRecord **papoGroup )
1565 :
1566 : {
1567 0 : if( CSLCount((char **) papoGroup) != 2
1568 0 : || papoGroup[0]->GetType() != NRT_LINEREC
1569 0 : || papoGroup[1]->GetType() != NRT_GEOMETRY )
1570 0 : return NULL;
1571 :
1572 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1573 :
1574 : // LINE_ID
1575 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1576 :
1577 : // FEAT_CODE
1578 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 17, 20 ) );
1579 :
1580 : // Geometry
1581 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
1582 :
1583 : // CHG_DATE (optional)
1584 0 : if( poFeature->GetFieldIndex("CHG_DATE") == 2 )
1585 : {
1586 0 : poFeature->SetField( 2, papoGroup[0]->GetField( 23, 28 ) );
1587 : }
1588 :
1589 : // CHG_TYPE (optional)
1590 0 : if( poFeature->GetFieldIndex("CHG_TYPE") == 3 )
1591 : {
1592 0 : poFeature->SetField( 3, papoGroup[0]->GetField( 22, 22 ) );
1593 : }
1594 0 : return poFeature;
1595 : }
1596 :
1597 : /************************************************************************/
1598 : /* TranslateLandlineName() */
1599 : /************************************************************************/
1600 :
1601 0 : static OGRFeature *TranslateLandlineName( NTFFileReader *poReader,
1602 : OGRNTFLayer *poLayer,
1603 : NTFRecord **papoGroup )
1604 :
1605 : {
1606 0 : if( CSLCount((char **) papoGroup) != 3
1607 0 : || papoGroup[0]->GetType() != NRT_NAMEREC
1608 0 : || papoGroup[1]->GetType() != NRT_NAMEPOSTN
1609 0 : || papoGroup[2]->GetType() != NRT_GEOMETRY )
1610 0 : return NULL;
1611 :
1612 0 : OGRFeature *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
1613 :
1614 : // NAME_ID
1615 0 : poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
1616 :
1617 : // TEXT_CODE
1618 0 : poFeature->SetField( 1, papoGroup[0]->GetField( 9, 12 ) );
1619 :
1620 : // TEXT
1621 0 : int nNumChar = atoi(papoGroup[0]->GetField(13,14));
1622 0 : poFeature->SetField( 2, papoGroup[0]->GetField( 15, 15+nNumChar-1) );
1623 :
1624 : // FONT
1625 0 : poFeature->SetField( 3, atoi(papoGroup[1]->GetField( 3, 6 )) );
1626 :
1627 : // TEXT_HT
1628 0 : poFeature->SetField( 4, atoi(papoGroup[1]->GetField(7,9)) * 0.1 );
1629 :
1630 : // DIG_POSTN
1631 0 : poFeature->SetField( 5, atoi(papoGroup[1]->GetField(10,10)) );
1632 :
1633 : // ORIENT
1634 0 : poFeature->SetField( 6, atof(papoGroup[1]->GetField( 11, 14 )) * 0.1 );
1635 :
1636 : // TEXT_HT_GROUND
1637 : poFeature->SetField( 7, poFeature->GetFieldAsDouble(4)
1638 0 : * poReader->GetPaperToGround() );
1639 :
1640 : // CHG_DATE (optional)
1641 0 : if( poFeature->GetFieldIndex("CHG_DATE") == 7 )
1642 : {
1643 0 : poFeature->SetField( 8, papoGroup[0]->GetField( 15+nNumChar+2,
1644 0 : 15+nNumChar+2+5) );
1645 : }
1646 :
1647 : // CHG_TYPE (optional)
1648 0 : if( poFeature->GetFieldIndex("CHG_TYPE") == 9 )
1649 : {
1650 0 : poFeature->SetField( 9, papoGroup[0]->GetField( 15+nNumChar+1,
1651 0 : 15+nNumChar+1 ) );
1652 : }
1653 :
1654 : // Geometry
1655 0 : poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[2]));
1656 :
1657 0 : return poFeature;
1658 : }
1659 :
1660 : /************************************************************************/
1661 : /* EstablishLayer() */
1662 : /* */
1663 : /* Establish one layer based on a simplified description of the */
1664 : /* fields to be present. */
1665 : /************************************************************************/
1666 :
1667 8 : void NTFFileReader::EstablishLayer( const char * pszLayerName,
1668 : OGRwkbGeometryType eGeomType,
1669 : NTFFeatureTranslator pfnTranslator,
1670 : int nLeadRecordType,
1671 : NTFGenericClass *poClass,
1672 : ... )
1673 :
1674 : {
1675 : va_list hVaArgs;
1676 : OGRFeatureDefn *poDefn;
1677 : OGRNTFLayer *poLayer;
1678 :
1679 : /* -------------------------------------------------------------------- */
1680 : /* Does this layer already exist? If so, we do nothing */
1681 : /* ... note that we don't check the definition. */
1682 : /* -------------------------------------------------------------------- */
1683 8 : poLayer = poDS->GetNamedLayer(pszLayerName);
1684 :
1685 : /* ==================================================================== */
1686 : /* Create a new layer matching the request if we don't aleady */
1687 : /* have one. */
1688 : /* ==================================================================== */
1689 8 : if( poLayer == NULL )
1690 : {
1691 : /* -------------------------------------------------------------------- */
1692 : /* Create a new feature definition. */
1693 : /* -------------------------------------------------------------------- */
1694 8 : poDefn = new OGRFeatureDefn( pszLayerName );
1695 8 : poDefn->SetGeomType( eGeomType );
1696 8 : poDefn->Reference();
1697 :
1698 : /* -------------------------------------------------------------------- */
1699 : /* Fetch definitions of each field in turn. */
1700 : /* -------------------------------------------------------------------- */
1701 8 : va_start(hVaArgs, poClass);
1702 102 : while( TRUE )
1703 : {
1704 110 : const char *pszFieldName = va_arg(hVaArgs, const char *);
1705 : OGRFieldType eType;
1706 : int nWidth, nPrecision;
1707 :
1708 110 : if( pszFieldName == NULL )
1709 : break;
1710 :
1711 102 : eType = (OGRFieldType) va_arg(hVaArgs, int);
1712 102 : nWidth = va_arg(hVaArgs, int);
1713 102 : nPrecision = va_arg(hVaArgs, int);
1714 :
1715 102 : OGRFieldDefn oFieldDefn( pszFieldName, eType );
1716 102 : oFieldDefn.SetWidth( nWidth );
1717 102 : oFieldDefn.SetPrecision( nPrecision );
1718 :
1719 102 : poDefn->AddFieldDefn( &oFieldDefn );
1720 : }
1721 :
1722 8 : va_end(hVaArgs);
1723 :
1724 : /* -------------------------------------------------------------------- */
1725 : /* Add attributes collected in the generic class survey. */
1726 : /* -------------------------------------------------------------------- */
1727 8 : if( poClass != NULL )
1728 : {
1729 0 : for( int iGAtt = 0; iGAtt < poClass->nAttrCount; iGAtt++ )
1730 : {
1731 0 : const char *pszFormat = poClass->papszAttrFormats[iGAtt];
1732 0 : OGRFieldDefn oFieldDefn( poClass->papszAttrNames[iGAtt],
1733 0 : OFTInteger );
1734 :
1735 0 : if( EQUALN(pszFormat,"I",1) )
1736 : {
1737 0 : oFieldDefn.SetType( OFTInteger );
1738 0 : oFieldDefn.SetWidth( poClass->panAttrMaxWidth[iGAtt] );
1739 : }
1740 0 : else if( EQUALN(pszFormat,"D",1)
1741 : || EQUALN(pszFormat,"A",1) )
1742 : {
1743 0 : oFieldDefn.SetType( OFTString );
1744 0 : oFieldDefn.SetWidth( poClass->panAttrMaxWidth[iGAtt] );
1745 : }
1746 0 : else if( EQUALN(pszFormat,"R",1) )
1747 : {
1748 0 : oFieldDefn.SetType( OFTReal );
1749 0 : oFieldDefn.SetWidth( poClass->panAttrMaxWidth[iGAtt]+1 );
1750 0 : if( pszFormat[2] == ',' )
1751 0 : oFieldDefn.SetPrecision(atoi(pszFormat+3));
1752 0 : else if( pszFormat[3] == ',' )
1753 0 : oFieldDefn.SetPrecision(atoi(pszFormat+4));
1754 : }
1755 :
1756 0 : poDefn->AddFieldDefn( &oFieldDefn );
1757 :
1758 : /*
1759 : ** If this field can appear multiple times, create an
1760 : ** additional attribute to hold lists of values. This
1761 : ** is always created as a variable length string field.
1762 : */
1763 0 : if( poClass->pabAttrMultiple[iGAtt] )
1764 : {
1765 : char szName[128];
1766 :
1767 : sprintf( szName, "%s_LIST",
1768 0 : poClass->papszAttrNames[iGAtt] );
1769 :
1770 0 : OGRFieldDefn oFieldDefnL( szName, OFTString );
1771 :
1772 0 : poDefn->AddFieldDefn( &oFieldDefnL );
1773 : }
1774 : }
1775 : }
1776 :
1777 : /* -------------------------------------------------------------------- */
1778 : /* Add the TILE_REF attribute. */
1779 : /* -------------------------------------------------------------------- */
1780 8 : OGRFieldDefn oTileID( "TILE_REF", OFTString );
1781 :
1782 8 : oTileID.SetWidth( 10 );
1783 :
1784 8 : poDefn->AddFieldDefn( &oTileID );
1785 :
1786 : /* -------------------------------------------------------------------- */
1787 : /* Create the layer, and give over to the data source object to */
1788 : /* maintain. */
1789 : /* -------------------------------------------------------------------- */
1790 8 : poLayer = new OGRNTFLayer( poDS, poDefn, pfnTranslator );
1791 :
1792 16 : poDS->AddLayer( poLayer );
1793 : }
1794 :
1795 : /* -------------------------------------------------------------------- */
1796 : /* Register this translator with this file reader for handling */
1797 : /* the indicate record type. */
1798 : /* -------------------------------------------------------------------- */
1799 8 : apoTypeTranslation[nLeadRecordType] = poLayer;
1800 8 : }
1801 :
1802 : /************************************************************************/
1803 : /* EstablishLayers() */
1804 : /* */
1805 : /* This method is responsible for creating any missing */
1806 : /* OGRNTFLayers needed for the current product based on the */
1807 : /* product name. */
1808 : /* */
1809 : /* NOTE: Any changes to the order of attribute fields in the */
1810 : /* following EstablishLayer() calls must also result in updates */
1811 : /* to the translate functions. Changes of names, widths and to */
1812 : /* some extent types can be done without side effects. */
1813 : /************************************************************************/
1814 :
1815 2 : void NTFFileReader::EstablishLayers()
1816 :
1817 : {
1818 2 : if( poDS == NULL || fp == NULL )
1819 0 : return;
1820 :
1821 2 : if( GetProductId() == NPC_LANDLINE )
1822 : {
1823 : EstablishLayer( "LANDLINE_POINT", wkbPoint,
1824 : TranslateLandlinePoint, NRT_POINTREC, NULL,
1825 : "POINT_ID", OFTInteger, 6, 0,
1826 : "FEAT_CODE", OFTString, 4, 0,
1827 : "ORIENT", OFTReal, 5, 1,
1828 : "DISTANCE", OFTReal, 6, 3,
1829 0 : NULL );
1830 :
1831 : EstablishLayer( "LANDLINE_LINE", wkbLineString,
1832 : TranslateLandlineLine, NRT_LINEREC, NULL,
1833 : "LINE_ID", OFTInteger, 6, 0,
1834 : "FEAT_CODE", OFTString, 4, 0,
1835 0 : NULL );
1836 :
1837 : EstablishLayer( "LANDLINE_NAME", wkbPoint,
1838 : TranslateLandlineName, NRT_NAMEREC, NULL,
1839 : "NAME_ID", OFTInteger, 6, 0,
1840 : "TEXT_CODE", OFTString, 4, 0,
1841 : "TEXT", OFTString, 0, 0,
1842 : "FONT", OFTInteger, 4, 0,
1843 : "TEXT_HT", OFTReal, 4, 1,
1844 : "DIG_POSTN", OFTInteger, 1, 0,
1845 : "ORIENT", OFTReal, 5, 1,
1846 : "TEXT_HT_GROUND", OFTReal, 10, 3,
1847 0 : NULL );
1848 : }
1849 2 : else if( GetProductId() == NPC_LANDLINE99 )
1850 : {
1851 : EstablishLayer( "LANDLINE99_POINT", wkbPoint,
1852 : TranslateLandlinePoint, NRT_POINTREC, NULL,
1853 : "POINT_ID", OFTInteger, 6, 0,
1854 : "FEAT_CODE", OFTString, 4, 0,
1855 : "ORIENT", OFTReal, 5, 1,
1856 : "DISTANCE", OFTReal, 6, 3,
1857 : "CHG_DATE", OFTString, 6, 0,
1858 : "CHG_TYPE", OFTString, 1, 0,
1859 0 : NULL );
1860 :
1861 : EstablishLayer( "LANDLINE99_LINE", wkbLineString,
1862 : TranslateLandlineLine, NRT_LINEREC, NULL,
1863 : "LINE_ID", OFTInteger, 6, 0,
1864 : "FEAT_CODE", OFTString, 4, 0,
1865 : "CHG_DATE", OFTString, 6, 0,
1866 : "CHG_TYPE", OFTString, 1, 0,
1867 0 : NULL );
1868 :
1869 : EstablishLayer( "LANDLINE99_NAME", wkbPoint,
1870 : TranslateLandlineName, NRT_NAMEREC, NULL,
1871 : "NAME_ID", OFTInteger, 6, 0,
1872 : "TEXT_CODE", OFTString, 4, 0,
1873 : "TEXT", OFTString, 0, 0,
1874 : "FONT", OFTInteger, 4, 0,
1875 : "TEXT_HT", OFTReal, 4, 1,
1876 : "DIG_POSTN", OFTInteger, 1, 0,
1877 : "ORIENT", OFTReal, 5, 1,
1878 : "TEXT_HT_GROUND", OFTReal, 10, 3,
1879 : "CHG_DATE", OFTString, 6, 0,
1880 : "CHG_TYPE", OFTString, 1, 0,
1881 0 : NULL );
1882 : }
1883 2 : else if( GetProductId() == NPC_LANDRANGER_CONT )
1884 : {
1885 : EstablishLayer( "PANORAMA_POINT", wkbPoint,
1886 : TranslateLandrangerPoint, NRT_POINTREC, NULL,
1887 : "POINT_ID", OFTInteger, 6, 0,
1888 : "FEAT_CODE", OFTString, 4, 0,
1889 : "HEIGHT", OFTReal, 7, 2,
1890 0 : NULL );
1891 :
1892 : EstablishLayer( "PANORAMA_CONTOUR", wkbLineString,
1893 : TranslateLandrangerLine, NRT_LINEREC, NULL,
1894 : "LINE_ID", OFTInteger, 6, 0,
1895 : "FEAT_CODE", OFTString, 4, 0,
1896 : "HEIGHT", OFTReal, 7, 2,
1897 0 : NULL );
1898 : }
1899 2 : else if( GetProductId() == NPC_LANDFORM_PROFILE_CONT )
1900 : {
1901 : EstablishLayer( "PROFILE_POINT", wkbPoint25D,
1902 : TranslateProfilePoint, NRT_POINTREC, NULL,
1903 : "POINT_ID", OFTInteger, 6, 0,
1904 : "FEAT_CODE", OFTString, 4, 0,
1905 : "HEIGHT", OFTReal, 7, 2,
1906 0 : NULL );
1907 :
1908 : EstablishLayer( "PROFILE_LINE", wkbLineString25D,
1909 : TranslateProfileLine, NRT_LINEREC, NULL,
1910 : "LINE_ID", OFTInteger, 6, 0,
1911 : "FEAT_CODE", OFTString, 4, 0,
1912 : "HEIGHT", OFTReal, 7, 2,
1913 0 : NULL );
1914 : }
1915 2 : else if( GetProductId() == NPC_STRATEGI )
1916 : {
1917 : EstablishLayer( "STRATEGI_POINT", wkbPoint,
1918 : TranslateStrategiPoint, NRT_POINTREC, NULL,
1919 : "POINT_ID", OFTInteger, 6, 0,
1920 : "FEAT_CODE", OFTString, 4, 0,
1921 : "PROPER_NAME", OFTString, 0, 0,
1922 : "FEATURE_NUMBER", OFTString, 0, 0,
1923 : "RB", OFTString, 1, 0,
1924 : "RU", OFTString, 1, 0,
1925 : "AN", OFTString, 0, 0,
1926 : "AO", OFTString, 0, 0,
1927 : "COUNTY_NAME", OFTString, 0, 0,
1928 : "UNITARY_NAME", OFTString, 0, 0,
1929 : "GEOM_ID", OFTInteger, 6, 0,
1930 : "DATE", OFTInteger, 8, 0,
1931 : "DISTRICT_NAME", OFTString, 0, 0,
1932 : "FEATURE_NAME", OFTString, 0, 0,
1933 : "GIS", OFTString, 0, 0,
1934 : "HEIGHT_IMPERIAL", OFTInteger, 4, 0,
1935 : "HEIGHT_METRIC", OFTInteger, 4, 0,
1936 : "LOCATION", OFTInteger, 1, 0,
1937 : "ORIENTATION", OFTReal, 4, 1,
1938 : "OWNER", OFTString, 0, 0,
1939 : "RESTRICTION_NORTH", OFTString, 0, 0,
1940 : "RESTRICTION_SOUTH", OFTString, 0, 0,
1941 : "RESTRICTION_EAST", OFTString, 0, 0,
1942 : "RESTRICTION_WEST", OFTString, 0, 0,
1943 : "RESTRICTION_CLOCKWISE", OFTString, 0, 0,
1944 : "RESTRICTION_ANTICLOCKWISE", OFTString, 0, 0,
1945 : "USAGE", OFTInteger, 1, 0,
1946 1 : NULL );
1947 :
1948 : EstablishLayer( "STRATEGI_LINE", wkbLineString,
1949 : TranslateStrategiLine, NRT_LINEREC, NULL,
1950 : "LINE_ID", OFTInteger, 6, 0,
1951 : "FEAT_CODE", OFTString, 4, 0,
1952 : "PROPER_NAME", OFTString, 0, 0,
1953 : "GEOM_ID", OFTInteger, 6, 0,
1954 : "DATE", OFTInteger, 8, 0,
1955 : "FERRY_ACCESS", OFTString, 0, 0,
1956 : "FERRY_FROM", OFTString, 0, 0,
1957 : "FERRY_TIME", OFTString, 0, 0,
1958 : "FEATURE_NAME", OFTString, 0, 0,
1959 : "FERRY_TYPE", OFTString, 0, 0,
1960 : "FERRY_RESTRICTIONS", OFTString, 0, 0,
1961 : "FERRY_TO", OFTString, 0, 0,
1962 : "GIS", OFTString, 0, 0,
1963 : "FEATURE_NUMBER", OFTString, 0, 0,
1964 1 : NULL );
1965 :
1966 : EstablishLayer( "STRATEGI_TEXT", wkbPoint,
1967 : TranslateStrategiText, NRT_TEXTREC, NULL,
1968 : "TEXT_ID", OFTInteger, 6, 0,
1969 : "FEAT_CODE", OFTString, 4, 0,
1970 : "FONT", OFTInteger, 4, 0,
1971 : "TEXT_HT", OFTReal, 5, 1,
1972 : "DIG_POSTN", OFTInteger, 1, 0,
1973 : "ORIENT", OFTReal, 5, 1,
1974 : "TEXT", OFTString, 0, 0,
1975 : "TEXT_HT_GROUND", OFTReal, 10, 3,
1976 : "DATE", OFTInteger, 8, 0,
1977 1 : NULL );
1978 :
1979 : EstablishLayer( "STRATEGI_NODE", wkbNone,
1980 : TranslateStrategiNode, NRT_NODEREC, NULL,
1981 : "NODE_ID", OFTInteger, 6, 0,
1982 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
1983 : "NUM_LINKS", OFTInteger, 4, 0,
1984 : "DIR", OFTIntegerList, 1, 0,
1985 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
1986 : "LEVEL", OFTIntegerList, 1, 0,
1987 : "ORIENT", OFTRealList, 5, 1,
1988 1 : NULL );
1989 : }
1990 1 : else if( GetProductId() == NPC_MERIDIAN )
1991 : {
1992 : EstablishLayer( "MERIDIAN_POINT", wkbPoint,
1993 : TranslateMeridianPoint, NRT_POINTREC, NULL,
1994 : "POINT_ID", OFTInteger, 6, 0,
1995 : "GEOM_ID", OFTInteger, 6, 0,
1996 : "FEAT_CODE", OFTString, 4, 0,
1997 : "PROPER_NAME", OFTString, 0, 0,
1998 : "OSMDR", OFTString, 13, 0,
1999 : "JUNCTION_NAME", OFTString, 0, 0,
2000 : "ROUNDABOUT", OFTString, 1, 0,
2001 : "STATION_ID", OFTString, 13, 0,
2002 : "GLOBAL_ID", OFTInteger, 6, 0,
2003 : "ADMIN_NAME", OFTString, 0, 0,
2004 : "DA_DLUA_ID", OFTString, 13, 0,
2005 0 : NULL );
2006 :
2007 : EstablishLayer( "MERIDIAN_LINE", wkbLineString,
2008 : TranslateMeridianLine, NRT_LINEREC, NULL,
2009 : "LINE_ID", OFTInteger, 6, 0,
2010 : "FEAT_CODE", OFTString, 4, 0,
2011 : "GEOM_ID", OFTInteger, 6, 0,
2012 : "OSMDR", OFTString, 13, 0,
2013 : "ROAD_NUM", OFTString, 0, 0,
2014 : "TRUNK_ROAD", OFTString, 1, 0,
2015 : "RAIL_ID", OFTString, 13, 0,
2016 : "LEFT_COUNTY", OFTInteger, 6, 0,
2017 : "RIGHT_COUNTY", OFTInteger, 6, 0,
2018 : "LEFT_DISTRICT", OFTInteger, 6, 0,
2019 : "RIGHT_DISTRICT", OFTInteger, 6, 0,
2020 0 : NULL );
2021 :
2022 : EstablishLayer( "MERIDIAN_TEXT", wkbPoint,
2023 : TranslateStrategiText, NRT_TEXTREC, NULL,
2024 : "TEXT_ID", OFTInteger, 6, 0,
2025 : "FEAT_CODE", OFTString, 4, 0,
2026 : "FONT", OFTInteger, 4, 0,
2027 : "TEXT_HT", OFTReal, 5, 1,
2028 : "DIG_POSTN", OFTInteger, 1, 0,
2029 : "ORIENT", OFTReal, 5, 1,
2030 : "TEXT", OFTString, 0, 0,
2031 : "TEXT_HT_GROUND", OFTReal, 10, 3,
2032 0 : NULL );
2033 :
2034 : EstablishLayer( "MERIDIAN_NODE", wkbNone,
2035 : TranslateStrategiNode, NRT_NODEREC, NULL,
2036 : "NODE_ID", OFTInteger, 6, 0,
2037 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2038 : "NUM_LINKS", OFTInteger, 4, 0,
2039 : "DIR", OFTIntegerList, 1, 0,
2040 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2041 : "LEVEL", OFTIntegerList, 1, 0,
2042 : "ORIENT", OFTRealList, 5, 1,
2043 0 : NULL );
2044 : }
2045 1 : else if( GetProductId() == NPC_MERIDIAN2 )
2046 : {
2047 : EstablishLayer( "MERIDIAN2_POINT", wkbPoint,
2048 : TranslateMeridian2Point, NRT_POINTREC, NULL,
2049 : "POINT_ID", OFTInteger, 6, 0,
2050 : "GEOM_ID", OFTInteger, 6, 0,
2051 : "FEAT_CODE", OFTString, 4, 0,
2052 : "PROPER_NAME", OFTString, 0, 0,
2053 : "OSODR", OFTString, 13, 0,
2054 : "PARENT_OSODR", OFTString, 13, 0,
2055 : "JUNCTION_NAME", OFTString, 0, 0,
2056 : "ROUNDABOUT", OFTString, 1, 0,
2057 : "SETTLEMENT_NAME", OFTString, 0, 0,
2058 : "STATION_ID", OFTString, 13, 0,
2059 : "GLOBAL_ID", OFTInteger, 6, 0,
2060 : "ADMIN_NAME", OFTString, 0, 0,
2061 : "DA_DLUA_ID", OFTString, 13, 0,
2062 : "WATER_AREA", OFTString, 13, 0,
2063 : "HEIGHT", OFTInteger, 8, 0,
2064 : "FOREST_ID", OFTString, 13, 0,
2065 1 : NULL );
2066 :
2067 : EstablishLayer( "MERIDIAN2_LINE", wkbLineString,
2068 : TranslateMeridian2Line, NRT_LINEREC, NULL,
2069 : "LINE_ID", OFTInteger, 6, 0,
2070 : "FEAT_CODE", OFTString, 4, 0,
2071 : "GEOM_ID", OFTInteger, 6, 0,
2072 : "OSODR", OFTString, 13, 0,
2073 : "PARENT_OSODR", OFTString, 13, 0,
2074 : "ROAD_NUM", OFTString, 0, 0,
2075 : "TRUNK_ROAD", OFTString, 1, 0,
2076 : "PROPER_NAME", OFTString, 0, 0,
2077 : "RAIL_ID", OFTString, 13, 0,
2078 : "LEFT_COUNTY", OFTInteger, 6, 0,
2079 : "RIGHT_COUNTY", OFTInteger, 6, 0,
2080 : "LEFT_DISTRICT", OFTInteger, 6, 0,
2081 : "RIGHT_DISTRICT", OFTInteger, 6, 0,
2082 : "WATER_LINK_ID", OFTString, 13, 0,
2083 1 : NULL );
2084 :
2085 : EstablishLayer( "MERIDIAN2_TEXT", wkbPoint,
2086 : TranslateStrategiText, NRT_TEXTREC, NULL,
2087 : "TEXT_ID", OFTInteger, 6, 0,
2088 : "FEAT_CODE", OFTString, 4, 0,
2089 : "FONT", OFTInteger, 4, 0,
2090 : "TEXT_HT", OFTReal, 5, 1,
2091 : "DIG_POSTN", OFTInteger, 1, 0,
2092 : "ORIENT", OFTReal, 5, 1,
2093 : "TEXT", OFTString, 0, 0,
2094 : "TEXT_HT_GROUND", OFTReal, 10, 3,
2095 1 : NULL );
2096 :
2097 : EstablishLayer( "MERIDIAN2_NODE", wkbNone,
2098 : TranslateStrategiNode, NRT_NODEREC, NULL,
2099 : "NODE_ID", OFTInteger, 6, 0,
2100 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2101 : "NUM_LINKS", OFTInteger, 4, 0,
2102 : "DIR", OFTIntegerList, 1, 0,
2103 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2104 : "LEVEL", OFTIntegerList, 1, 0,
2105 : "ORIENT", OFTRealList, 5, 1,
2106 1 : NULL );
2107 : }
2108 0 : else if( GetProductId() == NPC_BOUNDARYLINE )
2109 : {
2110 : EstablishLayer( "BOUNDARYLINE_LINK", wkbLineString,
2111 : TranslateBoundarylineLink, NRT_GEOMETRY, NULL,
2112 : "GEOM_ID", OFTInteger, 6, 0,
2113 : "FEAT_CODE", OFTString, 4, 0,
2114 : "GLOBAL_LINK_ID", OFTInteger, 10, 0,
2115 : "HWM_FLAG", OFTInteger, 1, 0,
2116 0 : NULL );
2117 :
2118 : EstablishLayer( "BOUNDARYLINE_POLY",
2119 : bCacheLines ? wkbPolygon : wkbPoint,
2120 : TranslateBoundarylinePoly, NRT_POLYGON, NULL,
2121 : "POLY_ID", OFTInteger, 6, 0,
2122 : "FEAT_CODE", OFTString, 4, 0,
2123 : "GLOBAL_SEED_ID", OFTInteger, 6, 0,
2124 : "HECTARES", OFTReal, 9, 3,
2125 : "NUM_PARTS", OFTInteger, 4, 0,
2126 : "DIR", OFTIntegerList, 1, 0,
2127 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2128 : "RingStart", OFTIntegerList, 6, 0,
2129 0 : NULL );
2130 :
2131 : EstablishLayer( "BOUNDARYLINE_COLLECTIONS", wkbNone,
2132 : TranslateBoundarylineCollection, NRT_COLLECT, NULL,
2133 : "COLL_ID", OFTInteger, 6, 0,
2134 : "NUM_PARTS", OFTInteger, 4, 0,
2135 : "POLY_ID", OFTIntegerList, 6, 0,
2136 : "ADMIN_AREA_ID", OFTInteger, 6, 0,
2137 : "OPCS_CODE", OFTString, 6, 0,
2138 : "ADMIN_NAME", OFTString, 0, 0,
2139 0 : NULL );
2140 : }
2141 0 : else if( GetProductId() == NPC_BL2000 )
2142 : {
2143 : EstablishLayer( "BL2000_LINK", wkbLineString,
2144 : TranslateBL2000Link, NRT_LINEREC, NULL,
2145 : "LINE_ID", OFTInteger, 6, 0,
2146 : "GEOM_ID", OFTInteger, 6, 0,
2147 : "FEAT_CODE", OFTString, 4, 0,
2148 : "GLOBAL_LINK_ID", OFTInteger, 10, 0,
2149 0 : NULL );
2150 : EstablishLayer( "BL2000_POLY",
2151 : bCacheLines ? wkbPolygon : wkbNone,
2152 : TranslateBL2000Poly, NRT_POLYGON, NULL,
2153 : "POLY_ID", OFTInteger, 6, 0,
2154 : "GLOBAL_SEED_ID", OFTInteger, 6, 0,
2155 : "HECTARES", OFTReal, 12, 3,
2156 : "NUM_PARTS", OFTInteger, 4, 0,
2157 : "DIR", OFTIntegerList, 1, 0,
2158 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2159 : "RingStart", OFTIntegerList, 6, 0,
2160 0 : NULL );
2161 0 : if( poDS->GetOption("CODELIST") != NULL
2162 : && EQUAL(poDS->GetOption("CODELIST"),"ON") )
2163 : EstablishLayer( "BL2000_COLLECTIONS", wkbNone,
2164 : TranslateBL2000Collection, NRT_COLLECT, NULL,
2165 : "COLL_ID", OFTInteger, 6, 0,
2166 : "NUM_PARTS", OFTInteger, 4, 0,
2167 : "POLY_ID", OFTIntegerList, 6, 0,
2168 : "ADMIN_AREA_ID", OFTInteger, 6, 0,
2169 : "CENSUS_CODE", OFTString, 7, 0,
2170 : "ADMIN_NAME", OFTString, 0, 0,
2171 : "AREA_TYPE", OFTString, 2, 0,
2172 : "AREA_CODE", OFTString, 3, 0,
2173 : "NON_TYPE_CODE", OFTString, 3, 0,
2174 : "NON_INLAND_AREA", OFTReal, 12, 3,
2175 : "COLL_ID_REFS", OFTIntegerList, 6, 0,
2176 : "AREA_TYPE_DESC", OFTString, 0, 0,
2177 : "AREA_CODE_DESC", OFTString, 0, 0,
2178 : "NON_TYPE_CODE_DESC", OFTString, 0, 0,
2179 0 : NULL );
2180 : else
2181 : EstablishLayer( "BL2000_COLLECTIONS", wkbNone,
2182 : TranslateBL2000Collection, NRT_COLLECT, NULL,
2183 : "COLL_ID", OFTInteger, 6, 0,
2184 : "NUM_PARTS", OFTInteger, 4, 0,
2185 : "POLY_ID", OFTIntegerList, 6, 0,
2186 : "ADMIN_AREA_ID", OFTInteger, 6, 0,
2187 : "CENSUS_CODE", OFTString, 7, 0,
2188 : "ADMIN_NAME", OFTString, 0, 0,
2189 : "AREA_TYPE", OFTString, 2, 0,
2190 : "AREA_CODE", OFTString, 3, 0,
2191 : "NON_TYPE_CODE", OFTString, 3, 0,
2192 : "NON_INLAND_AREA", OFTReal, 12, 3,
2193 : "COLL_ID_REFS", OFTIntegerList, 6, 0,
2194 0 : NULL );
2195 : }
2196 0 : else if( GetProductId() == NPC_BASEDATA )
2197 : {
2198 : EstablishLayer( "BASEDATA_POINT", wkbPoint,
2199 : TranslateBasedataPoint, NRT_POINTREC, NULL,
2200 : "POINT_ID", OFTInteger, 6, 0,
2201 : "GEOM_ID", OFTInteger, 6, 0,
2202 : "FEAT_CODE", OFTString, 4, 0,
2203 : "PROPER_NAME", OFTString, 0, 0,
2204 : "FEATURE_NUMBER", OFTString, 0, 0,
2205 : "COUNTY_NAME", OFTString, 0, 0,
2206 : "UNITARY_NAME", OFTString, 0, 0,
2207 : "ORIENT", OFTRealList, 5, 1,
2208 0 : NULL );
2209 :
2210 : EstablishLayer( "BASEDATA_LINE", wkbLineString,
2211 : TranslateBasedataLine, NRT_LINEREC, NULL,
2212 : "LINE_ID", OFTInteger, 6, 0,
2213 : "FEAT_CODE", OFTString, 4, 0,
2214 : "GEOM_ID", OFTInteger, 6, 0,
2215 : "PROPER_NAME", OFTString, 0, 0,
2216 : "FEATURE_NUMBER", OFTString, 0, 0,
2217 : "RB", OFTString, 1, 0,
2218 0 : NULL );
2219 :
2220 : EstablishLayer( "BASEDATA_TEXT", wkbPoint,
2221 : TranslateStrategiText, NRT_TEXTREC, NULL,
2222 : "TEXT_ID", OFTInteger, 6, 0,
2223 : "FEAT_CODE", OFTString, 4, 0,
2224 : "FONT", OFTInteger, 4, 0,
2225 : "TEXT_HT", OFTReal, 5, 1,
2226 : "DIG_POSTN", OFTInteger, 1, 0,
2227 : "ORIENT", OFTReal, 5, 1,
2228 : "TEXT", OFTString, 0, 0,
2229 : "TEXT_HT_GROUND", OFTReal, 10, 3,
2230 0 : NULL );
2231 :
2232 : EstablishLayer( "BASEDATA_NODE", wkbNone,
2233 : TranslateStrategiNode, NRT_NODEREC, NULL,
2234 : "NODE_ID", OFTInteger, 6, 0,
2235 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2236 : "NUM_LINKS", OFTInteger, 4, 0,
2237 : "DIR", OFTIntegerList, 1, 0,
2238 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2239 : "LEVEL", OFTIntegerList, 1, 0,
2240 : "ORIENT", OFTRealList, 5, 1,
2241 0 : NULL );
2242 : }
2243 0 : else if( GetProductId() == NPC_OSCAR_ASSET
2244 : || GetProductId() == NPC_OSCAR_TRAFFIC )
2245 : {
2246 : EstablishLayer( "OSCAR_POINT", wkbPoint,
2247 : TranslateOscarPoint, NRT_POINTREC, NULL,
2248 : "POINT_ID", OFTInteger, 6, 0,
2249 : "GEOM_ID", OFTInteger, 6, 0,
2250 : "FEAT_CODE", OFTString, 4, 0,
2251 : "OSODR", OFTString, 13, 0,
2252 : "JUNCTION_NAME", OFTString, 0, 0,
2253 : "SETTLE_NAME", OFTString, 0, 0,
2254 0 : NULL );
2255 :
2256 : EstablishLayer( "OSCAR_LINE", wkbLineString,
2257 : TranslateOscarLine, NRT_LINEREC, NULL,
2258 : "LINE_ID", OFTInteger, 6, 0,
2259 : "GEOM_ID", OFTInteger, 6, 0,
2260 : "FEAT_CODE", OFTString, 4, 0,
2261 : "OSODR", OFTString, 13, 0,
2262 : "PROPER_NAME", OFTString, 0, 0,
2263 : "LINE_LENGTH", OFTInteger, 5, 0,
2264 : "SOURCE", OFTString, 1, 0,
2265 : "FORM_OF_WAY", OFTString, 1, 0,
2266 : "ROAD_NUM", OFTString, 0, 0,
2267 : "TRUNK_ROAD", OFTString, 1, 0,
2268 0 : NULL );
2269 :
2270 : EstablishLayer( "OSCAR_NODE", wkbNone,
2271 : TranslateStrategiNode, NRT_NODEREC, NULL,
2272 : "NODE_ID", OFTInteger, 6, 0,
2273 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2274 : "NUM_LINKS", OFTInteger, 4, 0,
2275 : "DIR", OFTIntegerList, 1, 0,
2276 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2277 : "LEVEL", OFTIntegerList, 1, 0,
2278 0 : NULL );
2279 :
2280 : EstablishLayer( "OSCAR_COMMENT", wkbNone,
2281 : TranslateOscarComment, NRT_COMMENT, NULL,
2282 : "RECORD_TYPE", OFTInteger, 2, 0,
2283 : "RECORD_ID", OFTString, 13, 0,
2284 : "CHANGE_TYPE", OFTString, 1, 0,
2285 0 : NULL );
2286 : }
2287 0 : else if( GetProductId() == NPC_OSCAR_ROUTE )
2288 : {
2289 : EstablishLayer( "OSCAR_ROUTE_POINT", wkbPoint,
2290 : TranslateOscarRoutePoint, NRT_POINTREC, NULL,
2291 : "POINT_ID", OFTInteger, 6, 0,
2292 : "GEOM_ID", OFTInteger, 6, 0,
2293 : "FEAT_CODE", OFTString, 4, 0,
2294 : "OSODR", OFTString, 13, 0,
2295 : "JUNCTION_NAME", OFTString, 0, 0,
2296 : "SETTLE_NAME", OFTString, 0, 0,
2297 : "NUM_PARENTS", OFTInteger, 2, 0,
2298 : "PARENT_OSODR", OFTStringList, 13, 0,
2299 : "ROUNDABOUT", OFTString, 1, 0,
2300 0 : NULL );
2301 :
2302 : EstablishLayer( "OSCAR_ROUTE_LINE", wkbLineString,
2303 : TranslateOscarRouteLine, NRT_LINEREC, NULL,
2304 : "LINE_ID", OFTInteger, 6, 0,
2305 : "GEOM_ID", OFTInteger, 6, 0,
2306 : "FEAT_CODE", OFTString, 4, 0,
2307 : "OSODR", OFTString, 13, 0,
2308 : "PROPER_NAME", OFTString, 0, 0,
2309 : "LINE_LENGTH", OFTInteger, 5, 0,
2310 : "ROAD_NUM", OFTString, 0, 0,
2311 : "TRUNK_ROAD", OFTString, 1, 0,
2312 : "NUM_PARENTS", OFTInteger, 2, 0,
2313 : "PARENT_OSODR", OFTStringList, 13, 0,
2314 0 : NULL );
2315 :
2316 : EstablishLayer( "OSCAR_ROUTE_NODE", wkbNone,
2317 : TranslateStrategiNode, NRT_NODEREC, NULL,
2318 : "NODE_ID", OFTInteger, 6, 0,
2319 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2320 : "NUM_LINKS", OFTInteger, 4, 0,
2321 : "DIR", OFTIntegerList, 1, 0,
2322 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2323 : "LEVEL", OFTIntegerList, 1, 0,
2324 0 : NULL );
2325 :
2326 : EstablishLayer( "OSCAR_COMMENT", wkbNone,
2327 : TranslateOscarComment, NRT_COMMENT, NULL,
2328 : "RECORD_TYPE", OFTInteger, 2, 0,
2329 : "RECORD_ID", OFTString, 13, 0,
2330 : "CHANGE_TYPE", OFTString, 1, 0,
2331 0 : NULL );
2332 : }
2333 0 : else if( GetProductId() == NPC_OSCAR_NETWORK )
2334 : {
2335 : EstablishLayer( "OSCAR_NETWORK_POINT", wkbPoint,
2336 : TranslateOscarNetworkPoint, NRT_POINTREC, NULL,
2337 : "POINT_ID", OFTInteger, 6, 0,
2338 : "GEOM_ID", OFTInteger, 6, 0,
2339 : "FEAT_CODE", OFTString, 4, 0,
2340 : "OSODR", OFTString, 13, 0,
2341 : "JUNCTION_NAME", OFTString, 0, 0,
2342 : "SETTLE_NAME", OFTString, 0, 0,
2343 : "ROUNDABOUT", OFTString, 1, 0,
2344 0 : NULL );
2345 :
2346 : EstablishLayer( "OSCAR_NETWORK_LINE", wkbLineString,
2347 : TranslateOscarNetworkLine, NRT_LINEREC, NULL,
2348 : "LINE_ID", OFTInteger, 6, 0,
2349 : "GEOM_ID", OFTInteger, 6, 0,
2350 : "FEAT_CODE", OFTString, 4, 0,
2351 : "OSODR", OFTString, 13, 0,
2352 : "PROPER_NAME", OFTString, 0, 0,
2353 : "LINE_LENGTH", OFTInteger, 5, 0,
2354 : "ROAD_NUM", OFTString, 0, 0,
2355 0 : NULL );
2356 :
2357 : EstablishLayer( "OSCAR_NETWORK_NODE", wkbNone,
2358 : TranslateStrategiNode, NRT_NODEREC, NULL,
2359 : "NODE_ID", OFTInteger, 6, 0,
2360 : "GEOM_ID_OF_POINT", OFTInteger, 6, 0,
2361 : "NUM_LINKS", OFTInteger, 4, 0,
2362 : "DIR", OFTIntegerList, 1, 0,
2363 : "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
2364 : "LEVEL", OFTIntegerList, 1, 0,
2365 0 : NULL );
2366 :
2367 : EstablishLayer( "OSCAR_COMMENT", wkbNone,
2368 : TranslateOscarComment, NRT_COMMENT, NULL,
2369 : "RECORD_TYPE", OFTInteger, 2, 0,
2370 : "RECORD_ID", OFTString, 13, 0,
2371 : "CHANGE_TYPE", OFTString, 1, 0,
2372 0 : NULL );
2373 : }
2374 0 : else if( GetProductId() == NPC_ADDRESS_POINT )
2375 : {
2376 : EstablishLayer( "ADDRESS_POINT", wkbPoint,
2377 : TranslateAddressPoint, NRT_POINTREC, NULL,
2378 : "POINT_ID", OFTInteger, 6, 0,
2379 : "OSAPR", OFTString, 18, 0,
2380 : "ORGANISATION_NAME", OFTString, 0, 0,
2381 : "DEPARTMENT_NAME", OFTString, 0, 0,
2382 : "PO_BOX", OFTString, 6, 0,
2383 : "SUBBUILDING_NAME", OFTString, 0, 0,
2384 : "BUILDING_NAME", OFTString, 0, 0,
2385 : "BUILDING_NUMBER", OFTInteger, 4, 0,
2386 : "DEPENDENT_THOROUGHFARE_NAME", OFTString, 0, 0,
2387 : "THOROUGHFARE_NAME", OFTString, 0, 0,
2388 : "DOUBLE_DEPENDENT_LOCALITY_NAME", OFTString, 0, 0,
2389 : "DEPENDENT_LOCALITY_NAME", OFTString, 0, 0,
2390 : "POST_TOWN_NAME", OFTString, 0, 0,
2391 : "COUNTY_NAME", OFTString, 0, 0,
2392 : "POSTCODE", OFTString, 7, 0,
2393 : "STATUS_FLAG", OFTString, 4, 0,
2394 : "RM_VERSION_DATE", OFTString, 8, 0,
2395 : "CHG_TYPE", OFTString, 1, 0,
2396 : "CHG_DATE", OFTString, 6, 0,
2397 0 : NULL );
2398 : }
2399 0 : else if( GetProductId() == NPC_CODE_POINT )
2400 : {
2401 : EstablishLayer( "CODE_POINT", wkbPoint,
2402 : TranslateCodePoint, NRT_POINTREC, NULL,
2403 : "POINT_ID", OFTInteger, 6, 0,
2404 : "UNIT_POSTCODE", OFTString, 7, 0,
2405 : "POSITIONAL_QUALITY", OFTInteger, 1, 0,
2406 : "PO_BOX_INDICATOR", OFTString, 1, 0,
2407 : "TOTAL_DELIVERY_POINTS", OFTInteger, 3, 0,
2408 : "DELIVERY_POINTS", OFTInteger, 3, 0,
2409 : "DOMESTIC_DELIVERY_POINTS", OFTInteger, 3, 0,
2410 : "NONDOMESTIC_DELIVERY_POINTS", OFTInteger, 3, 0,
2411 : "POBOX_DELIVERY_POINTS", OFTInteger, 3, 0,
2412 : "MATCHED_ADDRESS_PREMISES", OFTInteger, 3, 0,
2413 : "UNMATCHED_DELIVERY_POINTS", OFTInteger, 3, 0,
2414 : "RM_VERSION_DATA", OFTString, 8, 0,
2415 0 : NULL );
2416 : }
2417 0 : else if( GetProductId() == NPC_CODE_POINT_PLUS )
2418 : {
2419 : EstablishLayer( "CODE_POINT_PLUS", wkbPoint,
2420 : TranslateCodePoint, NRT_POINTREC, NULL,
2421 : "POINT_ID", OFTInteger, 6, 0,
2422 : "UNIT_POSTCODE", OFTString, 7, 0,
2423 : "POSITIONAL_QUALITY", OFTInteger, 1, 0,
2424 : "PO_BOX_INDICATOR", OFTString, 1, 0,
2425 : "TOTAL_DELIVERY_POINTS", OFTInteger, 3, 0,
2426 : "DELIVERY_POINTS", OFTInteger, 3, 0,
2427 : "DOMESTIC_DELIVERY_POINTS", OFTInteger, 3, 0,
2428 : "NONDOMESTIC_DELIVERY_POINTS", OFTInteger, 3, 0,
2429 : "POBOX_DELIVERY_POINTS", OFTInteger, 3, 0,
2430 : "MATCHED_ADDRESS_PREMISES", OFTInteger, 3, 0,
2431 : "UNMATCHED_DELIVERY_POINTS", OFTInteger, 3, 0,
2432 : "RM_VERSION_DATA", OFTString, 8, 0,
2433 : "NHS_REGIONAL_HEALTH_AUTHORITY", OFTString, 3, 0,
2434 : "NHS_HEALTH_AUTHORITY", OFTString, 3, 0,
2435 : "ADMIN_COUNTY", OFTString, 2, 0,
2436 : "ADMIN_DISTRICT", OFTString, 2, 0,
2437 : "ADMIN_WARD", OFTString, 2, 0,
2438 0 : NULL );
2439 : }
2440 : else // generic case
2441 : {
2442 : CPLAssert( GetProductId() == NPC_UNKNOWN );
2443 :
2444 0 : poDS->WorkupGeneric( this );
2445 : }
2446 : }
|