LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/s57 - s57writer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 455 0 0.0 %
Date: 2012-04-28 Functions: 15 0 0.0 %

       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                 : 

Generated by: LCOV version 1.7