1 : /******************************************************************************
2 : * $Id: s57writer.cpp 21684 2011-02-11 22:14:01Z warmerdam $
3 : *
4 : * Project: S-57 Translator
5 : * Purpose: Implements S57Writer class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2003, 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 : #include "s57.h"
31 : #include "ogr_api.h"
32 : #include "cpl_conv.h"
33 : #include "cpl_string.h"
34 :
35 : CPL_CVSID("$Id: s57writer.cpp 21684 2011-02-11 22:14:01Z warmerdam $");
36 :
37 : /************************************************************************/
38 : /* S57Writer() */
39 : /************************************************************************/
40 :
41 0 : S57Writer::S57Writer()
42 :
43 : {
44 0 : poModule = NULL;
45 0 : poRegistrar = NULL;
46 :
47 0 : nCOMF = 10000000;
48 0 : nSOMF = 10;
49 0 : }
50 :
51 : /************************************************************************/
52 : /* ~S57Writer() */
53 : /************************************************************************/
54 :
55 0 : S57Writer::~S57Writer()
56 :
57 : {
58 0 : Close();
59 0 : }
60 :
61 : /************************************************************************/
62 : /* Close() */
63 : /* */
64 : /* Close the current S-57 dataset. */
65 : /************************************************************************/
66 :
67 0 : int S57Writer::Close()
68 :
69 : {
70 0 : if( poModule != NULL )
71 : {
72 0 : poModule->Close();
73 0 : delete poModule;
74 0 : poModule = NULL;
75 : }
76 0 : return TRUE;
77 : }
78 :
79 : /************************************************************************/
80 : /* CreateS57File() */
81 : /* */
82 : /* Create a new output ISO8211 file with all the S-57 data */
83 : /* definitions. */
84 : /************************************************************************/
85 :
86 0 : int S57Writer::CreateS57File( const char *pszFilename )
87 :
88 : {
89 0 : DDFModule oModule;
90 : DDFFieldDefn *poFDefn;
91 :
92 0 : Close();
93 :
94 0 : nNext0001Index = 1;
95 :
96 : /* -------------------------------------------------------------------- */
97 : /* Create and initialize new module. */
98 : /* -------------------------------------------------------------------- */
99 0 : poModule = new DDFModule();
100 0 : poModule->Initialize();
101 :
102 : /* -------------------------------------------------------------------- */
103 : /* Create the '0000' definition. */
104 : /* -------------------------------------------------------------------- */
105 0 : poFDefn = new DDFFieldDefn();
106 :
107 : poFDefn->Create( "0000", "", "0001DSIDDSIDDSSI0001DSPM0001VRIDVRIDATTVVRIDVRPCVRIDVRPTVRIDSGCCVRIDSG2DVRIDSG3D0001FRIDFRIDFOIDFRIDATTFFRIDNATFFRIDFFPCFRIDFFPTFRIDFSPCFRIDFSPT",
108 : dsc_elementary,
109 0 : dtc_char_string );
110 :
111 0 : poModule->AddField( poFDefn );
112 :
113 : /* -------------------------------------------------------------------- */
114 : /* Create the '0001' definition. */
115 : /* -------------------------------------------------------------------- */
116 0 : poFDefn = new DDFFieldDefn();
117 :
118 : poFDefn->Create( "0001", "ISO 8211 Record Identifier", "",
119 : dsc_elementary, dtc_bit_string,
120 0 : "(b12)" );
121 :
122 0 : poModule->AddField( poFDefn );
123 :
124 : /* -------------------------------------------------------------------- */
125 : /* Create the DSID field. */
126 : /* -------------------------------------------------------------------- */
127 0 : poFDefn = new DDFFieldDefn();
128 :
129 : poFDefn->Create( "DSID", "Data set identification field", "",
130 0 : dsc_vector, dtc_mixed_data_type );
131 :
132 0 : poFDefn->AddSubfield( "RCNM", "b11" );
133 0 : poFDefn->AddSubfield( "RCID", "b14" );
134 0 : poFDefn->AddSubfield( "EXPP", "b11" );
135 0 : poFDefn->AddSubfield( "INTU", "b11" );
136 0 : poFDefn->AddSubfield( "DSNM", "A" );
137 0 : poFDefn->AddSubfield( "EDTN", "A" );
138 0 : poFDefn->AddSubfield( "UPDN", "A" );
139 0 : poFDefn->AddSubfield( "UADT", "A(8)" );
140 0 : poFDefn->AddSubfield( "ISDT", "A(8)" );
141 0 : poFDefn->AddSubfield( "STED", "R(4)" );
142 0 : poFDefn->AddSubfield( "PRSP", "b11" );
143 0 : poFDefn->AddSubfield( "PSDN", "A" );
144 0 : poFDefn->AddSubfield( "PRED", "A" );
145 0 : poFDefn->AddSubfield( "PROF", "b11" );
146 0 : poFDefn->AddSubfield( "AGEN", "b12" );
147 0 : poFDefn->AddSubfield( "COMT", "A" );
148 :
149 0 : poModule->AddField( poFDefn );
150 :
151 : /* -------------------------------------------------------------------- */
152 : /* Create the DSSI field. */
153 : /* -------------------------------------------------------------------- */
154 0 : poFDefn = new DDFFieldDefn();
155 :
156 : poFDefn->Create( "DSSI", "Data set structure information field", "",
157 0 : dsc_vector, dtc_mixed_data_type );
158 :
159 0 : poFDefn->AddSubfield( "DSTR", "b11" );
160 0 : poFDefn->AddSubfield( "AALL", "b11" );
161 0 : poFDefn->AddSubfield( "NALL", "b11" );
162 0 : poFDefn->AddSubfield( "NOMR", "b14" );
163 0 : poFDefn->AddSubfield( "NOCR", "b14" );
164 0 : poFDefn->AddSubfield( "NOGR", "b14" );
165 0 : poFDefn->AddSubfield( "NOLR", "b14" );
166 0 : poFDefn->AddSubfield( "NOIN", "b14" );
167 0 : poFDefn->AddSubfield( "NOCN", "b14" );
168 0 : poFDefn->AddSubfield( "NOED", "b14" );
169 0 : poFDefn->AddSubfield( "NOFA", "b14" );
170 :
171 0 : poModule->AddField( poFDefn );
172 :
173 : /* -------------------------------------------------------------------- */
174 : /* Create the DSPM field. */
175 : /* -------------------------------------------------------------------- */
176 0 : poFDefn = new DDFFieldDefn();
177 :
178 : poFDefn->Create( "DSPM", "Data set parameter field", "",
179 0 : dsc_vector, dtc_mixed_data_type );
180 :
181 0 : poFDefn->AddSubfield( "RCNM", "b11" );
182 0 : poFDefn->AddSubfield( "RCID", "b14" );
183 0 : poFDefn->AddSubfield( "HDAT", "b11" );
184 0 : poFDefn->AddSubfield( "VDAT", "b11" );
185 0 : poFDefn->AddSubfield( "SDAT", "b11" );
186 0 : poFDefn->AddSubfield( "CSCL", "b14" );
187 0 : poFDefn->AddSubfield( "DUNI", "b11" );
188 0 : poFDefn->AddSubfield( "HUNI", "b11" );
189 0 : poFDefn->AddSubfield( "PUNI", "b11" );
190 0 : poFDefn->AddSubfield( "COUN", "b11" );
191 0 : poFDefn->AddSubfield( "COMF", "b14" );
192 0 : poFDefn->AddSubfield( "SOMF", "b14" );
193 0 : poFDefn->AddSubfield( "COMT", "A" );
194 :
195 0 : poModule->AddField( poFDefn );
196 :
197 : /* -------------------------------------------------------------------- */
198 : /* Create the VRID field. */
199 : /* -------------------------------------------------------------------- */
200 0 : poFDefn = new DDFFieldDefn();
201 :
202 : poFDefn->Create( "VRID", "Vector record identifier field", "",
203 0 : dsc_vector, dtc_mixed_data_type );
204 :
205 0 : poFDefn->AddSubfield( "RCNM", "b11" );
206 0 : poFDefn->AddSubfield( "RCID", "b14" );
207 0 : poFDefn->AddSubfield( "RVER", "b12" );
208 0 : poFDefn->AddSubfield( "RUIN", "b11" );
209 :
210 0 : poModule->AddField( poFDefn );
211 :
212 : /* -------------------------------------------------------------------- */
213 : /* Create the VRPC field. */
214 : /* -------------------------------------------------------------------- */
215 0 : poFDefn = new DDFFieldDefn();
216 :
217 : poFDefn->Create( "VRPC", "Vector Record Pointer Control field", "",
218 0 : dsc_vector, dtc_mixed_data_type );
219 :
220 0 : poFDefn->AddSubfield( "VPUI", "b11" );
221 0 : poFDefn->AddSubfield( "VPIX", "b12" );
222 0 : poFDefn->AddSubfield( "NVPT", "b12" );
223 :
224 0 : poModule->AddField( poFDefn );
225 :
226 : /* -------------------------------------------------------------------- */
227 : /* Create the VRPT field. */
228 : /* -------------------------------------------------------------------- */
229 0 : poFDefn = new DDFFieldDefn();
230 :
231 : poFDefn->Create( "VRPT", "Vector record pointer field", "*",
232 0 : dsc_array, dtc_mixed_data_type );
233 :
234 0 : poFDefn->AddSubfield( "NAME", "B(40)" );
235 0 : poFDefn->AddSubfield( "ORNT", "b11" );
236 0 : poFDefn->AddSubfield( "USAG", "b11" );
237 0 : poFDefn->AddSubfield( "TOPI", "b11" );
238 0 : poFDefn->AddSubfield( "MASK", "b11" );
239 :
240 0 : poModule->AddField( poFDefn );
241 :
242 : /* -------------------------------------------------------------------- */
243 : /* Create the ATTV field. */
244 : /* -------------------------------------------------------------------- */
245 0 : poFDefn = new DDFFieldDefn();
246 :
247 : poFDefn->Create( "ATTV", "Vector record attribute field", "*",
248 0 : dsc_array, dtc_mixed_data_type );
249 :
250 0 : poFDefn->AddSubfield( "ATTL", "b12" );
251 0 : poFDefn->AddSubfield( "ATVL", "A" );
252 :
253 0 : poModule->AddField( poFDefn );
254 :
255 : /* -------------------------------------------------------------------- */
256 : /* Create the SGCC field. */
257 : /* -------------------------------------------------------------------- */
258 0 : poFDefn = new DDFFieldDefn();
259 :
260 : poFDefn->Create( "SGCC", "Coordinate Control Field", "",
261 0 : dsc_vector, dtc_mixed_data_type );
262 :
263 0 : poFDefn->AddSubfield( "CCUI", "b11" );
264 0 : poFDefn->AddSubfield( "CCIX", "b12" );
265 0 : poFDefn->AddSubfield( "CCNC", "b12" );
266 :
267 0 : poModule->AddField( poFDefn );
268 :
269 : /* -------------------------------------------------------------------- */
270 : /* Create the SG2D field. */
271 : /* -------------------------------------------------------------------- */
272 0 : poFDefn = new DDFFieldDefn();
273 :
274 : poFDefn->Create( "SG2D", "2-D coordinate field", "*",
275 0 : dsc_array, dtc_mixed_data_type );
276 :
277 0 : poFDefn->AddSubfield( "YCOO", "b24" );
278 0 : poFDefn->AddSubfield( "XCOO", "b24" );
279 :
280 0 : poModule->AddField( poFDefn );
281 :
282 : /* -------------------------------------------------------------------- */
283 : /* Create the SG3D field. */
284 : /* -------------------------------------------------------------------- */
285 0 : poFDefn = new DDFFieldDefn();
286 :
287 : poFDefn->Create( "SG3D", "3-D coordinate (sounding array) field", "*",
288 0 : dsc_array, dtc_mixed_data_type );
289 :
290 0 : poFDefn->AddSubfield( "YCOO", "b24" );
291 0 : poFDefn->AddSubfield( "XCOO", "b24" );
292 0 : poFDefn->AddSubfield( "VE3D", "b24" );
293 :
294 0 : poModule->AddField( poFDefn );
295 :
296 : /* -------------------------------------------------------------------- */
297 : /* Create the FRID field. */
298 : /* -------------------------------------------------------------------- */
299 0 : poFDefn = new DDFFieldDefn();
300 :
301 : poFDefn->Create( "FRID", "Feature record identifier field", "",
302 0 : dsc_vector, dtc_mixed_data_type );
303 :
304 0 : poFDefn->AddSubfield( "RCNM", "b11" );
305 0 : poFDefn->AddSubfield( "RCID", "b14" );
306 0 : poFDefn->AddSubfield( "PRIM", "b11" );
307 0 : poFDefn->AddSubfield( "GRUP", "b11" );
308 0 : poFDefn->AddSubfield( "OBJL", "b12" );
309 0 : poFDefn->AddSubfield( "RVER", "b12" );
310 0 : poFDefn->AddSubfield( "RUIN", "b11" );
311 :
312 0 : poModule->AddField( poFDefn );
313 :
314 : /* -------------------------------------------------------------------- */
315 : /* Create the FOID field. */
316 : /* -------------------------------------------------------------------- */
317 0 : poFDefn = new DDFFieldDefn();
318 :
319 : poFDefn->Create( "FOID", "Feature object identifier field", "",
320 0 : dsc_vector, dtc_mixed_data_type );
321 :
322 0 : poFDefn->AddSubfield( "AGEN", "b12" );
323 0 : poFDefn->AddSubfield( "FIDN", "b14" );
324 0 : poFDefn->AddSubfield( "FIDS", "b12" );
325 :
326 0 : poModule->AddField( poFDefn );
327 :
328 : /* -------------------------------------------------------------------- */
329 : /* Create the ATTF field. */
330 : /* -------------------------------------------------------------------- */
331 0 : poFDefn = new DDFFieldDefn();
332 :
333 : poFDefn->Create( "ATTF", "Feature record attribute field", "*",
334 0 : dsc_array, dtc_mixed_data_type );
335 :
336 0 : poFDefn->AddSubfield( "ATTL", "b12" );
337 0 : poFDefn->AddSubfield( "ATVL", "A" );
338 :
339 0 : poModule->AddField( poFDefn );
340 :
341 : /* -------------------------------------------------------------------- */
342 : /* Create the NATF field. */
343 : /* -------------------------------------------------------------------- */
344 0 : poFDefn = new DDFFieldDefn();
345 :
346 : poFDefn->Create( "NATF", "Feature record national attribute field", "*",
347 0 : dsc_array, dtc_mixed_data_type );
348 :
349 0 : poFDefn->AddSubfield( "ATTL", "b12" );
350 0 : poFDefn->AddSubfield( "ATVL", "A" );
351 :
352 0 : poModule->AddField( poFDefn );
353 :
354 : /* -------------------------------------------------------------------- */
355 : /* Create the FFPC field. */
356 : /* -------------------------------------------------------------------- */
357 0 : poFDefn = new DDFFieldDefn();
358 :
359 : poFDefn->Create( "FFPC", "Feature record to feature object pointer control field", "",
360 0 : dsc_vector, dtc_mixed_data_type );
361 :
362 0 : poFDefn->AddSubfield( "FFUI", "b11" );
363 0 : poFDefn->AddSubfield( "FFIX", "b12" );
364 0 : poFDefn->AddSubfield( "NFPT", "b12" );
365 :
366 0 : poModule->AddField( poFDefn );
367 :
368 : /* -------------------------------------------------------------------- */
369 : /* Create the FFPT field. */
370 : /* -------------------------------------------------------------------- */
371 0 : poFDefn = new DDFFieldDefn();
372 :
373 : poFDefn->Create( "FFPT", "Feature record to feature object pointer field", "*",
374 0 : dsc_array, dtc_mixed_data_type );
375 :
376 0 : poFDefn->AddSubfield( "LNAM", "B(64)" );
377 0 : poFDefn->AddSubfield( "RIND", "b11" );
378 0 : poFDefn->AddSubfield( "COMT", "A" );
379 :
380 0 : poModule->AddField( poFDefn );
381 :
382 : /* -------------------------------------------------------------------- */
383 : /* Create the FSPC field. */
384 : /* -------------------------------------------------------------------- */
385 0 : poFDefn = new DDFFieldDefn();
386 :
387 : poFDefn->Create( "FSPC", "Feature record to spatial record pointer control field", "",
388 0 : dsc_vector, dtc_mixed_data_type );
389 :
390 0 : poFDefn->AddSubfield( "FSUI", "b11" );
391 0 : poFDefn->AddSubfield( "FSIX", "b12" );
392 0 : poFDefn->AddSubfield( "NSPT", "b12" );
393 :
394 0 : poModule->AddField( poFDefn );
395 :
396 : /* -------------------------------------------------------------------- */
397 : /* Create the FSPT field. */
398 : /* -------------------------------------------------------------------- */
399 0 : poFDefn = new DDFFieldDefn();
400 :
401 : poFDefn->Create( "FSPT", "Feature record to spatial record pointer field",
402 0 : "*", dsc_array, dtc_mixed_data_type );
403 :
404 0 : poFDefn->AddSubfield( "NAME", "B(40)" );
405 0 : poFDefn->AddSubfield( "ORNT", "b11" );
406 0 : poFDefn->AddSubfield( "USAG", "b11" );
407 0 : poFDefn->AddSubfield( "MASK", "b11" );
408 :
409 0 : poModule->AddField( poFDefn );
410 :
411 : /* -------------------------------------------------------------------- */
412 : /* Create file. */
413 : /* -------------------------------------------------------------------- */
414 0 : if( !poModule->Create( pszFilename ) )
415 : {
416 0 : delete poModule;
417 0 : poModule = NULL;
418 0 : return FALSE;
419 : }
420 :
421 0 : return TRUE;
422 : }
423 :
424 : /************************************************************************/
425 : /* WriteDSID() */
426 : /************************************************************************/
427 :
428 0 : int S57Writer::WriteDSID( const char *pszDSNM, const char *pszISDT,
429 : const char *pszSTED, int nAGEN,
430 : const char *pszCOMT )
431 :
432 : {
433 : /* -------------------------------------------------------------------- */
434 : /* Default values. */
435 : /* -------------------------------------------------------------------- */
436 0 : if( pszDSNM == NULL )
437 0 : pszDSNM = "";
438 0 : if( pszISDT == NULL )
439 0 : pszISDT = "20030801";
440 0 : if( pszSTED == NULL )
441 0 : pszSTED = "03.1";
442 0 : if( pszCOMT == NULL )
443 0 : pszCOMT = "";
444 :
445 : /* -------------------------------------------------------------------- */
446 : /* Add the DSID field. */
447 : /* -------------------------------------------------------------------- */
448 0 : DDFRecord *poRec = MakeRecord();
449 : DDFField *poField;
450 :
451 0 : poField = poRec->AddField( poModule->FindFieldDefn( "DSID" ) );
452 :
453 0 : poRec->SetIntSubfield ( "DSID", 0, "RCNM", 0, 10 );
454 0 : poRec->SetIntSubfield ( "DSID", 0, "RCID", 0, 1 );
455 0 : poRec->SetIntSubfield ( "DSID", 0, "EXPP", 0, 1 );
456 0 : poRec->SetIntSubfield ( "DSID", 0, "INTU", 0, 4 );
457 0 : poRec->SetStringSubfield( "DSID", 0, "DSNM", 0, pszDSNM );
458 0 : poRec->SetStringSubfield( "DSID", 0, "EDTN", 0, "2" );
459 0 : poRec->SetStringSubfield( "DSID", 0, "UPDN", 0, "0" );
460 0 : poRec->SetStringSubfield( "DSID", 0, "UADT", 0, pszISDT );
461 0 : poRec->SetStringSubfield( "DSID", 0, "ISDT", 0, pszISDT );
462 0 : poRec->SetStringSubfield( "DSID", 0, "STED", 0, pszSTED );
463 0 : poRec->SetIntSubfield ( "DSID", 0, "PRSP", 0, 1 );
464 0 : poRec->SetStringSubfield( "DSID", 0, "PSDN", 0, "" );
465 0 : poRec->SetStringSubfield( "DSID", 0, "PRED", 0, "2.0" );
466 0 : poRec->SetIntSubfield ( "DSID", 0, "PROF", 0, 1 );
467 0 : poRec->SetIntSubfield ( "DSID", 0, "AGEN", 0, nAGEN );
468 0 : poRec->SetStringSubfield( "DSID", 0, "COMT", 0, pszCOMT );
469 :
470 : /* -------------------------------------------------------------------- */
471 : /* Add the DSSI record. Eventually we will need to return and */
472 : /* correct these when we are finished writing. */
473 : /* -------------------------------------------------------------------- */
474 0 : poField = poRec->AddField( poModule->FindFieldDefn( "DSSI" ) );
475 :
476 0 : poRec->SetIntSubfield ( "DSSI", 0, "DSTR", 0, 2 );
477 0 : poRec->SetIntSubfield ( "DSSI", 0, "AALL", 0, 1 );
478 0 : poRec->SetIntSubfield ( "DSSI", 0, "NALL", 0, 1 );
479 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOMR", 0, 0 );
480 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOCR", 0, 0 );
481 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOGR", 0, 3 );
482 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOLR", 0, 0 );
483 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOIN", 0, 3 );
484 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOCN", 0, 0 );
485 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOED", 0, 0 );
486 0 : poRec->SetIntSubfield ( "DSSI", 0, "NOFA", 0, 0 );
487 :
488 : /* -------------------------------------------------------------------- */
489 : /* Write out the record. */
490 : /* -------------------------------------------------------------------- */
491 0 : poRec->Write();
492 0 : delete poRec;
493 :
494 0 : return TRUE;
495 : }
496 :
497 : /************************************************************************/
498 : /* WriteDSPM() */
499 : /************************************************************************/
500 :
501 0 : int S57Writer::WriteDSPM( int nScale )
502 :
503 : {
504 0 : if( nScale == 0 )
505 0 : nScale = 52000;
506 :
507 : /* -------------------------------------------------------------------- */
508 : /* Add the DSID field. */
509 : /* -------------------------------------------------------------------- */
510 0 : DDFRecord *poRec = MakeRecord();
511 : DDFField *poField;
512 :
513 0 : poField = poRec->AddField( poModule->FindFieldDefn( "DSPM" ) );
514 :
515 0 : poRec->SetIntSubfield ( "DSPM", 0, "RCNM", 0, 20 );
516 0 : poRec->SetIntSubfield ( "DSPM", 0, "RCID", 0, 1 );
517 0 : poRec->SetIntSubfield ( "DSPM", 0, "HDAT", 0, 2 );
518 0 : poRec->SetIntSubfield ( "DSPM", 0, "VDAT", 0, 17 );
519 0 : poRec->SetIntSubfield ( "DSPM", 0, "SDAT", 0, 23 );
520 0 : poRec->SetIntSubfield ( "DSPM", 0, "CSCL", 0, nScale );
521 0 : poRec->SetIntSubfield ( "DSPM", 0, "DUNI", 0, 1 );
522 0 : poRec->SetIntSubfield ( "DSPM", 0, "HUNI", 0, 1 );
523 0 : poRec->SetIntSubfield ( "DSPM", 0, "PUNI", 0, 1 );
524 0 : poRec->SetIntSubfield ( "DSPM", 0, "COUN", 0, 1 );
525 0 : poRec->SetIntSubfield ( "DSPM", 0, "COMF", 0, nCOMF );
526 0 : poRec->SetIntSubfield ( "DSPM", 0, "SOMF", 0, nSOMF );
527 :
528 : /* -------------------------------------------------------------------- */
529 : /* Write out the record. */
530 : /* -------------------------------------------------------------------- */
531 0 : poRec->Write();
532 0 : delete poRec;
533 :
534 0 : return TRUE;
535 : }
536 :
537 : /************************************************************************/
538 : /* MakeRecord() */
539 : /* */
540 : /* Create a new empty record, and append a 0001 field with a */
541 : /* properly set record index in it. */
542 : /************************************************************************/
543 :
544 0 : DDFRecord *S57Writer::MakeRecord()
545 :
546 : {
547 0 : DDFRecord *poRec = new DDFRecord( poModule );
548 : DDFField *poField;
549 : unsigned char abyData[3];
550 :
551 0 : abyData[0] = nNext0001Index % 256;
552 0 : abyData[1] = (unsigned char) (nNext0001Index / 256);
553 0 : abyData[2] = DDF_FIELD_TERMINATOR;
554 :
555 0 : poField = poRec->AddField( poModule->FindFieldDefn( "0001" ) );
556 0 : poRec->SetFieldRaw( poField, 0, (const char *) abyData, 3 );
557 :
558 0 : nNext0001Index++;
559 :
560 0 : return poRec;
561 : }
562 :
563 : /************************************************************************/
564 : /* WriteGeometry() */
565 : /************************************************************************/
566 :
567 0 : int S57Writer::WriteGeometry( DDFRecord *poRec, int nVertCount,
568 : double *padfX, double *padfY, double *padfZ )
569 :
570 : {
571 0 : const char *pszFieldName = "SG2D";
572 : DDFField *poField;
573 : int nRawDataSize, i, nSuccess;
574 : unsigned char *pabyRawData;
575 :
576 0 : if( padfZ != NULL )
577 0 : pszFieldName = "SG3D";
578 :
579 0 : poField = poRec->AddField( poModule->FindFieldDefn( pszFieldName ) );
580 :
581 0 : if( padfZ )
582 0 : nRawDataSize = 12 * nVertCount + 1;
583 : else
584 0 : nRawDataSize = 8 * nVertCount + 1;
585 :
586 0 : pabyRawData = (unsigned char *) CPLMalloc(nRawDataSize);
587 0 : pabyRawData[nRawDataSize-1] = DDF_UNIT_TERMINATOR;
588 :
589 0 : for( i = 0; i < nVertCount; i++ )
590 : {
591 : GInt32 nXCOO, nYCOO, nVE3D;
592 :
593 0 : nXCOO = CPL_LSBWORD32((GInt32) floor(padfX[i] * nCOMF + 0.5));
594 0 : nYCOO = CPL_LSBWORD32((GInt32) floor(padfY[i] * nCOMF + 0.5));
595 :
596 0 : if( padfZ == NULL )
597 : {
598 0 : memcpy( pabyRawData + i * 8, &nYCOO, 4 );
599 0 : memcpy( pabyRawData + i * 8 + 4, &nXCOO, 4 );
600 : }
601 : else
602 : {
603 0 : nVE3D = CPL_LSBWORD32((GInt32) floor( padfZ[i] * nSOMF + 0.5 ));
604 0 : memcpy( pabyRawData + i * 12, &nYCOO, 4 );
605 0 : memcpy( pabyRawData + i * 12 + 4, &nXCOO, 4 );
606 0 : memcpy( pabyRawData + i * 12 + 8, &nVE3D, 4 );
607 : }
608 : }
609 :
610 : nSuccess = poRec->SetFieldRaw( poField, 0,
611 0 : (const char *) pabyRawData, nRawDataSize );
612 :
613 0 : CPLFree( pabyRawData );
614 :
615 0 : return nSuccess;
616 : }
617 :
618 : /************************************************************************/
619 : /* WritePrimitive() */
620 : /************************************************************************/
621 :
622 0 : int S57Writer::WritePrimitive( OGRFeature *poFeature )
623 :
624 : {
625 0 : DDFRecord *poRec = MakeRecord();
626 : DDFField *poField;
627 0 : OGRGeometry *poGeom = poFeature->GetGeometryRef();
628 :
629 : /* -------------------------------------------------------------------- */
630 : /* Add the VRID field. */
631 : /* -------------------------------------------------------------------- */
632 :
633 0 : poField = poRec->AddField( poModule->FindFieldDefn( "VRID" ) );
634 :
635 : poRec->SetIntSubfield ( "VRID", 0, "RCNM", 0,
636 0 : poFeature->GetFieldAsInteger( "RCNM") );
637 : poRec->SetIntSubfield ( "VRID", 0, "RCID", 0,
638 0 : poFeature->GetFieldAsInteger( "RCID") );
639 0 : poRec->SetIntSubfield ( "VRID", 0, "RVER", 0, 1 );
640 0 : poRec->SetIntSubfield ( "VRID", 0, "RUIN", 0, 1 );
641 :
642 : /* -------------------------------------------------------------------- */
643 : /* Handle simple point. */
644 : /* -------------------------------------------------------------------- */
645 0 : if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
646 : {
647 : double dfX, dfY, dfZ;
648 0 : OGRPoint *poPoint = (OGRPoint *) poGeom;
649 :
650 : CPLAssert( poFeature->GetFieldAsInteger( "RCNM") == RCNM_VI
651 0 : || poFeature->GetFieldAsInteger( "RCNM") == RCNM_VC );
652 :
653 0 : dfX = poPoint->getX();
654 0 : dfY = poPoint->getY();
655 0 : dfZ = poPoint->getZ();
656 :
657 0 : if( dfZ == 0.0 )
658 0 : WriteGeometry( poRec, 1, &dfX, &dfY, NULL );
659 : else
660 0 : WriteGeometry( poRec, 1, &dfX, &dfY, &dfZ );
661 : }
662 :
663 : /* -------------------------------------------------------------------- */
664 : /* For multipoints we assuming SOUNDG, and write out as SG3D. */
665 : /* -------------------------------------------------------------------- */
666 0 : else if( poGeom != NULL
667 0 : && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPoint )
668 : {
669 0 : OGRMultiPoint *poMP = (OGRMultiPoint *) poGeom;
670 0 : int i, nVCount = poMP->getNumGeometries();
671 : double *padfX, *padfY, *padfZ;
672 :
673 : CPLAssert( poFeature->GetFieldAsInteger( "RCNM") == RCNM_VI
674 0 : || poFeature->GetFieldAsInteger( "RCNM") == RCNM_VC );
675 :
676 0 : padfX = (double *) CPLMalloc(sizeof(double) * nVCount);
677 0 : padfY = (double *) CPLMalloc(sizeof(double) * nVCount);
678 0 : padfZ = (double *) CPLMalloc(sizeof(double) * nVCount);
679 :
680 0 : for( i = 0; i < nVCount; i++ )
681 : {
682 0 : OGRPoint *poPoint = (OGRPoint *) poMP->getGeometryRef( i );
683 0 : padfX[i] = poPoint->getX();
684 0 : padfY[i] = poPoint->getY();
685 0 : padfZ[i] = poPoint->getZ();
686 : }
687 :
688 0 : WriteGeometry( poRec, nVCount, padfX, padfY, padfZ );
689 :
690 0 : CPLFree( padfX );
691 0 : CPLFree( padfY );
692 0 : CPLFree( padfZ );
693 : }
694 :
695 : /* -------------------------------------------------------------------- */
696 : /* Handle LINESTRINGs (edge) geometry. */
697 : /* -------------------------------------------------------------------- */
698 0 : else if( poGeom != NULL
699 0 : && wkbFlatten(poGeom->getGeometryType()) == wkbLineString )
700 : {
701 0 : OGRLineString *poLS = (OGRLineString *) poGeom;
702 0 : int i, nVCount = poLS->getNumPoints();
703 : double *padfX, *padfY;
704 :
705 0 : CPLAssert( poFeature->GetFieldAsInteger( "RCNM") == RCNM_VE );
706 :
707 0 : padfX = (double *) CPLMalloc(sizeof(double) * nVCount);
708 0 : padfY = (double *) CPLMalloc(sizeof(double) * nVCount);
709 :
710 0 : for( i = 0; i < nVCount; i++ )
711 : {
712 0 : padfX[i] = poLS->getX(i);
713 0 : padfY[i] = poLS->getY(i);
714 : }
715 :
716 0 : WriteGeometry( poRec, nVCount, padfX, padfY, NULL );
717 :
718 0 : CPLFree( padfX );
719 0 : CPLFree( padfY );
720 :
721 : }
722 :
723 : /* -------------------------------------------------------------------- */
724 : /* edge node linkages. */
725 : /* -------------------------------------------------------------------- */
726 0 : if( poFeature->GetDefnRef()->GetFieldIndex( "NAME_RCNM_0" ) >= 0 )
727 : {
728 : DDFField *poField;
729 : char szName[5];
730 : int nRCID;
731 :
732 0 : CPLAssert( poFeature->GetFieldAsInteger( "NAME_RCNM_0") == RCNM_VC );
733 :
734 0 : poField = poRec->AddField( poModule->FindFieldDefn( "VRPT" ) );
735 :
736 0 : nRCID = poFeature->GetFieldAsInteger( "NAME_RCID_0");
737 0 : szName[0] = RCNM_VC;
738 0 : szName[1] = nRCID & 0xff;
739 0 : szName[2] = (char) ((nRCID & 0xff00) >> 8);
740 0 : szName[3] = (char) ((nRCID & 0xff0000) >> 16);
741 0 : szName[4] = (char) ((nRCID & 0xff000000) >> 24);
742 :
743 0 : poRec->SetStringSubfield( "VRPT", 0, "NAME", 0, szName, 5 );
744 : poRec->SetIntSubfield ( "VRPT", 0, "ORNT", 0,
745 0 : poFeature->GetFieldAsInteger( "ORNT_0") );
746 : poRec->SetIntSubfield ( "VRPT", 0, "USAG", 0,
747 0 : poFeature->GetFieldAsInteger( "USAG_0") );
748 : poRec->SetIntSubfield ( "VRPT", 0, "TOPI", 0,
749 0 : poFeature->GetFieldAsInteger( "TOPI_0") );
750 : poRec->SetIntSubfield ( "VRPT", 0, "MASK", 0,
751 0 : poFeature->GetFieldAsInteger( "MASK_0") );
752 :
753 0 : nRCID = poFeature->GetFieldAsInteger( "NAME_RCID_1");
754 0 : szName[0] = RCNM_VC;
755 0 : szName[1] = nRCID & 0xff;
756 0 : szName[2] = (char) ((nRCID & 0xff00) >> 8);
757 0 : szName[3] = (char) ((nRCID & 0xff0000) >> 16);
758 0 : szName[4] = (char) ((nRCID & 0xff000000) >> 24);
759 :
760 0 : poRec->SetStringSubfield( "VRPT", 0, "NAME", 1, szName, 5 );
761 : poRec->SetIntSubfield ( "VRPT", 0, "ORNT", 1,
762 0 : poFeature->GetFieldAsInteger( "ORNT_1") );
763 : poRec->SetIntSubfield ( "VRPT", 0, "USAG", 1,
764 0 : poFeature->GetFieldAsInteger( "USAG_1") );
765 : poRec->SetIntSubfield ( "VRPT", 0, "TOPI", 1,
766 0 : poFeature->GetFieldAsInteger( "TOPI_1") );
767 : poRec->SetIntSubfield ( "VRPT", 0, "MASK", 1,
768 0 : poFeature->GetFieldAsInteger( "MASK_1") );
769 : }
770 :
771 : /* -------------------------------------------------------------------- */
772 : /* Write out the record. */
773 : /* -------------------------------------------------------------------- */
774 0 : poRec->Write();
775 0 : delete poRec;
776 :
777 0 : return TRUE;
778 : }
779 :
780 : /************************************************************************/
781 : /* GetHEXChar() */
782 : /************************************************************************/
783 :
784 0 : static char GetHEXChar( const char *pszSrcHEXString )
785 :
786 : {
787 0 : int nResult = 0;
788 :
789 0 : if( pszSrcHEXString[0] == '\0' || pszSrcHEXString[1] == '\0' )
790 0 : return (char) 0;
791 :
792 0 : if( pszSrcHEXString[0] >= '0' && pszSrcHEXString[0] <= '9' )
793 0 : nResult += (pszSrcHEXString[0] - '0') * 16;
794 0 : else if( pszSrcHEXString[0] >= 'a' && pszSrcHEXString[0] <= 'f' )
795 0 : nResult += (pszSrcHEXString[0] - 'a' + 10) * 16;
796 0 : else if( pszSrcHEXString[0] >= 'A' && pszSrcHEXString[0] <= 'F' )
797 0 : nResult += (pszSrcHEXString[0] - 'A' + 10) * 16;
798 :
799 0 : if( pszSrcHEXString[1] >= '0' && pszSrcHEXString[1] <= '9' )
800 0 : nResult += pszSrcHEXString[1] - '0';
801 0 : else if( pszSrcHEXString[1] >= 'a' && pszSrcHEXString[1] <= 'f' )
802 0 : nResult += pszSrcHEXString[1] - 'a' + 10;
803 0 : else if( pszSrcHEXString[1] >= 'A' && pszSrcHEXString[1] <= 'F' )
804 0 : nResult += pszSrcHEXString[1] - 'A' + 10;
805 :
806 0 : return (char) nResult;
807 : }
808 :
809 : /************************************************************************/
810 : /* WriteCompleteFeature() */
811 : /************************************************************************/
812 :
813 0 : int S57Writer::WriteCompleteFeature( OGRFeature *poFeature )
814 :
815 : {
816 0 : OGRFeatureDefn *poFDefn = poFeature->GetDefnRef();
817 :
818 : /* -------------------------------------------------------------------- */
819 : /* We handle primitives in a seperate method. */
820 : /* -------------------------------------------------------------------- */
821 0 : if( EQUAL(poFDefn->GetName(),OGRN_VI)
822 : || EQUAL(poFDefn->GetName(),OGRN_VC)
823 : || EQUAL(poFDefn->GetName(),OGRN_VE) )
824 0 : return WritePrimitive( poFeature );
825 :
826 : /* -------------------------------------------------------------------- */
827 : /* Create the record. */
828 : /* -------------------------------------------------------------------- */
829 0 : DDFRecord *poRec = MakeRecord();
830 :
831 : /* -------------------------------------------------------------------- */
832 : /* Add the FRID. */
833 : /* -------------------------------------------------------------------- */
834 : DDFField *poField;
835 :
836 0 : poField = poRec->AddField( poModule->FindFieldDefn( "FRID" ) );
837 :
838 0 : poRec->SetIntSubfield ( "FRID", 0, "RCNM", 0, 100 );
839 : poRec->SetIntSubfield ( "FRID", 0, "RCID", 0,
840 0 : poFeature->GetFieldAsInteger( "RCID" ) );
841 : poRec->SetIntSubfield ( "FRID", 0, "PRIM", 0,
842 0 : poFeature->GetFieldAsInteger( "PRIM" ) );
843 : poRec->SetIntSubfield ( "FRID", 0, "GRUP", 0,
844 0 : poFeature->GetFieldAsInteger( "GRUP") );
845 : poRec->SetIntSubfield ( "FRID", 0, "OBJL", 0,
846 0 : poFeature->GetFieldAsInteger( "OBJL") );
847 0 : poRec->SetIntSubfield ( "FRID", 0, "RVER", 0, 1 ); /* always new insert*/
848 0 : poRec->SetIntSubfield ( "FRID", 0, "RUIN", 0, 1 );
849 :
850 : /* -------------------------------------------------------------------- */
851 : /* Add the FOID */
852 : /* -------------------------------------------------------------------- */
853 0 : poField = poRec->AddField( poModule->FindFieldDefn( "FOID" ) );
854 :
855 : poRec->SetIntSubfield ( "FOID", 0, "AGEN", 0,
856 0 : poFeature->GetFieldAsInteger( "AGEN") );
857 : poRec->SetIntSubfield ( "FOID", 0, "FIDN", 0,
858 0 : poFeature->GetFieldAsInteger( "FIDN") );
859 : poRec->SetIntSubfield ( "FOID", 0, "FIDS", 0,
860 0 : poFeature->GetFieldAsInteger( "FIDS") );
861 :
862 : /* -------------------------------------------------------------------- */
863 : /* ATTF support. */
864 : /* -------------------------------------------------------------------- */
865 :
866 0 : if( poRegistrar != NULL
867 : && poRegistrar->SelectClass( poFeature->GetDefnRef()->GetName() )
868 : && !WriteATTF( poRec, poFeature ) )
869 0 : return FALSE;
870 :
871 : /* -------------------------------------------------------------------- */
872 : /* Add the FSPT if needed. */
873 : /* -------------------------------------------------------------------- */
874 0 : if( poFeature->IsFieldSet( poFeature->GetFieldIndex("NAME_RCNM") ) )
875 : {
876 : int nItemCount, i;
877 : const int *panRCNM, *panRCID, *panORNT, *panUSAG, *panMASK;
878 : unsigned char *pabyRawData;
879 : int nRawDataSize;
880 :
881 0 : panRCNM = poFeature->GetFieldAsIntegerList( "NAME_RCNM", &nItemCount );
882 0 : panRCID = poFeature->GetFieldAsIntegerList( "NAME_RCID", &nItemCount );
883 0 : panORNT = poFeature->GetFieldAsIntegerList( "ORNT", &nItemCount );
884 0 : panUSAG = poFeature->GetFieldAsIntegerList( "USAG", &nItemCount );
885 0 : panMASK = poFeature->GetFieldAsIntegerList( "MASK", &nItemCount );
886 :
887 : CPLAssert( sizeof(int) == sizeof(GInt32) );
888 :
889 0 : nRawDataSize = nItemCount * 8 + 1;
890 0 : pabyRawData = (unsigned char *) CPLMalloc(nRawDataSize);
891 0 : pabyRawData[nRawDataSize-1] = DDF_UNIT_TERMINATOR;
892 :
893 0 : for( i = 0; i < nItemCount; i++ )
894 : {
895 0 : GInt32 nRCID = CPL_LSBWORD32(panRCID[i]);
896 :
897 0 : pabyRawData[i*8 + 0] = (GByte) panRCNM[i];
898 0 : memcpy( pabyRawData + i*8 + 1, &nRCID, 4 );
899 0 : pabyRawData[i*8 + 5] = (GByte) panORNT[i];
900 0 : pabyRawData[i*8 + 6] = (GByte) panUSAG[i];
901 0 : pabyRawData[i*8 + 7] = (GByte) panMASK[i];
902 : }
903 :
904 0 : poField = poRec->AddField( poModule->FindFieldDefn( "FSPT" ) );
905 : poRec->SetFieldRaw( poField, 0,
906 0 : (const char *) pabyRawData, nRawDataSize );
907 0 : CPLFree( pabyRawData );
908 : }
909 :
910 : /* -------------------------------------------------------------------- */
911 : /* Add the FFPT if needed. */
912 : /* -------------------------------------------------------------------- */
913 0 : char **papszLNAM_REFS = poFeature->GetFieldAsStringList( "LNAM_REFS" );
914 :
915 0 : if( CSLCount(papszLNAM_REFS) > 0 )
916 : {
917 0 : int i, nRefCount = CSLCount(papszLNAM_REFS);
918 : const int *panRIND =
919 0 : poFeature->GetFieldAsIntegerList( "FFPT_RIND", NULL );
920 :
921 0 : poRec->AddField( poModule->FindFieldDefn( "FFPT" ) );
922 :
923 0 : for( i = 0; i < nRefCount; i++ )
924 : {
925 : char szLNAM[9];
926 :
927 0 : if( strlen(papszLNAM_REFS[i]) < 16 )
928 0 : continue;
929 :
930 : // AGEN
931 0 : szLNAM[1] = GetHEXChar( papszLNAM_REFS[i] + 0 );
932 0 : szLNAM[0] = GetHEXChar( papszLNAM_REFS[i] + 2 );
933 :
934 : // FIDN
935 0 : szLNAM[5] = GetHEXChar( papszLNAM_REFS[i] + 4 );
936 0 : szLNAM[4] = GetHEXChar( papszLNAM_REFS[i] + 6 );
937 0 : szLNAM[3] = GetHEXChar( papszLNAM_REFS[i] + 8 );
938 0 : szLNAM[2] = GetHEXChar( papszLNAM_REFS[i] + 10 );
939 :
940 : // FIDS
941 0 : szLNAM[7] = GetHEXChar( papszLNAM_REFS[i] + 12 );
942 0 : szLNAM[6] = GetHEXChar( papszLNAM_REFS[i] + 14 );
943 :
944 0 : szLNAM[8] = '\0';
945 :
946 : poRec->SetStringSubfield( "FFPT", 0, "LNAM", i,
947 0 : (char *) szLNAM, 8 );
948 : poRec->SetIntSubfield( "FFPT", 0, "RIND", i,
949 0 : panRIND[i] );
950 : }
951 : }
952 :
953 : /* -------------------------------------------------------------------- */
954 : /* Write out the record. */
955 : /* -------------------------------------------------------------------- */
956 0 : poRec->Write();
957 0 : delete poRec;
958 :
959 0 : return TRUE;
960 : }
961 :
962 : /************************************************************************/
963 : /* SetClassBased() */
964 : /************************************************************************/
965 :
966 0 : void S57Writer::SetClassBased( S57ClassRegistrar * poReg )
967 :
968 : {
969 0 : poRegistrar = poReg;
970 0 : }
971 :
972 : /************************************************************************/
973 : /* WriteATTF() */
974 : /************************************************************************/
975 :
976 0 : int S57Writer::WriteATTF( DDFRecord *poRec, OGRFeature *poFeature )
977 : {
978 0 : int nRawSize=0, nACount = 0;
979 : char achRawData[5000];
980 : char **papszAttrList;
981 :
982 0 : CPLAssert( poRegistrar != NULL );
983 :
984 : /* -------------------------------------------------------------------- */
985 : /* Loop over all attributes. */
986 : /* -------------------------------------------------------------------- */
987 0 : papszAttrList = poRegistrar->GetAttributeList(NULL);
988 :
989 0 : for( int iAttr = 0; papszAttrList[iAttr] != NULL; iAttr++ )
990 : {
991 0 : int iField = poFeature->GetFieldIndex( papszAttrList[iAttr] );
992 : OGRFieldType eFldType =
993 0 : poFeature->GetDefnRef()->GetFieldDefn(iField)->GetType();
994 : GInt16 nATTL;
995 : const char *pszATVL;
996 :
997 0 : if( iField < 0 )
998 0 : continue;
999 :
1000 0 : if( !poFeature->IsFieldSet( iField ) )
1001 0 : continue;
1002 :
1003 0 : nATTL = poRegistrar->FindAttrByAcronym( papszAttrList[iAttr] );
1004 0 : if( nATTL == -1 )
1005 0 : continue;
1006 :
1007 0 : nATTL = CPL_LSBWORD16( nATTL );
1008 0 : memcpy( achRawData + nRawSize, &nATTL, 2 );
1009 0 : nRawSize += 2;
1010 :
1011 0 : pszATVL = poFeature->GetFieldAsString( iField );
1012 :
1013 : // Special hack to handle special "empty" marker in integer fields.
1014 0 : if( atoi(pszATVL) == EMPTY_NUMBER_MARKER
1015 : && (eFldType == OFTInteger || eFldType == OFTReal) )
1016 0 : pszATVL = "";
1017 :
1018 : // Watch for really long data.
1019 0 : if( strlen(pszATVL) + nRawSize + 10 > sizeof(achRawData) )
1020 : {
1021 : CPLError( CE_Failure, CPLE_AppDefined,
1022 0 : "Too much ATTF data for fixed buffer size." );
1023 0 : return FALSE;
1024 : }
1025 :
1026 : // copy data into record buffer.
1027 0 : memcpy( achRawData + nRawSize, pszATVL, strlen(pszATVL) );
1028 0 : nRawSize += strlen(pszATVL);
1029 0 : achRawData[nRawSize++] = DDF_UNIT_TERMINATOR;
1030 :
1031 0 : nACount++;
1032 : }
1033 :
1034 : /* -------------------------------------------------------------------- */
1035 : /* If we got no attributes, return without adding ATTF. */
1036 : /* -------------------------------------------------------------------- */
1037 0 : if( nACount == 0 )
1038 0 : return TRUE;
1039 :
1040 : /* -------------------------------------------------------------------- */
1041 : /* Write the new field value. */
1042 : /* -------------------------------------------------------------------- */
1043 : DDFField *poField;
1044 :
1045 0 : poField = poRec->AddField( poModule->FindFieldDefn( "ATTF" ) );
1046 :
1047 0 : return poRec->SetFieldRaw( poField, 0, achRawData, nRawSize );
1048 : }
1049 :
1050 :
|