Changeset 13555

Show
Ignore:
Timestamp:
01/20/08 12:47:35 (6 months ago)
Author:
rouault
Message:

Commit geoconcept-20080120.patch (bug #2146)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/ogr/ogrsf_frmts/geoconcept/drv_geoconcept.html

    r13510 r13555  
    88<h1>G&eacute;oconcept text export</h1> 
    99 
    10 G&eacute;oconcept text export files should be available for writing as of 
    11 editing this page.<p> 
    12  
    13 Normally the OGR G&eacute;oconcept driver treats a whole directory of G&eacute;oconcept 
    14 as a dataset, and a single G&eacute;oconcept within that directory as a layer.  In 
    15 this case, the directory name should be used as the dataset name.  However, 
    16 it is also possible to use one of the files (<code>.txt</code>, <code>.gxt</code>) in a 
    17 G&eacute;oconcept files set as the dataset name, and then it will be treated as a dataset 
    18 with one layer.<p> 
     10G&eacute;oconcept text export files should be available for writing and reading.<p> 
     11 
     12The OGR G&eacute;oconcept driver treats a single G&eacute;oconcept file within 
     13a directory as a dataset comprising layers. 
     14G&eacute;oconcept files extensions are <code>.txt</code> or <code>.gxt</code>.<p> 
    1915 
    2016Currently the G&eacute;oconcept driver only supports multi-polygons, lines and 
    21 points.  <p> 
     17points.<p> 
    2218 
    2319<h2>Creation Issues</h2> 
    2420 
    25 The G&eacute;oconcept driver treats a directory as a dataset, and each 
    26 G&eacute;oconcept files set (.txt or .gxt) as a layer.  The dataset name 
    27 will be treated as a directory name.  If the directory already exists it 
    28 is used and existing files in the directory are ignored.  If the directory 
    29 does not exist it will be created (<span style="color:red;">EXPERIMENTAL</span>).<p> 
    30  
    31 As a special case attempts to create a new dataset with the extension .gxt 
    32 will result in a single file set being created instead of a directory.<p> 
    33  
    34 G&eacute;oconcept files can store multiple kinds of geometry, even if 
    35 a G&eacute;oconcept feature can only have one kind of geometry.<p> 
    36  
    37 Note tthis makes it very difficult to translate a mixed geometry layer 
     21The G&eacute;oconcept driver treats a G&eacute;oconcept file (<code>.txt</code> 
     22or <code>.gxt</code>) as a dataset.<p> 
     23 
     24G&eacute;oconcept files can store multiple kinds of geometry (one by layer), 
     25even if a G&eacute;oconcept layer can only have one kind of geometry.<p> 
     26 
     27Note this makes it very difficult to translate a mixed geometry layer 
    3828from another format into G&eacute;oconcept format using ogr2ogr, since ogr2ogr has 
    3929no support for separating out geometries from a source layer.<p> 
    4030 
    41 G&eacute;oconcept feature fields definition are stored in an associated .gct file, and so 
    42 fields suffer a number of limitations (<span style="color:red;">FIXME</span>)&nbsp;:<p> 
     31G&eacute;oconcept sub-type is treated as OGR feature. The name of a layer is therefore 
     32the concatenation of the G&eacute;oconcept type name, <code>'.'</code> and G&eacute;oconcept 
     33sub-type name.<p> 
     34 
     35G&eacute;oconcept type definition (<code>.gct</code> files) are used for creation only.<p> 
     36 
     37G&eacute;oconcept feature fields definition are stored in an associated <code>.gct</code> 
     38file, and so fields suffer a number of limitations (<span style="color:red;">FIXME</span>)&nbsp;:<p> 
    4339 
    4440<ul> 
     
    5147</ul> 
    5248 
    53 The OGR G&eacute;oconcept driver does not support reading existing G&eacute;oconcept 
    54 files as well as deleting features. <p>  
     49The OGR G&eacute;oconcept driver does not support deleting features. <p>  
    5550 
    5651<h3>Dataset Creation Options</h3> 
     
    124119</ul> 
    125120 
     121When this option is not used, the driver manage types and sub-types name based on either 
     122the layer name or on the use of <code>-nln</code> option.  
    126123</li> 
    127124 
     
    130127<h3>Layer Creation Options</h3> 
    131128 
    132 <b>FEATURETYPE=TYPE.SUBTYPE</b>&nbsp;: defines the feature to be created/appended. The <code>TYPE</code> 
     129<b>FEATURETYPE=TYPE.SUBTYPE</b>&nbsp;: defines the feature to be created. The <code>TYPE</code> 
    133130corresponds to one of the <code>Name</code> found in the GCT file for a type section. 
    134131The <code>SUBTYPE</code> corresponds to one of the <code>Name</code> found in the GCT file for a 
     
    212209 
    213210<pre> 
    214 //$DELIMITER "&#x9;" 
    215 //$QUOTED-TEXT "no" 
     211//$DELIMITER &quot;&#x9;&quot; 
     212//$QUOTED-TEXT &quot;no&quot; 
    216213//$CHARSET ANSI 
    217214//$UNIT Distance=m 
    218215//$FORMAT 2 
    219 //$SYSCOORD {Type: 9999
     216//$SYSCOORD {Type: 2001
    220217//$FIELDS Class=TILE;Subclass=TILE;Kind=4;Fields=Private#Identifier&#x9;Private#Class&#x9;Private#Subclass&#x9;Private#Name&#x9;Private#NbFields&#x9;IDSEL&#x9;NOM&#x9;WITHDATA&#x9;Private#X&#x9;Private#Y&#x9;Private#Graphics 
    221218-1&#x9;TILE&#x9;TILE&#x9;TILE&#x9;3&#x9;000-2007-0050-7130-LAMB93&#x9;&#x9;0&#x9;50000&#x9;7.13e+06&#x9;4&#x9;600000&#x9;7.13e+06&#x9;600000&#x9;6.58e+06&#x9;50000&#x9;6.58e+06&#x9;50000&#x9;7.13e+06 
     
    231228 
    232229<pre> 
    233 ogr2ogr -f "Geoconcept" -a_srs "+init=IGNF:LAMB93" -dsco EXTENSION=txt -dsco CONFIG=tile_schema.gct tile.gxt tile.shp -lco FEATURETYPE=TILE.TILE 
     230ogr2ogr -f &quot;Geoconcept&quot; -a_srs &quot;+init=IGNF:LAMB93&quot; -dsco EXTENSION=txt -dsco CONFIG=tile_schema.gct tile.gxt tile.shp -lco FEATURETYPE=TILE.TILE 
    234231</pre> 
    235232 
     
    237234 
    238235<pre> 
    239 ogr2ogr -f "Geoconcept" -update tile.gxt tile.shp -lco FEATURETYPE=TILE.TILE 
     236ogr2ogr -f &quot;Geoconcept&quot; -update -append tile.gxt tile.shp -nln TILE.TILE 
     237</pre> 
     238 
     239Translating a G&eacute;oconcept export file layer into MapInfo file&nbsp;:<br/> 
     240 
     241<pre> 
     242ogr2ogr -f &quot;MapInfo File&quot; -dsco FORMAT=MIF tile.mif tile.gxt TILE.TILE 
    240243</pre> 
    241244 
  • trunk/gdal/ogr/ogrsf_frmts/geoconcept/geoconcept.c

    r13483 r13555  
    4242#define UNDEFINEDID_GCIO 199901L 
    4343 
    44 #define  kIdentifier_GCIO         "@Identifier" 
    45 #define  kClass_GCIO              "@Class" 
    46 #define  kSubclass_GCIO           "@Subclass" 
    47 #define  kName_GCIO               "@Name" 
    48 #define  kNbFields_GCIO           "@NbFields" 
    49 #define  kX_GCIO                  "@X" 
    50 #define  kY_GCIO                  "@Y" 
    51 #define  kXP_GCIO                 "@XP" 
    52 #define  kYP_GCIO                 "@YP" 
    53 #define  kGraphics_GCIO           "@Graphics" 
    54 #define  kAngle_GCIO              "@Angle" 
     44static char* gkGCCharset[]= 
     45
     46/* 0 */ "", 
     47/* 1 */ "ANSI", 
     48/* 2 */ "DOS", 
     49/* 3 */ "MAC" 
     50}; 
    5551 
    5652static char* gkGCAccess[]= 
     
    114110  return b; 
    115111}/* _getHeaderValue_GCIO */ 
     112 
     113/* -------------------------------------------------------------------- */ 
     114const char GCIOAPI_CALL1(*) GCCharset2str_GCIO ( GCCharset cs ) 
     115{ 
     116  switch (cs) { 
     117  case vANSI_GCIO        : 
     118  case vDOS_GCIO         : 
     119  case vMAC_GCIO         : 
     120  case vWriteAccess_GCIO : 
     121    return gkGCCharset[cs]; 
     122  default                : 
     123    return gkGCCharset[vUnknownCharset_GCIO]; 
     124  } 
     125}/* GCCharset2str_GCIO */ 
     126 
     127/* -------------------------------------------------------------------- */ 
     128GCCharset GCIOAPI_CALL str2GCCharset_GCIO ( const char* s) 
     129{ 
     130  if (strcmp(s,gkGCCharset[vANSI_GCIO])==0) return vANSI_GCIO; 
     131  if (strcmp(s,gkGCCharset[vDOS_GCIO])==0) return vDOS_GCIO; 
     132  if (strcmp(s,gkGCCharset[vMAC_GCIO])==0) return vMAC_GCIO; 
     133  return vUnknownCharset_GCIO; 
     134}/* str2GCCharset_GCIO */ 
    116135 
    117136/* -------------------------------------------------------------------- */ 
     
    227246/* -------------------------------------------------------------------- */ 
    228247static long GCIOAPI_CALL _read_GCIO ( 
    229                                       GCExportFileH* hGXT, 
    230                                       const char* sep 
     248                                      GCExportFileH* hGXT 
    231249                                    ) 
    232250{ 
     
    239257  nread= 0L; 
    240258  result= GetGCCache_GCIO(hGXT); 
     259  SetGCCurrentOffset_GCIO(hGXT, VSIFTell(h));/* keep offset of beginning of lines */ 
    241260  while ((c= VSIFGetc(h))!=EOF) 
    242261  { 
     
    254273      if (nread==0L) continue; 
    255274      *result= '\0'; 
    256       SetGCCurrentOffset_GCIO(hGXT, VSIFTell(h)); 
    257275      return nread; 
    258276    default   : 
    259       if (sep && strchr(sep,c)!=NULL) 
    260       { 
    261         if (nread>0L) 
    262         { 
    263           VSIUngetc(c,h); 
    264           *result= '\0'; 
    265           SetGCCurrentOffset_GCIO(hGXT, VSIFTell(h)); 
    266           return nread; 
    267         } 
    268         *result= (char)c; 
    269         result++; 
    270         *result= '\0'; 
    271         SetGCCurrentOffset_GCIO(hGXT, VSIFTell(h)); 
    272         return 1L; 
    273       } 
    274277      *result= (char)c; 
    275278      result++; 
     
    278281  }/* while */ 
    279282  *result= '\0'; 
    280   SetGCCurrentOffset_GCIO(hGXT, VSIFTell(h)); 
    281283  if (c==EOF) 
    282284  { 
     
    307309    return GetGCCurrentOffset_GCIO(hGXT); 
    308310  } 
    309   if (_read_GCIO(hGXT,NULL)==EOF) 
     311  if (_read_GCIO(hGXT)==EOF) 
    310312  { 
    311313    SetGCWhatIs_GCIO(hGXT, vUnknownIO_ItemType_GCIO); 
     
    343345 
    344346/* -------------------------------------------------------------------- */ 
    345 static GCExtent GCIOAPI_CALL1(*) _CreateExtent_GCIO ( 
    346                                                       double Xmin, 
    347                                                       double Ymin, 
    348                                                       double Xmax, 
    349                                                       double Ymax 
    350                                                    
     347GCExtent GCIOAPI_CALL1(*) CreateExtent_GCIO ( 
     348                                              double Xmin, 
     349                                              double Ymin, 
     350                                              double Xmax, 
     351                                              double Ymax 
     352                                           
    351353{ 
    352354  GCExtent* theExtent; 
     
    366368 
    367369  return theExtent; 
    368 }/* _CreateExtent_GCIO */ 
     370}/* CreateExtent_GCIO */ 
    369371 
    370372/* -------------------------------------------------------------------- */ 
     
    377379 
    378380/* -------------------------------------------------------------------- */ 
    379 static void GCIOAPI_CALL _DestroyExtent_GCIO ( 
    380                                                GCExtent** theExtent 
    381                                             
     381void GCIOAPI_CALL DestroyExtent_GCIO ( 
     382                                       GCExtent** theExtent 
     383                                     
    382384{ 
    383385  _ReInitExtent_GCIO(*theExtent); 
    384386  CPLFree(*theExtent); 
    385387  *theExtent= NULL; 
    386 }/* _DestroyExtent_GCIO */ 
     388}/* DestroyExtent_GCIO */ 
    387389 
    388390/* -------------------------------------------------------------------- */ 
     
    568570                                           ) 
    569571{ 
     572  SetSubTypeGCHandle_GCIO(theSubType, NULL); 
    570573  SetSubTypeType_GCIO(theSubType, NULL); 
    571574  SetSubTypeName_GCIO(theSubType, NULL); 
     
    575578  SetSubTypeDim_GCIO(theSubType, v2D_GCIO); 
    576579  SetSubTypeNbFields_GCIO(theSubType, -1); 
     580  SetSubTypeNbFeatures_GCIO(theSubType, 0L); 
     581  SetSubTypeBOF_GCIO(theSubType, -1L); 
     582  SetSubTypeBOFLinenum_GCIO(theSubType, 0L); 
     583  SetSubTypeExtent_GCIO(theSubType, NULL); 
    577584}/* _InitSubType_GCIO */ 
    578585 
     
    632639    CPLFree( GetSubTypeName_GCIO(theSubType) ); 
    633640  } 
     641  if( GetSubTypeExtent_GCIO(theSubType) ) 
     642  { 
     643    DestroyExtent_GCIO(&(GetSubTypeExtent_GCIO(theSubType))); 
     644  } 
    634645  _InitSubType_GCIO(theSubType); 
    635646}/* _ReInitSubType_GCIO */ 
     
    659670    if( (n= CPLListCount(GetTypeSubtypes_GCIO(theClass)))>0 ) 
    660671    { 
     672      if( *subtypName=='*' ) return 0; 
    661673      for( i = 0; i < n; i++) 
    662674      { 
     
    801813    if( (n= CPLListCount(GetMetaTypes_GCIO(header)))>0 ) 
    802814    { 
     815      if( *typName=='*' ) return 0; 
    803816      for( i = 0; i < n; i++) 
    804817      { 
     
    839852  SetMetaDelimiter_GCIO(header, kTAB_GCIO[0]); 
    840853  SetMetaQuotedText_GCIO(header, FALSE); 
    841   SetMetaCharset_GCIO(header, "ANSI");/* FIXME */ 
     854  SetMetaCharset_GCIO(header, vANSI_GCIO); 
    842855  SetMetaUnit_GCIO(header, "m"); 
    843   SetMetaZUnit_GCIO(header,"m"); 
    844856  SetMetaFormat_GCIO(header, 2); 
    845   SetMetaSysCoord_GCIO(header, -1); 
     857  SetMetaSysCoord_GCIO(header, NULL); /* GCSysCoord */ 
     858  SetMetaSRS_GCIO(header, NULL); 
    846859  SetMetaTypes_GCIO(header, NULL); /* GCType */ 
    847860  SetMetaFields_GCIO(header, NULL); /* GCField */ 
    848861  SetMetaResolution_GCIO(header, 0.1); 
    849   SetMetaZResolution_GCIO(header, -1.0); 
    850862  SetMetaExtent_GCIO(header, NULL); 
    851863}/* _InitHeader_GCIO */ 
    852864 
    853865/* -------------------------------------------------------------------- */ 
    854 static GCExportFileMetadata GCIOAPI_CALL1(*) _CreateHeader_GCIO ( ) 
     866GCExportFileMetadata GCIOAPI_CALL1(*) CreateHeader_GCIO ( ) 
    855867{ 
    856868  GCExportFileMetadata* m; 
     
    865877 
    866878  return m; 
    867 }/* _CreateHeader_GCIO */ 
     879}/* CreateHeader_GCIO */ 
    868880 
    869881/* -------------------------------------------------------------------- */ 
     
    874886  if( GetMetaExtent_GCIO(header) ) 
    875887  { 
    876     _DestroyExtent_GCIO(&(GetMetaExtent_GCIO(header))); 
     888    DestroyExtent_GCIO(&(GetMetaExtent_GCIO(header))); 
    877889  } 
    878890  if( GetMetaTypes_GCIO(header) ) 
     
    916928    CPLListDestroy(GetMetaFields_GCIO(header)); 
    917929  } 
     930  if( GetMetaSRS_GCIO(header) ) 
     931  { 
     932    if( OSRDereference( GetMetaSRS_GCIO(header) )==0 ) 
     933      OSRDestroySpatialReference( GetMetaSRS_GCIO(header) ); 
     934  } 
     935  if( GetMetaSysCoord_GCIO(header) ) 
     936  { 
     937    DestroySysCoord_GCSRS(&(GetMetaSysCoord_GCIO(header))); 
     938  } 
    918939 
    919940  _InitHeader_GCIO(header); 
     
    921942 
    922943/* -------------------------------------------------------------------- */ 
    923 static void GCIOAPI_CALL _DestroyHeader_GCIO ( 
    924                                                GCExportFileMetadata** m 
    925                                             
     944void GCIOAPI_CALL DestroyHeader_GCIO ( 
     945                                       GCExportFileMetadata** m 
     946                                     
    926947{ 
    927948  _ReInitHeader_GCIO(*m); 
    928949  CPLFree(*m); 
    929950  *m= NULL; 
    930 }/* _DestroyHeader_GCIO */ 
     951}/* DestroyHeader_GCIO */ 
    931952 
    932953/* -------------------------------------------------------------------- */ 
     
    958979  GCExportFileH* hGXT; 
    959980 
    960   /* Not yet implemented : */ 
    961   if( mode[0]=='r') 
    962   { 
    963     CPLError( CE_Failure, CPLE_NotSupported, 
    964               "opening a Geoconcept file '%s' for reading is not yet supported.\n", 
    965               pszGeoconceptFile); 
    966     return NULL; 
    967   } 
    968  
    969981  if( !(hGXT= CPLMalloc(sizeof(GCExportFileH)) ) ) 
    970982  { 
     
    9911003  if( GetGCMeta_GCIO(hGXT) ) 
    9921004  { 
    993     _DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT))); 
     1005    DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT))); 
    9941006  } 
    9951007  if( GetGCHandle_GCIO(hGXT) ) 
     
    10151027/* -------------------------------------------------------------------- */ 
    10161028static void GCIOAPI_CALL _Destroy_GCIO ( 
    1017                                          GCExportFileH** hGXT 
     1029                                         GCExportFileH** hGXT, 
     1030                                         int delFile 
    10181031                                       ) 
    10191032{ 
     1033  if( delFile && GetGCMode_GCIO(*hGXT)==vWriteAccess_GCIO ) 
     1034  { 
     1035    VSIFClose(GetGCHandle_GCIO(*hGXT)); 
     1036    SetGCHandle_GCIO(*hGXT, NULL); 
     1037    VSIUnlink(CPLFormFilename(GetGCPath_GCIO(*hGXT),GetGCBasename_GCIO(*hGXT),GetGCExtension_GCIO(*hGXT))); 
     1038  } 
    10201039  _ReInit_GCIO(*hGXT); 
    10211040  CPLFree(*hGXT); 
     
    10351054  CPLList* e; 
    10361055 
    1037   Meta= GetGCMeta_GCIO(hGXT); 
     1056  if( !(Meta= GetGCMeta_GCIO(hGXT)) ) 
     1057  { 
     1058    return TRUE; /* FIXME */ 
     1059  } 
    10381060  if( (nT= CPLListCount(GetMetaTypes_GCIO(Meta)))==0 ) 
    10391061  { 
     
    12661288              } 
    12671289              SetSubTypeNbFields_GCIO(theSubType,nU); 
     1290              SetSubTypeGCHandle_GCIO(theSubType,hGXT); 
    12681291            } 
    12691292          } 
     
    12751298  return TRUE; 
    12761299}/* _checkSchema_GCIO */ 
     1300 
     1301/* -------------------------------------------------------------------- */ 
     1302static OGRGeometryH GCIOAPI_CALL _buildOGRGeometry_GCIO ( 
     1303                                                          GCExportFileMetadata* Meta, 
     1304                                                          GCSubType* theSubType, 
     1305                                                          int i, 
     1306                                                          const char** pszFields, 
     1307                                                          int nbtp, 
     1308                                                          GCDim d 
     1309                                                        ) 
     1310{ 
     1311  OGRGeometryH g; 
     1312  OGRwkbGeometryType gt; 
     1313  double x, y, z; 
     1314  int ip, np; 
     1315 
     1316  g= NULL; 
     1317  x= y= z= 0.0; 
     1318  switch( GetSubTypeKind_GCIO(theSubType) ) 
     1319  { 
     1320    case vPoint_GCIO : 
     1321      gt= wkbPoint; 
     1322      break; 
     1323    case vLine_GCIO  : 
     1324      gt= wkbLineString; 
     1325      break; 
     1326    case vPoly_GCIO  : 
     1327      gt= wkbMultiPolygon; 
     1328      break; 
     1329    case vText_GCIO  : 
     1330    default          : 
     1331      gt= wkbUnknown; 
     1332      break; 
     1333  } 
     1334  if( !(g= OGR_G_CreateGeometry(gt)) ) 
     1335  { 
     1336    return NULL; 
     1337  } 
     1338  OGR_G_SetCoordinateDimension(g,d==v3D_GCIO||d==v3DM_GCIO? 3:2); 
     1339  if( !GetMetaSRS_GCIO(Meta) && GetMetaSysCoord_GCIO(Meta) ) 
     1340  { 
     1341    SetMetaSRS_GCIO(Meta, SysCoord2OGRSpatialReference_GCSRS(GetMetaSysCoord_GCIO(Meta))); 
     1342    OSRReference( GetMetaSRS_GCIO(Meta) ); 
     1343  } 
     1344  if( GetMetaSRS_GCIO(Meta) ) 
     1345  { 
     1346    OGR_G_AssignSpatialReference(g,GetMetaSRS_GCIO(Meta)); 
     1347  } 
     1348 
     1349  /* 
     1350   * General structure : 
     1351   * X<>Y[<>Z]{<>More Graphics} 
     1352   */ 
     1353 
     1354  if( gt==wkbPoint ) 
     1355  { 
     1356    /* 
     1357     * More Graphics : 
     1358     * Angle 
     1359     * Angle in tenth of degrees (counterclockwise) of the symbol 
     1360     * displayed to represent the ponctual entity or angle of the text entity 
     1361     * NOT IMPLEMENTED 
     1362     */ 
     1363    x= CPLAtof(pszFields[i]), i++; 
     1364    y= CPLAtof(pszFields[i]), i++; 
     1365    if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1366    { 
     1367      z= CPLAtof(pszFields[i]), i++; 
     1368    } 
     1369    OGR_G_AddPoint(g,x,y,z); 
     1370    return g; 
     1371  } 
     1372 
     1373  if( gt==wkbLineString ) 
     1374  { 
     1375    /* 
     1376     * More Graphics : 
     1377     * XP<>YP[<>ZP]Nr points=k[<>X<>Y[<>Z]]k... 
     1378     */ 
     1379    x= CPLAtof(pszFields[i]), i++; 
     1380    y= CPLAtof(pszFields[i]), i++; 
     1381    if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1382    { 
     1383      z= CPLAtof(pszFields[i]), i++; 
     1384    } 
     1385    OGR_G_AddPoint(g,x,y,z); 
     1386    /* skip XP<>YP[<>ZP] : the last point is in k[<>X<>Y[<>Z]]k */ 
     1387    i++; 
     1388    i++; 
     1389    if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1390    { 
     1391      i++; 
     1392    } 
     1393    np= atoi(pszFields[i]), i++; 
     1394    for( ip= 1; ip<=np; ip++ ) 
     1395    { 
     1396      x= CPLAtof(pszFields[i]), i++; 
     1397      y= CPLAtof(pszFields[i]), i++; 
     1398      if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1399      { 
     1400        z= CPLAtof(pszFields[i]), i++; 
     1401      } 
     1402      OGR_G_AddPoint(g,x,y,z); 
     1403    } 
     1404    return g; 
     1405  } 
     1406 
     1407  if( gt==wkbMultiPolygon ) 
     1408  { 
     1409    /* 
     1410     * More Graphics : 
     1411     * {Single Polygon{<>NrPolys=j[<>X<>Y[<>Z]<>Single Polygon]j}} 
     1412     * with Single Polygon : 
     1413     * Nr points=k[<>X<>Y[<>Z]]k... 
     1414     */ 
     1415    CPLList* Lpo, *e; 
     1416    OGRGeometryH outer, ring; 
     1417    int npo, ipo, ilpo; 
     1418 
     1419 
     1420    Lpo= NULL; 
     1421    if( !(outer= OGR_G_CreateGeometry(wkbPolygon)) ) 
     1422    { 
     1423      goto onError; 
     1424    } 
     1425    OGR_G_SetCoordinateDimension(outer,d==v3D_GCIO||v3DM_GCIO? 3:2); 
     1426    if( GetMetaSRS_GCIO(Meta) ) 
     1427    { 
     1428      OGR_G_AssignSpatialReference(outer,GetMetaSRS_GCIO(Meta)); 
     1429    } 
     1430    if( !(ring= OGR_G_CreateGeometry(wkbLinearRing)) ) 
     1431    { 
     1432      OGR_G_DestroyGeometry(outer); 
     1433      goto onError; 
     1434    } 
     1435    OGR_G_SetCoordinateDimension(ring,d==v3D_GCIO||v3DM_GCIO? 3:2); 
     1436    if( GetMetaSRS_GCIO(Meta) ) 
     1437    { 
     1438      OGR_G_AssignSpatialReference(ring,GetMetaSRS_GCIO(Meta)); 
     1439    } 
     1440    x= CPLAtof(pszFields[i]), i++; 
     1441    y= CPLAtof(pszFields[i]), i++; 
     1442    if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1443    { 
     1444      z= CPLAtof(pszFields[i]), i++; 
     1445    } 
     1446    OGR_G_AddPoint(ring,x,y,z); 
     1447    np= atoi(pszFields[i]), i++; 
     1448    for( ip= 1; ip<=np; ip++ ) 
     1449    { 
     1450      x= CPLAtof(pszFields[i]), i++; 
     1451      y= CPLAtof(pszFields[i]), i++; 
     1452      if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1453      { 
     1454        z= CPLAtof(pszFields[i]), i++; 
     1455      } 
     1456      OGR_G_AddPoint(ring,x,y,z); 
     1457    } 
     1458    OGR_G_AddGeometryDirectly(outer,ring); 
     1459    if( (Lpo= CPLListAppend(Lpo,outer))==NULL ) 
     1460    { 
     1461      CPLError( CE_Failure, CPLE_OutOfMemory, 
     1462                "failed to add a polygon to subtype '%s.%s'.\n", 
     1463                GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)),  
     1464                GetSubTypeName_GCIO(theSubType) ); 
     1465      OGR_G_DestroyGeometry(outer); 
     1466      goto onError; 
     1467    } 
     1468    /* additionnal ring : either holes, or islands */ 
     1469    if( i < nbtp-1 ) 
     1470    { 
     1471      npo= atoi(pszFields[i]), i++; 
     1472      for( ipo= 1; ipo<=npo; ipo++ ) 
     1473      { 
     1474        if( !(ring= OGR_G_CreateGeometry(wkbLinearRing)) ) 
     1475        { 
     1476          goto onError; 
     1477        } 
     1478        OGR_G_SetCoordinateDimension(ring,d==v3D_GCIO||v3DM_GCIO? 3:2); 
     1479        if( GetMetaSRS_GCIO(Meta) ) 
     1480        { 
     1481          OGR_G_AssignSpatialReference(ring,GetMetaSRS_GCIO(Meta)); 
     1482        } 
     1483        x= CPLAtof(pszFields[i]), i++; 
     1484        y= CPLAtof(pszFields[i]), i++; 
     1485        if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1486        { 
     1487          z= CPLAtof(pszFields[i]), i++; 
     1488        } 
     1489        OGR_G_AddPoint(ring,x,y,z); 
     1490        np= atoi(pszFields[i]), i++; 
     1491        for( ip= 1; ip<=np; ip++ ) 
     1492        { 
     1493          x= CPLAtof(pszFields[i]), i++; 
     1494          y= CPLAtof(pszFields[i]), i++; 
     1495          if( d==v3D_GCIO || d==v3DM_GCIO ) 
     1496          { 
     1497            z= CPLAtof(pszFields[i]), i++; 
     1498          } 
     1499          OGR_G_AddPoint(ring,x,y,z); 
     1500        } 
     1501        /* is the ring of hole or another polygon ? */ 
     1502        for( ilpo= 0; ilpo<CPLListCount(Lpo); ilpo++) 
     1503        { 
     1504          if( (e= CPLListGet(Lpo,ilpo)) ) 
     1505          { 
     1506            if( (outer= (OGRGeometryH)CPLListGetData(e)) ) 
     1507            { 
     1508              if( OGR_G_Contains(outer,ring) ) 
     1509              { 
     1510                OGR_G_AddGeometryDirectly(outer,ring); 
     1511                ring= NULL; 
     1512                break; 
     1513              } 
     1514            } 
     1515          } 
     1516        } 
     1517        if( !ring ) 
     1518        { 
     1519          /* new polygon */ 
     1520          if( !(outer= OGR_G_CreateGeometry(wkbPolygon)) ) 
     1521          { 
     1522            OGR_G_DestroyGeometry(ring); 
     1523            goto onError; 
     1524          } 
     1525          OGR_G_SetCoordinateDimension(outer,d==v3D_GCIO||v3DM_GCIO? 3:2); 
     1526          if( GetMetaSRS_GCIO(Meta) ) 
     1527          { 
     1528            OGR_G_AssignSpatialReference(outer,GetMetaSRS_GCIO(Meta)); 
     1529          } 
     1530          OGR_G_AddGeometryDirectly(outer,ring); 
     1531          if( (Lpo= CPLListAppend(Lpo,outer))==NULL ) 
     1532          { 
     1533            CPLError( CE_Failure, CPLE_OutOfMemory, 
     1534                      "failed to add a polygon to subtype '%s.%s'.\n", 
     1535                      GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)), 
     1536                      GetSubTypeName_GCIO(theSubType) ); 
     1537            OGR_G_DestroyGeometry(outer); 
     1538            goto onError; 
     1539          } 
     1540        } 
     1541      } 
     1542    } 
     1543    if( Lpo ) 
     1544    { 
     1545      if( (npo= CPLListCount(Lpo))>0 ) 
     1546      { 
     1547        for (ipo= 0; ipo<npo; ipo++) 
     1548        { 
     1549          if( (e= CPLListGet(Lpo,ipo)) ) 
     1550          { 
     1551            if( (outer= (OGRGeometryH)CPLListGetData(e)) ) 
     1552            { 
     1553              OGR_G_AddGeometryDirectly(g,outer); 
     1554            } 
     1555          } 
     1556        } 
     1557      } 
     1558      CPLListDestroy(Lpo); 
     1559    } 
     1560    return g; 
     1561 
     1562onError: 
     1563    if( Lpo ) 
     1564    { 
     1565      if( (npo= CPLListCount(Lpo))>0 ) 
     1566      { 
     1567        for (ipo= 0; ipo<npo; ipo++) 
     1568        { 
     1569          if( (e= CPLListGet(Lpo,ipo)) ) 
     1570          { 
     1571            if( (outer= (OGRGeometryH)CPLListGetData(e)) ) 
     1572            { 
     1573              OGR_G_DestroyGeometry(outer); 
     1574            } 
     1575          } 
     1576        } 
     1577      } 
     1578      CPLListDestroy(Lpo); 
     1579    } 
     1580    if( g ) OGR_G_DestroyGeometry(g); 
     1581  } 
     1582 
     1583  return NULL; 
     1584}/* _buildOGRGeometry_GCIO */ 
     1585 
     1586/* -------------------------------------------------------------------- */ 
     1587static OGRFeatureH GCIOAPI_CALL _buildOGRFeature_GCIO ( 
     1588                                                        GCExportFileH* H, 
     1589                                                        GCSubType** theSubType, 
     1590                                                        GCDim d 
     1591                                                      ) 
     1592{ 
     1593  GCExportFileMetadata* Meta; 
     1594  char **pszFields, delim[2], tdst[kItemSize_GCIO]; 
     1595  int whereClass, whereSubType, i, j, nbf, nbtf; 
     1596  GCType* theClass; 
     1597  GCField* theField; 
     1598  OGRFieldDefnH fld; 
     1599  OGRFeatureDefnH fd; 
     1600  OGRFeatureH f; 
     1601  OGRGeometryH g; 
     1602 
     1603  fd= NULL; 
     1604  f= NULL; 
     1605  Meta= GetGCMeta_GCIO(H); 
     1606  delim[0]= GetMetaDelimiter_GCIO(Meta); 
     1607  delim[1]= '\0'; 
     1608  if( d==vUnknown3D_GCIO) d= v2D_GCIO; 
     1609  /* due to the order of fields, we know how to proceed : */ 
     1610  /* A.- Line syntax :                                    */ 
     1611  /* Object internal identifier <delimiter>               */ 
     1612  /* Class <delimiter>                                    */ 
     1613  /* Subclass <delimiter>                                 */ 
     1614  /* Name <delimiter>                                     */ 
     1615  /* NbFields <delimiter>                                 */ 
     1616  /* User's field <delimiter> [0..N]                      */ 
     1617  /* Graphics                                             */ 
     1618  /* Graphics depends on the Kind of the                  */ 
     1619  /* B.- Algorithm :                                      */ 
     1620  /*  1.- Get Class                                       */ 
     1621  /*  2.- Get Subclass                                    */ 
     1622  /*  3.- Find feature in schema                          */ 
     1623  /*  4.- Get Kind                                        */ 
     1624  /*  5.- Get NbFields                                    */ 
     1625  /*  6.- Get Geometry as 5+NbFields field                */ 
     1626  /*  7.- Parse Geometry and build OGRGeometryH           */ 
     1627  /*  8.- Compute extent and update file extent           */ 
     1628  /*   9.- increment number of features                   */ 
     1629  /* FIXME : add index when reading feature to            */ 
     1630  /*         allow direct access !                        */ 
     1631  if( !(pszFields= CSLTokenizeStringComplex(GetGCCache_GCIO(H), 
     1632                                            delim, 
     1633                                            GetMetaQuotedText_GCIO(Meta), 
     1634                                            TRUE)) ) 
     1635  { 
     1636    CPLError( CE_Failure, CPLE_AppDefined, 
     1637              "Line %ld, Geoconcept line syntax is incorrect.\n", 
     1638              GetGCCurrentLinenum_GCIO(H) ); 
     1639    return NULL; 
     1640  } 
     1641  if( (nbtf= CSLCount(pszFields)) <= 5 ) 
     1642  { 
     1643    CPLError( CE_Failure, CPLE_AppDefined, 
     1644              "Line %ld, Missing fields.\n", 
     1645              GetGCCurrentLinenum_GCIO(H) ); 
     1646    return NULL; 
     1647  } 
     1648  if( (whereClass = _findTypeByName_GCIO(H,pszFields[1]))==-1 ) 
     1649  { 
     1650    CPLError( CE_Failure, CPLE_AppDefined, 
     1651              "Line %ld, Unknown type '%s'.\n", 
     1652              GetGCCurrentLinenum_GCIO(H), pszFields[1] ); 
     1653    return NULL; 
     1654  } 
     1655  theClass= _getType_GCIO(H,whereClass); 
     1656  if( *theSubType ) 
     1657  { 
     1658    /* reading ... */ 
     1659    if( !EQUAL(GetTypeName_GCIO(GetSubTypeType_GCIO(*theSubType)),GetTypeName_GCIO(theClass)) ) 
     1660    { 
     1661      return NULL; 
     1662    } 
     1663  } 
     1664  if( (whereSubType= _findSubTypeByName_GCIO(theClass,pszFields[2]))==-1 ) 
     1665  { 
     1666    CPLError( CE_Failure, CPLE_AppDefined, 
     1667              "Line %ld, Unknown subtype found '%s' for type '%s'.\n", 
     1668              GetGCCurrentLinenum_GCIO(H), pszFields[2], pszFields[1] ); 
     1669    return NULL; 
     1670  } 
     1671  if( *theSubType ) 
     1672  { 
     1673    if( !EQUAL(GetSubTypeName_GCIO(_getSubType_GCIO(theClass,whereSubType)),GetSubTypeName_GCIO(*theSubType)) ) 
     1674    { 
     1675      return NULL; 
     1676    } 
     1677  } 
     1678  else 
     1679  { 
     1680    *theSubType= _getSubType_GCIO(theClass,whereSubType); 
     1681  } 
     1682  snprintf(tdst, kItemSize_GCIO-1, "%s.%s", GetTypeName_GCIO(theClass), GetSubTypeName_GCIO(*theSubType)); 
     1683  tdst[kItemSize_GCIO-1]= '\0'; 
     1684  if( _findFieldByName_GCIO(GetSubTypeFields_GCIO(*theSubType),kName_GCIO)!=-1 ) 
     1685  { 
     1686    nbf= 4; 
     1687  } 
     1688  else 
     1689  { 
     1690    nbf= 3; 
     1691  } 
     1692  if( atoi(pszFields[nbf])!=GetSubTypeNbFields_GCIO(*theSubType) ) 
     1693  { 
     1694    CPLError( CE_Failure, CPLE_AppDefined, 
     1695              "Line %ld, Number of user's fields differs with type definition '%s' (%d found, %d expected).\n", 
     1696              GetGCCurrentLinenum_GCIO(H), tdst, atoi(pszFields[nbf]), GetSubTypeNbFields_GCIO(*theSubType) ); 
     1697    return NULL; 
     1698  } 
     1699  if( !(fd= OGR_FD_Create(tdst)) ) 
     1700  { 
     1701    return NULL; 
     1702  } 
     1703  OGR_FD_Reference(fd);/* FIXME ? */ 
     1704  switch( GetSubTypeKind_GCIO(*theSubType) ) 
     1705  { 
     1706    case vPoint_GCIO : 
     1707      OGR_FD_SetGeomType(fd,wkbPoint); 
     1708      break; 
     1709    case vLine_GCIO  : 
     1710      OGR_FD_SetGeomType(fd,wkbLineString); 
     1711      break; 
     1712    case vPoly_GCIO  : 
     1713      OGR_FD_SetGeomType(fd,wkbMultiPolygon); 
     1714      break; 
     1715    case vText_GCIO  : 
     1716    default          : 
     1717      OGR_FD_Dereference(fd); 
     1718      OGR_FD_Destroy(fd); 
     1719      CPLError( CE_Failure, CPLE_NotSupported, 
     1720                "Unknown Geoconcept type for '%s'.\n", 
     1721                tdst ); 
     1722      return NULL; 
     1723  } 
     1724  if( nbtf < 1 + nbf + GetSubTypeNbFields_GCIO(*theSubType) + 1) 
     1725  { 
     1726    OGR_FD_Destroy(fd); 
     1727    CPLError( CE_Failure, CPLE_AppDefined, 
     1728              "Line %ld, Missing fields.\n", 
     1729              GetGCCurrentLinenum_GCIO(H) ); 
     1730    return NULL; 
     1731  } 
     1732  for( i= 1 + nbf; i<1 + nbf + GetSubTypeNbFields_GCIO(*theSubType); i++ ) 
     1733  { 
     1734    theField= GetSubTypeField_GCIO(*theSubType,i); 
     1735    if( !(fld= OGR_Fld_Create(GetFieldName_GCIO(theField),OFTString)) ) /* FIXME */ 
     1736    { 
     1737      OGR_FD_Destroy(fd); 
     1738      return NULL; 
     1739    } 
     1740    OGR_FD_AddFieldDefn(fd,fld); 
     1741  } 
     1742  if( !(f= OGR_F_Create(fd)) ) 
     1743  { 
     1744    OGR_FD_Destroy(fd); 
     1745    return NULL; 
     1746  } 
     1747  OGR_F_SetFID(f, atol(pszFields[0])); /* FID */ 
     1748  for( i= 1 + nbf, j= 0; i<1 + nbf + GetSubTypeNbFields_GCIO(*theSubType); i++, j++ ) 
     1749  { 
     1750    theField= GetSubTypeField_GCIO(*theSubType,i); 
     1751    if( pszFields[i][0]=='\0' ) 
     1752      OGR_F_UnsetField(f,j); 
     1753    else 
     1754      OGR_F_SetFieldString(f,j,pszFields[i]); 
     1755  } 
     1756  if( !(g= _buildOGRGeometry_GCIO(Meta,*theSubType,i,(const char **)pszFields,nbtf,d)) ) 
     1757  { 
     1758    OGR_F_Destroy(f); 
     1759    return NULL; 
     1760  } 
     1761  if( OGR_F_SetGeometryDirectly(f,g)!=OGRERR_NONE ) 
     1762  { 
     1763    OGR_F_Destroy(f); 
     1764    return NULL; 
     1765  } 
     1766  CSLDestroy(pszFields); 
     1767 
     1768  return f; 
     1769}/* _buildOGRFeature_GCIO */ 
     1770 
     1771/* -------------------------------------------------------------------- */ 
     1772static GCExportFileMetadata GCIOAPI_CALL1(*) _completeHeader_GCIO ( 
     1773                                                                    GCExportFileH* H 
     1774                                                                  ) 
     1775{ 
     1776  GCExportFileMetadata* Meta; 
     1777  GCSubType* theSubType; 
     1778  OGRFeatureH f; 
     1779  GCDim d; 
     1780  long coff; 
     1781  OGREnvelope bbox; 
     1782 
     1783  if( (Meta= GetGCMeta_GCIO(H))==NULL ) 
     1784  { 
     1785    return NULL; 
     1786  } 
     1787  SetMetaExtent_GCIO(Meta, CreateExtent_GCIO(HUGE_VAL,HUGE_VAL,-HUGE_VAL,-HUGE_VAL)); 
     1788  bbox.MinX= HUGE_VAL; 
     1789  bbox.MaxX= -HUGE_VAL; 
     1790  bbox.MinY= HUGE_VAL; 
     1791  bbox.MaxY= -HUGE_VAL; 
     1792 
     1793  d= vUnknown3D_GCIO; 
     1794  theSubType= NULL; 
     1795  coff= -1L; 
     1796  while( _get_GCIO(H)!=EOF ) 
     1797  { 
     1798    if( GetGCWhatIs_GCIO(H)==vComType_GCIO ) 
     1799    { 
     1800      continue; 
     1801    } 
     1802    /* analyze the line according to schema : */ 
     1803    if( GetGCWhatIs_GCIO(H)==vPragma_GCIO ) 
     1804    { 
     1805      if( strstr(GetGCCache_GCIO(H),k3DOBJECTMONO_GCIO) ) 
     1806      { 
     1807        d= v3DM_GCIO; 
     1808        coff= GetGCCurrentOffset_GCIO(H); 
     1809      } 
     1810      else if( strstr(GetGCCache_GCIO(H),k3DOBJECT_GCIO) ) 
     1811      { 
     1812        d= v3D_GCIO; 
     1813        coff= GetGCCurrentOffset_GCIO(H); 
     1814      } 
     1815      else if( strstr(GetGCCache_GCIO(H),k2DOBJECT_GCIO) ) 
     1816      { 
     1817        d= v2D_GCIO; 
     1818        coff= GetGCCurrentOffset_GCIO(H); 
     1819      } 
     1820      continue; 
     1821    } 
     1822    if( coff==-1L) coff= GetGCCurrentOffset_GCIO(H); 
     1823    if( !(f= _buildOGRFeature_GCIO(H,&theSubType,d)) ) 
     1824    { 
     1825      return NULL; 
     1826    } 
     1827    if( GetSubTypeBOF_GCIO(theSubType)==-1L ) 
     1828    { 
     1829      SetSubTypeBOF_GCIO(theSubType,coff);/* Begin Of Features for the Class.Subclass */ 
     1830      SetSubTypeBOFLinenum_GCIO(theSubType, GetGCCurrentLinenum_GCIO(H)); 
     1831    } 
     1832    SetSubTypeNbFeatures_GCIO(theSubType, GetSubTypeNbFeatures_GCIO(theSubType)+1L); 
     1833    SetGCNbObjects_GCIO(H,GetGCNbObjects_GCIO(H)+1L); 
     1834    OGR_G_GetEnvelope(OGR_F_GetGeometryRef(f),&bbox); 
     1835    /* update bbox of both feature and file */ 
     1836    SetExtentULAbscissa_GCIO(GetMetaExtent_GCIO(Meta),bbox.MinX); 
     1837    SetExtentULOrdinate_GCIO(GetMetaExtent_GCIO(Meta),bbox.MaxY); 
     1838    SetExtentLRAbscissa_GCIO(GetMetaExtent_GCIO(Meta),bbox.MaxX); 
     1839    SetExtentLROrdinate_GCIO(GetMetaExtent_GCIO(Meta),bbox.MinY); 
     1840    if( !GetSubTypeExtent_GCIO(theSubType) ) 
     1841    { 
     1842      SetSubTypeExtent_GCIO(theSubType, CreateExtent_GCIO(HUGE_VAL,HUGE_VAL,-HUGE_VAL,-HUGE_VAL)); 
     1843    } 
     1844    SetExtentULAbscissa_GCIO(GetSubTypeExtent_GCIO(theSubType),bbox.MinX); 
     1845    SetExtentULOrdinate_GCIO(GetSubTypeExtent_GCIO(theSubType),bbox.MaxY); 
     1846    SetExtentLRAbscissa_GCIO(GetSubTypeExtent_GCIO(theSubType),bbox.MaxX); 
     1847    SetExtentLROrdinate_GCIO(GetSubTypeExtent_GCIO(theSubType),bbox.MinY); 
     1848    if( d==vUnknown3D_GCIO && GetSubTypeDim_GCIO(theSubType)==vUnknown3D_GCIO ) 
     1849    { 
     1850      switch( OGR_G_GetCoordinateDimension(OGR_F_GetGeometryRef(f)) ) 
     1851      { 
     1852        case 3  : 
     1853          SetSubTypeDim_GCIO(theSubType,v3D_GCIO); 
     1854          break; 
     1855        case 2  : 
     1856        default : <