LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/ili - ili1reader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 461 3 0.7 %
Date: 2011-12-18 Functions: 29 1 3.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: ili1reader.cpp 20142 2010-07-27 18:43:49Z rouault $
       3                 :  *
       4                 :  * Project:  Interlis 1 Reader
       5                 :  * Purpose:  Implementation of ILI1Reader class.
       6                 :  * Author:   Pirmin Kalberer, Sourcepole AG
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
      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 "ogr_ili1.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "ogr_api.h"
      34                 : #include "ogr_geos.h"
      35                 : 
      36                 : #include "ilihelper.h"
      37                 : #include "iomhelper.h"
      38                 : #include "ili1reader.h"
      39                 : #include "ili1readerp.h"
      40                 : 
      41                 : #include <vector>
      42                 : 
      43                 : #ifdef HAVE_GEOS
      44                 : #  define POLYGONIZE_AREAS
      45                 : #endif
      46                 : 
      47                 : #ifndef POLYGONIZE_AREAS
      48                 : #  if defined(__GNUC_PREREQ)
      49                 : #    warning Interlis 1 Area polygonizing disabled. Needs GEOS >= 2.1.0
      50                 : #  endif
      51                 : #endif
      52                 : 
      53                 : CPL_CVSID("$Id: ili1reader.cpp 20142 2010-07-27 18:43:49Z rouault $");
      54                 : 
      55                 : 
      56                 : //
      57                 : // ILI1Reader
      58                 : //
      59               0 : IILI1Reader::~IILI1Reader() {
      60               0 : }
      61                 : 
      62               0 : ILI1Reader::ILI1Reader() {
      63               0 :   fpItf = NULL;
      64               0 :   nLayers = 0;
      65               0 :   papoLayers = NULL;
      66               0 :   curLayer = NULL;
      67               0 :   metaLayer = NULL;
      68               0 :   SetArcDegrees(1);
      69               0 : }
      70                 : 
      71               0 : ILI1Reader::~ILI1Reader() {
      72                 :  int i;
      73               0 :  if (fpItf) VSIFClose( fpItf );
      74                 : 
      75               0 :  for(i=0;i<nLayers;i++)
      76               0 :      delete papoLayers[i];
      77               0 :  CPLFree(papoLayers);
      78               0 : }
      79                 : 
      80               0 : void ILI1Reader::SetArcDegrees(double arcDegrees) {
      81               0 :   arcIncr = arcDegrees*PI/180;
      82               0 : }
      83                 : 
      84                 : /* -------------------------------------------------------------------- */
      85                 : /*      Open the source file.                                           */
      86                 : /* -------------------------------------------------------------------- */
      87               0 : int ILI1Reader::OpenFile( const char *pszFilename ) {
      88               0 :     fpItf = VSIFOpen( pszFilename, "r" );
      89               0 :     if( fpItf == NULL )
      90                 :     {
      91                 :           CPLError( CE_Failure, CPLE_OpenFailed,
      92                 :                     "Failed to open ILI file `%s'.",
      93               0 :                     pszFilename );
      94                 : 
      95               0 :         return FALSE;
      96                 :     }
      97               0 :     return TRUE;
      98                 : }
      99                 : 
     100               0 : int ILI1Reader::HasMultiplePointGeom(const char* layername) {
     101               0 :     if (metaLayer != NULL) {
     102               0 :         OGRFeature *metaFeature = NULL;
     103               0 :         metaLayer->ResetReading();
     104               0 :         int i = -1;
     105               0 :         while((metaFeature = metaLayer->GetNextFeature()) != NULL ) {
     106               0 :             if(EQUAL(layername, metaFeature->GetFieldAsString(0))) {
     107               0 :               i++;
     108                 :             }
     109                 :         }
     110               0 :         return i;
     111                 :     } else {
     112               0 :         return -1;
     113                 :     }
     114                 : }
     115                 : 
     116               0 : char* ILI1Reader::GetPointLayerName(const char* layername, char* newlayername) {
     117                 :     static char geomlayername[512];
     118               0 :     geomlayername[0] = '\0';
     119               0 :     strcat(geomlayername, layername);
     120               0 :     strcat(geomlayername, "__");
     121               0 :     strcat(geomlayername, newlayername);
     122               0 :     return geomlayername;
     123                 : }
     124                 : 
     125               0 : const char* ILI1Reader::GetLayerNameString(const char* topicname, const char* tablename) {
     126                 :     static char layername[512];
     127               0 :     layername[0] = '\0';
     128               0 :     strcat(layername, topicname);
     129               0 :     strcat(layername, "__");
     130               0 :     strcat(layername, tablename);
     131               0 :     return layername;
     132                 : }
     133                 : 
     134               0 : const char* ILI1Reader::GetLayerName(IOM_BASKET model, IOM_OBJECT table) {
     135                 :     static char layername[512];
     136               0 :     IOM_OBJECT topic = GetAttrObj(model, table, "container");
     137               0 :     layername[0] = '\0';
     138               0 :     strcat(layername, iom_getattrvalue(topic, "name"));
     139               0 :     strcat(layername, "__");
     140               0 :     strcat(layername, iom_getattrvalue(table, "name"));
     141               0 :     return layername;
     142                 : }
     143                 : 
     144               0 : void ILI1Reader::AddCoord(OGRILI1Layer* layer, IOM_BASKET model, IOM_OBJECT modelele, IOM_OBJECT typeobj) {
     145               0 :   unsigned int dim = ::GetCoordDim(model, typeobj);
     146               0 :   for (unsigned int i=0; i<dim; i++) {
     147               0 :     OGRFieldDefn fieldDef(CPLSPrintf("%s_%d", iom_getattrvalue(modelele, "name"), i), OFTReal);
     148               0 :     layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     149                 :     //CPLDebug( "AddCoord   OGR_ILI", "Field %s: OFTReal", fieldDef.GetNameRef());
     150                 :   }
     151               0 : }
     152                 : 
     153               0 : OGRILI1Layer* ILI1Reader::AddGeomTable(const char* datalayername, const char* geomname, OGRwkbGeometryType eType) {
     154                 :   static char layername[512];
     155               0 :   layername[0] = '\0';
     156               0 :   strcat(layername, datalayername);
     157               0 :   strcat(layername, "_");
     158               0 :   strcat(layername, geomname);
     159                 : 
     160               0 :   OGRILI1Layer* geomlayer = new OGRILI1Layer(layername, NULL, 0, eType, NULL);
     161               0 :   AddLayer(geomlayer);
     162               0 :   OGRFieldDefn fieldDef("_TID", OFTString);
     163               0 :   geomlayer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     164               0 :   if (eType == wkbPolygon)
     165                 :   {
     166               0 :      OGRFieldDefn fieldDefRef("_RefTID", OFTString);
     167               0 :      geomlayer->GetLayerDefn()->AddFieldDefn(&fieldDefRef);
     168                 :   }
     169               0 :   OGRFieldDefn fieldDef2("ILI_Geometry", OFTString); //in write mode only?
     170               0 :   geomlayer->GetLayerDefn()->AddFieldDefn(&fieldDef2);
     171               0 :   return geomlayer;
     172                 : }
     173                 : 
     174               0 : void ILI1Reader::AddField(OGRILI1Layer* layer, IOM_BASKET model, IOM_OBJECT obj) {
     175               0 :   const char* typenam = "Reference";
     176               0 :   if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.LocalAttribute")) typenam = GetTypeName(model, obj);
     177                 :   //CPLDebug( "OGR_ILI", "Field %s: %s", iom_getattrvalue(obj, "name"), typenam);
     178               0 :   if (EQUAL(typenam, "iom04.metamodel.SurfaceType")) {
     179               0 :     OGRILI1Layer* polyLayer = AddGeomTable(layer->GetLayerDefn()->GetName(), iom_getattrvalue(obj, "name"), wkbPolygon);
     180               0 :     layer->SetSurfacePolyLayer(polyLayer);
     181                 :     //TODO: add line attributes to geometry
     182               0 :   } else if (EQUAL(typenam, "iom04.metamodel.AreaType")) {
     183               0 :     IOM_OBJECT controlPointDomain = GetAttrObj(model, GetTypeObj(model, obj), "controlPointDomain");
     184               0 :     if (controlPointDomain) {
     185               0 :       AddCoord(layer, model, obj, GetTypeObj(model, controlPointDomain));
     186               0 :       layer->GetLayerDefn()->SetGeomType(wkbPoint);
     187                 :     }
     188               0 :     OGRILI1Layer* areaLineLayer = AddGeomTable(layer->GetLayerDefn()->GetName(), iom_getattrvalue(obj, "name"), wkbMultiLineString);
     189                 : #ifdef POLYGONIZE_AREAS
     190               0 :     OGRILI1Layer* areaLayer = new OGRILI1Layer(CPLSPrintf("%s__Areas",layer->GetLayerDefn()->GetName()), NULL, 0, wkbPolygon, NULL);
     191               0 :     AddLayer(areaLayer);
     192               0 :     areaLayer->SetAreaLayers(layer, areaLineLayer);
     193                 : #endif
     194               0 :   } else if (EQUAL(typenam, "iom04.metamodel.PolylineType") ) {
     195               0 :     layer->GetLayerDefn()->SetGeomType(wkbMultiLineString);
     196               0 :   } else if (EQUAL(typenam, "iom04.metamodel.CoordType")) {
     197               0 :     AddCoord(layer, model, obj, GetTypeObj(model, obj));
     198               0 :     if (layer->GetLayerDefn()->GetGeomType() == wkbUnknown) layer->GetLayerDefn()->SetGeomType(wkbPoint);
     199               0 :   } else if (EQUAL(typenam, "iom04.metamodel.NumericType") ) {
     200               0 :      OGRFieldDefn fieldDef(iom_getattrvalue(obj, "name"), OFTReal);
     201               0 :      layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     202               0 :   } else if (EQUAL(typenam, "iom04.metamodel.EnumerationType") ) {
     203               0 :      OGRFieldDefn fieldDef(iom_getattrvalue(obj, "name"), OFTInteger);
     204               0 :      layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     205                 :   } else {
     206               0 :     OGRFieldDefn fieldDef(iom_getattrvalue(obj, "name"), OFTString);
     207               0 :     layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     208                 :   }
     209               0 : }
     210                 : 
     211               0 : int ILI1Reader::ReadModel(const char *pszModelFilename) {
     212                 : 
     213                 :   IOM_BASKET model;
     214                 :   IOM_ITERATOR modelelei;
     215                 :   IOM_OBJECT modelele;
     216                 : 
     217               0 :   iom_init();
     218                 : 
     219                 :   // set error listener to a iom provided one, that just
     220                 :   // dumps all errors to stderr
     221               0 :   iom_seterrlistener(iom_stderrlistener);
     222                 : 
     223                 :   // compile ili model
     224               0 :   char *iomarr[1] = {(char *)pszModelFilename};
     225               0 :   model=iom_compileIli(1, iomarr);
     226               0 :   if(!model){
     227               0 :     CPLError( CE_Failure, CPLE_FileIO, "iom_compileIli failed." );
     228               0 :     iom_end();
     229               0 :     return FALSE;
     230                 :   }
     231                 : 
     232                 :   // create new layer with meta information (ILI table name and geometry column index)
     233                 :   // while reading the features from the ITF we have to know which column is the geometry column
     234               0 :   metaLayer = new OGRILI1Layer("Metatable", NULL, 0, wkbUnknown, NULL);
     235               0 :   OGRFieldDefn fieldDef1("layername", OFTString);
     236               0 :   metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef1);
     237               0 :   OGRFieldDefn fieldDef2("geomIdx", OFTInteger);
     238               0 :   metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef2);
     239               0 :   OGRFieldDefn fieldDef3("geomlayername", OFTString);
     240               0 :   metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef3);
     241                 : 
     242                 : 
     243                 :   // read tables
     244               0 :   int j = 0;
     245               0 :   modelelei=iom_iteratorobject(model);
     246               0 :   modelele=iom_nextobject(modelelei);
     247               0 :   while(modelele){
     248               0 :     const char *tag=iom_getobjecttag(modelele);
     249                 : 
     250               0 :     if (tag && EQUAL(tag,"iom04.metamodel.Table")) {
     251                 : 
     252               0 :       const char* topic = iom_getattrvalue(GetAttrObj(model, modelele, "container"), "name");
     253                 : 
     254               0 :       if (!EQUAL(topic, "INTERLIS")) {
     255                 : 
     256               0 :         const char* layername = GetLayerName(model, modelele);
     257               0 :         OGRSpatialReference *poSRSIn = NULL;
     258               0 :         int bWriterIn = 0;
     259               0 :         OGRwkbGeometryType eReqType = wkbUnknown;
     260               0 :         OGRILI1DataSource *poDSIn = NULL;
     261                 : 
     262               0 :         CPLDebug( "OGR_ILI", "Reading table model '%s'", layername );
     263                 : 
     264                 :         // read fields
     265                 :         IOM_OBJECT fields[255];
     266                 :         IOM_OBJECT roledefs[255];
     267               0 :         memset(fields, 0, 255);
     268               0 :         memset(roledefs, 0, 255);
     269               0 :         int maxIdx = -1;
     270               0 :         IOM_ITERATOR fieldit=iom_iteratorobject(model);
     271               0 :         std::vector<IOM_OBJECT> attributes;
     272                 : 
     273               0 :         for (IOM_OBJECT fieldele=iom_nextobject(fieldit); fieldele; fieldele=iom_nextobject(fieldit)){
     274               0 :           const char *etag=iom_getobjecttag(fieldele);
     275                 : 
     276               0 :           if (etag && (EQUAL(etag,"iom04.metamodel.ViewableAttributesAndRoles"))) {
     277               0 :             IOM_OBJECT table = GetAttrObj(model, fieldele, "viewable");
     278                 : 
     279               0 :             if (table == modelele) {
     280                 : 
     281               0 :               IOM_OBJECT obj = GetAttrObj(model, fieldele, "attributesAndRoles");
     282               0 :               int ili1AttrIdx = GetAttrObjPos(fieldele, "attributesAndRoles")-1;
     283                 : 
     284               0 :               if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.RoleDef")) {
     285               0 :                 int ili1AttrIdxOppend = atoi(iom_getattrvalue(GetAttrObj(model, obj, "oppend"), "ili1AttrIdx"));
     286                 : 
     287               0 :                 if (ili1AttrIdxOppend>=0) {
     288               0 :                   roledefs[ili1AttrIdxOppend] = obj;
     289               0 :                   if (ili1AttrIdxOppend > maxIdx) maxIdx = ili1AttrIdxOppend;
     290                 :                 }
     291                 :               } else {
     292               0 :                 fields[ili1AttrIdx] = obj;
     293               0 :                 if (ili1AttrIdx > maxIdx) maxIdx = ili1AttrIdx;
     294                 :               }
     295                 :             }
     296                 :           }
     297               0 :           iom_releaseobject(fieldele);
     298                 :         }
     299               0 :         iom_releaseiterator(fieldit);
     300                 : 
     301                 :         // if multiple gets positive we have more than one geometry column (only points)
     302               0 :         int multiple = -1;
     303                 : 
     304               0 :         for (int i=0; i<=maxIdx; i++) {
     305               0 :           IOM_OBJECT obj = fields[i];
     306               0 :           if (obj) {
     307               0 :            attributes.push_back(obj);
     308               0 :            if (EQUAL(GetTypeName(model, obj), "iom04.metamodel.CoordType")) multiple++;
     309                 :           }
     310                 :         }
     311                 : 
     312               0 :         std::vector<IOM_OBJECT>::iterator it = attributes.begin();
     313               0 :         for (int i=0; i<=maxIdx; i++) {
     314               0 :           IOM_OBJECT obj = roledefs[i];
     315               0 :           if (obj) attributes.insert(attributes.begin() + i, obj);
     316                 :         }
     317                 : 
     318               0 :         OGRFeature *feature = NULL;
     319               0 :         char* geomlayername = '\0';
     320               0 :         OGRILI1Layer* layer = NULL;
     321                 : 
     322               0 :         for(size_t i=0; i<attributes.size(); i++) {
     323               0 :           IOM_OBJECT obj = attributes.at(i);
     324               0 :           const char* typenam = GetTypeName(model, obj);
     325               0 :           if (EQUAL(typenam, "iom04.metamodel.CoordType")  || EQUAL(typenam, "iom04.metamodel.AreaType")) {
     326               0 :             feature = OGRFeature::CreateFeature(metaLayer->GetLayerDefn());
     327               0 :             feature->SetFID(j+1);
     328               0 :             feature->SetField("layername", layername);
     329               0 :             feature->SetField("geomIdx", (int)i);
     330                 : 
     331               0 :             if(multiple > 0) {
     332               0 :               geomlayername = GetPointLayerName(layername, iom_getattrvalue(obj, "name"));
     333               0 :               feature->SetField("geomlayername", geomlayername);
     334               0 :               layer = new OGRILI1Layer(geomlayername, poSRSIn, bWriterIn, eReqType, poDSIn);
     335               0 :               AddLayer(layer);
     336                 : 
     337                 :             } else {
     338               0 :               feature->SetField("geomlayername", layername);
     339               0 :               layer = new OGRILI1Layer(layername, poSRSIn, bWriterIn, eReqType, poDSIn);
     340               0 :               AddLayer(layer);
     341                 :             }
     342               0 :             metaLayer->AddFeature(feature);
     343                 :           }
     344                 :         }
     345                 : 
     346               0 :         if(layer == NULL) {
     347               0 :           layer = new OGRILI1Layer(layername, poSRSIn, bWriterIn, eReqType, poDSIn);
     348               0 :           AddLayer(layer);
     349                 :         }
     350                 : 
     351               0 :         OGRFieldDefn fieldDef("_TID", OFTString);
     352               0 :         layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     353                 : 
     354               0 :         for(size_t i=0; i<attributes.size(); i++) {
     355               0 :           IOM_OBJECT obj = attributes.at(i);
     356               0 :           AddField(layer, model, obj);
     357                 :         }
     358                 : 
     359                 :         // additional point layer added
     360               0 :         if(multiple > 0) {
     361               0 :           for(int i = 1; i <= multiple; i++) {
     362               0 :              OGRILI1Layer* pointLayer = papoLayers[nLayers-(i+1)];
     363               0 :              for (int j=0; j < layer->GetLayerDefn()->GetFieldCount(); j++) {
     364               0 :                pointLayer->CreateField(layer->GetLayerDefn()->GetFieldDefn(j));
     365                 :              }
     366               0 :           if (pointLayer->GetLayerDefn()->GetGeomType() == wkbUnknown) pointLayer->GetLayerDefn()->SetGeomType(wkbPoint);
     367                 :           }
     368                 :         }
     369                 : 
     370               0 :         if (papoLayers[nLayers-1]->GetLayerDefn()->GetFieldCount() == 0) {
     371                 :             //Area layer added
     372               0 :             OGRILI1Layer* areaLayer = papoLayers[nLayers-1];
     373               0 :             for (int i=0; i < layer->GetLayerDefn()->GetFieldCount(); i++) {
     374               0 :               areaLayer->CreateField(layer->GetLayerDefn()->GetFieldDefn(i));
     375                 :             }
     376               0 :         }
     377                 :       }
     378                 :     }
     379               0 :     iom_releaseobject(modelele);
     380                 : 
     381               0 :     modelele=iom_nextobject(modelelei);
     382               0 :     j++;
     383                 :   }
     384                 : 
     385               0 :   iom_releaseiterator(modelelei);
     386                 : 
     387               0 :   iom_releasebasket(model);
     388                 : 
     389               0 :   iom_end();
     390                 : 
     391               0 :   return 0;
     392                 : }
     393                 : 
     394               0 : int ILI1Reader::ReadFeatures() {
     395               0 :     char **tokens = NULL;
     396               0 :     const char *firsttok = NULL;
     397                 :     const char *pszLine;
     398               0 :     char *topic = NULL;
     399               0 :     int ret = TRUE;
     400                 : 
     401               0 :     while (ret && (tokens = ReadParseLine()))
     402                 :     {
     403               0 :       firsttok = tokens[0];
     404               0 :       if (EQUAL(firsttok, "SCNT"))
     405                 :       {
     406                 :         //read description
     407               0 :         do
     408                 :         {
     409               0 :           pszLine = CPLReadLine( fpItf );
     410                 :         }
     411                 :         while (pszLine && !EQUALN(pszLine, "////", 4));
     412               0 :         ret = (pszLine != NULL);
     413                 :       }
     414               0 :       else if (EQUAL(firsttok, "MOTR"))
     415                 :       {
     416                 :         //read model
     417               0 :         do
     418                 :         {
     419               0 :           pszLine = CPLReadLine( fpItf );
     420                 :         }
     421                 :         while (pszLine && !EQUALN(pszLine, "////", 4));
     422               0 :         ret = (pszLine != NULL);
     423                 :       }
     424               0 :       else if (EQUAL(firsttok, "MTID"))
     425                 :       {
     426                 :       }
     427               0 :       else if (EQUAL(firsttok, "MODL"))
     428                 :       {
     429                 :       }
     430               0 :       else if (EQUAL(firsttok, "TOPI"))
     431                 :       {
     432               0 :         CPLFree(topic);
     433               0 :         topic = CPLStrdup(CSLGetField(tokens, 1));
     434                 :       }
     435               0 :       else if (EQUAL(firsttok, "TABL"))
     436                 :       {
     437               0 :         CPLDebug( "OGR_ILI", "Reading table '%s'", GetLayerNameString(topic, CSLGetField(tokens, 1)) );
     438               0 :         const char *layername = GetLayerNameString(topic, CSLGetField(tokens, 1));
     439               0 :         curLayer = GetLayerByName(layername);
     440                 : 
     441               0 :         int multiple = HasMultiplePointGeom(layername);
     442                 : 
     443                 :         // create only a new layer if there is no curLayer AND
     444                 :         // if there are more than one point geometry columns
     445               0 :         if (curLayer == NULL && multiple < 1) { //create one
     446               0 :           CPLDebug( "OGR_ILI", "No model found, using default field names." );
     447               0 :           OGRSpatialReference *poSRSIn = NULL;
     448               0 :           int bWriterIn = 0;
     449               0 :           OGRwkbGeometryType eReqType = wkbUnknown;
     450               0 :           OGRILI1DataSource *poDSIn = NULL;
     451               0 :           curLayer = new OGRILI1Layer(GetLayerNameString(topic, CSLGetField(tokens, 1)), poSRSIn, bWriterIn, eReqType, poDSIn);
     452               0 :           AddLayer(curLayer);
     453                 :         }
     454               0 :         if(curLayer != NULL) {
     455               0 :           for (int i=0; i < curLayer->GetLayerDefn()->GetFieldCount(); i++) {
     456               0 :             CPLDebug( "OGR_ILI", "Field %d: %s", i,  curLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());
     457                 :           }
     458                 :         }
     459               0 :         ret = ReadTable(layername);
     460                 :       }
     461               0 :       else if (EQUAL(firsttok, "ETOP"))
     462                 :       {
     463                 :       }
     464               0 :       else if (EQUAL(firsttok, "EMOD"))
     465                 :       {
     466                 :       }
     467               0 :       else if (EQUAL(firsttok, "ENDE"))
     468                 :       {
     469               0 :         CSLDestroy(tokens);
     470               0 :         CPLFree(topic);
     471               0 :         return TRUE;
     472                 :       }
     473                 :       else
     474                 :       {
     475               0 :         CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok );
     476                 :       }
     477                 : 
     478               0 :       CSLDestroy(tokens);
     479               0 :       tokens = NULL;
     480                 :     }
     481                 : 
     482               0 :     CSLDestroy(tokens);
     483               0 :     CPLFree(topic);
     484                 : 
     485               0 :     return ret;
     486                 : }
     487                 : 
     488               0 : int ILI1Reader::AddIliGeom(OGRFeature *feature, int iField, long fpos)
     489                 : {
     490                 : #if defined(_WIN32) || defined(__WIN32__)
     491                 :     //Other positions on Windows !?
     492                 : #else
     493               0 :     long nBlockLen = VSIFTell( fpItf )-fpos;
     494               0 :     VSIFSeek( fpItf, fpos, SEEK_SET );
     495                 : 
     496               0 :     char *pszRawData = (char *) CPLMalloc(nBlockLen+1);
     497               0 :     if( (int) VSIFRead( pszRawData, 1, nBlockLen, fpItf ) != nBlockLen )
     498                 :     {
     499               0 :         CPLFree( pszRawData );
     500                 : 
     501               0 :         CPLError( CE_Failure, CPLE_FileIO, "Read of transfer file failed." );
     502               0 :         return FALSE;
     503                 :     }
     504               0 :     pszRawData[nBlockLen]= '\0';
     505               0 :     feature->SetField(iField, pszRawData);
     506               0 :     CPLFree( pszRawData );
     507                 : #endif
     508               0 :     return TRUE;
     509                 : }
     510                 : 
     511                 : 
     512               0 : int ILI1Reader::ReadTable(const char *layername) {
     513               0 :     char **tokens = NULL;
     514               0 :     const char *firsttok = NULL;
     515               0 :     int ret = TRUE;
     516               0 :     int warned = FALSE;
     517                 :     int fIndex;
     518               0 :     int geomIdx = 0;
     519                 : 
     520                 :     // curLayer is NULL if we have more than one
     521                 :     // point geometry column
     522               0 :     if(curLayer == NULL) {
     523               0 :       OGRFeature *metaFeature = NULL;
     524               0 :       metaLayer->ResetReading();
     525               0 :       while((metaFeature = metaLayer->GetNextFeature()) != NULL ) {
     526               0 :         if(EQUAL(layername, metaFeature->GetFieldAsString(0))) {
     527               0 :           const char *geomlayername = metaFeature->GetFieldAsString(2);
     528               0 :           curLayer = GetLayerByName(geomlayername);
     529               0 :           break;
     530                 :         }
     531                 :       }
     532                 :     }
     533                 : 
     534               0 :     OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
     535               0 :     OGRFeature *feature = NULL;
     536                 : 
     537                 :     // get the geometry index of the current layer
     538                 :     // only if the model is read
     539               0 :     if(featureDef->GetFieldCount() != 0) {
     540               0 :       OGRFeature *metaFeature = NULL;
     541               0 :       metaLayer->ResetReading();
     542               0 :       while((metaFeature = metaLayer->GetNextFeature()) != NULL ) {
     543               0 :         if(EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) {
     544               0 :           geomIdx = metaFeature->GetFieldAsInteger(1);
     545                 :         }
     546                 :       }
     547                 :     }
     548                 : 
     549               0 :     long fpos = VSIFTell(fpItf);
     550               0 :     while (ret && (tokens = ReadParseLine()))
     551                 :     {
     552               0 :       firsttok = CSLGetField(tokens, 0);
     553               0 :       if (EQUAL(firsttok, "OBJE"))
     554                 :       {
     555                 :         //Check for features spread over multiple objects
     556               0 :         if (featureDef->GetGeomType() == wkbPolygon)
     557                 :         {
     558                 :           //Multiple polygon rings
     559               0 :           feature = curLayer->GetFeatureRef(atol(CSLGetField(tokens, 2)));
     560                 :         }
     561               0 :         else if (featureDef->GetGeomType() == wkbGeometryCollection)
     562                 :         {
     563                 :           //AREA lines spread over mutltiple objects
     564                 :         }
     565                 :         else
     566                 :         {
     567               0 :           feature = NULL;
     568                 :         }
     569                 : 
     570               0 :         if (feature == NULL)
     571                 :         {
     572               0 :           if (featureDef->GetFieldCount() == 0)
     573                 :           {
     574               0 :             CPLDebug( "OGR_ILI", "No field definition found for table: %s", featureDef->GetName() );
     575                 :             //Model not read - use heuristics
     576               0 :             for (fIndex=1; fIndex<CSLCount(tokens); fIndex++)
     577                 :             {
     578                 :               char szFieldName[32];
     579               0 :               sprintf(szFieldName, "Field%02d", fIndex);
     580               0 :               OGRFieldDefn oFieldDefn(szFieldName, OFTString);
     581               0 :               featureDef->AddFieldDefn(&oFieldDefn);
     582                 :             }
     583                 :           }
     584                 :           //start new feature
     585               0 :           feature = new OGRFeature(featureDef);
     586                 : 
     587               0 :           int fieldno = 0;
     588               0 :           for (fIndex=1; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++)
     589                 :           {
     590               0 :             if (!EQUAL(tokens[fIndex], "@")) {
     591                 :               //CPLDebug( "READ TABLE OGR_ILI", "Adding Field %d: %s", fieldno, tokens[fIndex]);
     592               0 :               feature->SetField(fieldno, tokens[fIndex]);
     593               0 :               if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal
     594                 :                   && fieldno > 0
     595                 :                   && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal
     596                 :                   && featureDef->GetGeomType() == wkbPoint
     597                 : 
     598                 :                   /*
     599                 :                   // if there is no ili model read,
     600                 :                   // we have no chance to detect the
     601                 :                   // geometry column!!
     602                 :                   */
     603                 : 
     604                 :                   && (fieldno-2) == geomIdx) {
     605                 :                 //add Point geometry
     606               0 :                 OGRPoint *ogrPoint = new OGRPoint(atof(tokens[fIndex-1]), atof(tokens[fIndex]));
     607               0 :                 feature->SetGeometryDirectly(ogrPoint);
     608                 :               }
     609                 :             }
     610                 :           }
     611               0 :           if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1 && !(featureDef->GetFieldCount() == CSLCount(tokens) && EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))) {
     612               0 :             CPLDebug( "OGR_ILI", "Field count doesn't match. %d declared, %d found", featureDef->GetFieldCount(), CSLCount(tokens)-1);
     613               0 :             warned = TRUE;
     614                 :           }
     615               0 :           if (featureDef->GetGeomType() == wkbPolygon)
     616               0 :             feature->SetFID(atol(feature->GetFieldAsString(1)));
     617               0 :           else if (feature->GetFieldCount() > 0)
     618               0 :             feature->SetFID(atol(feature->GetFieldAsString(0)));
     619               0 :           curLayer->AddFeature(feature);
     620                 :         }
     621                 :       }
     622               0 :       else if (EQUAL(firsttok, "STPT"))
     623                 :       {
     624               0 :         ReadGeom(tokens, featureDef->GetGeomType(), feature);
     625               0 :         if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))
     626                 :         {
     627               0 :           AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos); //TODO: append multi-OBJECT geometries
     628                 :         }
     629                 :       }
     630               0 :       else if (EQUAL(firsttok, "ELIN"))
     631                 :       {
     632                 :         //empty geom
     633                 :       }
     634               0 :       else if (EQUAL(firsttok, "EDGE"))
     635                 :       {
     636               0 :         tokens = ReadParseLine(); //STPT
     637               0 :         ReadGeom(tokens, wkbMultiLineString, feature);
     638               0 :         if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))
     639                 :         {
     640               0 :           AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos);
     641                 :         }
     642                 :       }
     643               0 :       else if (EQUAL(firsttok, "PERI"))
     644                 :       {
     645                 :       }
     646               0 :       else if (EQUAL(firsttok, "ETAB"))
     647                 :       {
     648               0 :         if(HasMultiplePointGeom(layername) > 0) {
     649               0 :           OGRFeature *metaFeature = NULL;
     650               0 :           metaLayer->ResetReading();
     651               0 :           while((metaFeature = metaLayer->GetNextFeature()) != NULL ) {
     652               0 :             int pntCln = 1;
     653               0 :             if(EQUAL(layername, metaFeature->GetFieldAsString(0)) && !EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) {
     654               0 :               pntCln++;
     655               0 :               OGRILI1Layer *curLayerTmp = GetLayerByName(metaFeature->GetFieldAsString(2));
     656               0 :               OGRFeature *tmpFeature = NULL;
     657               0 :               int geomIdxTmp = metaFeature->GetFieldAsInteger(1);
     658               0 :               curLayer->ResetReading();
     659               0 :               while((tmpFeature = curLayer->GetNextFeature()) != NULL ) {
     660               0 :                 OGRPoint *ogrPoint = new OGRPoint(atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln)), atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln + 1)));
     661               0 :                 tmpFeature->SetGeometryDirectly(ogrPoint);
     662               0 :                 curLayerTmp->AddFeature(tmpFeature);
     663                 :               }
     664                 :             }
     665                 :           }
     666                 :         }
     667               0 :         CSLDestroy(tokens);
     668               0 :         return TRUE;
     669                 :       }
     670                 :       else
     671                 :       {
     672               0 :         CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok );
     673                 :       }
     674                 : 
     675               0 :       CSLDestroy(tokens);
     676               0 :       fpos = VSIFTell(fpItf);
     677                 :     }
     678                 : 
     679               0 :     return ret;
     680                 : }
     681                 : 
     682               0 : void ILI1Reader::ReadGeom(char **stgeom, OGRwkbGeometryType eType, OGRFeature *feature) {
     683                 : 
     684               0 :     char **tokens = NULL;
     685               0 :     const char *firsttok = NULL;
     686               0 :     int end = FALSE;
     687               0 :     int isArc = FALSE;
     688               0 :     OGRLineString *ogrLine = NULL; //current line
     689               0 :     OGRLinearRing *ogrRing = NULL; //current ring
     690               0 :     OGRPolygon *ogrPoly = NULL; //current polygon
     691               0 :     OGRPoint ogrPoint, arcPoint, endPoint; //points for arc interpolation
     692               0 :     OGRMultiLineString *ogrMultiLine = NULL; //current multi line
     693                 : 
     694                 :     //tokens = ["STPT", "1111", "22222"]
     695               0 :     ogrPoint.setX(atof(stgeom[1])); ogrPoint.setY(atof(stgeom[2]));
     696               0 :     ogrLine = (eType == wkbPolygon) ? new OGRLinearRing() : new OGRLineString();
     697               0 :     ogrLine->addPoint(&ogrPoint);
     698                 : 
     699                 :     //Set feature geometry
     700               0 :     if (eType == wkbMultiLineString)
     701                 :     {
     702               0 :       ogrMultiLine = new OGRMultiLineString();
     703               0 :       feature->SetGeometryDirectly(ogrMultiLine);
     704                 :     }
     705               0 :     else if (eType == wkbGeometryCollection) //AREA
     706                 :     {
     707               0 :       if (feature->GetGeometryRef())
     708               0 :         ogrMultiLine = (OGRMultiLineString *)feature->GetGeometryRef();
     709                 :       else
     710                 :       {
     711               0 :         ogrMultiLine = new OGRMultiLineString();
     712               0 :         feature->SetGeometryDirectly(ogrMultiLine);
     713                 :       }
     714                 :     }
     715               0 :     else if (eType == wkbPolygon)
     716                 :     {
     717               0 :       if (feature->GetGeometryRef())
     718                 :       {
     719               0 :         ogrPoly = (OGRPolygon *)feature->GetGeometryRef();
     720               0 :         if (ogrPoly->getNumInteriorRings() > 0)
     721               0 :           ogrRing = ogrPoly->getInteriorRing(ogrPoly->getNumInteriorRings()-1);
     722                 :         else
     723               0 :           ogrRing = ogrPoly->getExteriorRing();
     724               0 :         if (ogrRing && !ogrRing->get_IsClosed()) ogrLine = ogrRing; //SURFACE polygon spread over multiple OBJECTs
     725                 :       }
     726                 :       else
     727                 :       {
     728               0 :         ogrPoly = new OGRPolygon();
     729               0 :         feature->SetGeometryDirectly(ogrPoly);
     730                 :       }
     731                 :     }
     732                 :     else
     733                 :     {
     734               0 :       feature->SetGeometryDirectly(ogrLine);
     735                 :     }
     736                 : 
     737                 :     //Parse geometry
     738               0 :     while (!end && (tokens = ReadParseLine()))
     739                 :     {
     740               0 :       firsttok = CSLGetField(tokens, 0);
     741               0 :       if (EQUAL(firsttok, "LIPT"))
     742                 :       {
     743               0 :         if (isArc) {
     744               0 :           endPoint.setX(atof(tokens[1])); endPoint.setY(atof(tokens[2]));
     745               0 :           interpolateArc(ogrLine, &ogrPoint, &arcPoint, &endPoint, arcIncr);
     746                 :         }
     747               0 :         ogrPoint.setX(atof(tokens[1])); ogrPoint.setY(atof(tokens[2])); isArc = FALSE;
     748               0 :         ogrLine->addPoint(&ogrPoint);
     749                 :       }
     750               0 :       else if (EQUAL(firsttok, "ARCP"))
     751                 :       {
     752               0 :         isArc = TRUE;
     753               0 :         arcPoint.setX(atof(tokens[1])); arcPoint.setY(atof(tokens[2]));
     754                 :       }
     755               0 :       else if (EQUAL(firsttok, "ELIN"))
     756                 :       {
     757               0 :         if (ogrMultiLine)
     758                 :         {
     759               0 :           ogrMultiLine->addGeometryDirectly(ogrLine);
     760                 :         }
     761               0 :         if (ogrPoly && ogrLine != ogrRing)
     762                 :         {
     763               0 :           ogrPoly->addRingDirectly((OGRLinearRing *)ogrLine);
     764                 :         }
     765               0 :         end = TRUE;
     766                 :       }
     767               0 :       else if (EQUAL(firsttok, "EEDG"))
     768                 :       {
     769               0 :         end = TRUE;
     770                 :       }
     771               0 :       else if (EQUAL(firsttok, "LATT"))
     772                 :       {
     773                 :         //Line Attributes (ignored)
     774                 :       }
     775               0 :       else if (EQUAL(firsttok, "EFLA"))
     776                 :       {
     777               0 :         end = TRUE;
     778                 :       }
     779               0 :       else if (EQUAL(firsttok, "ETAB"))
     780                 :       {
     781               0 :         end = TRUE;
     782                 :       }
     783                 :       else
     784                 :       {
     785               0 :         CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok );
     786                 :       }
     787                 : 
     788               0 :       CSLDestroy(tokens);
     789               0 :     }
     790               0 : }
     791                 : 
     792                 : /************************************************************************/
     793                 : /*                              AddLayer()                              */
     794                 : /************************************************************************/
     795                 : 
     796               0 : void ILI1Reader::AddLayer( OGRILI1Layer * poNewLayer )
     797                 : 
     798                 : {
     799               0 :     nLayers++;
     800                 : 
     801                 :     papoLayers = (OGRILI1Layer **)
     802               0 :         CPLRealloc( papoLayers, sizeof(void*) * nLayers );
     803                 : 
     804               0 :     papoLayers[nLayers-1] = poNewLayer;
     805               0 : }
     806                 : 
     807                 : /************************************************************************/
     808                 : /*                              AddAreaLayer()                              */
     809                 : /************************************************************************/
     810                 : 
     811                 : /************************************************************************/
     812                 : /*                              GetLayer()                              */
     813                 : /************************************************************************/
     814                 : 
     815               0 : OGRILI1Layer *ILI1Reader::GetLayer( int iLayer )
     816                 : 
     817                 : {
     818               0 :     if( iLayer < 0 || iLayer >= nLayers )
     819               0 :         return NULL;
     820                 :     else
     821               0 :         return papoLayers[iLayer];
     822                 : }
     823                 : 
     824               0 : OGRILI1Layer *ILI1Reader::GetLayerByName( const char* pszLayerName )
     825                 : 
     826                 : {
     827               0 :     for(int iLayer = 0; iLayer < nLayers; iLayer++ )
     828                 :     {
     829               0 :         if( EQUAL(pszLayerName,
     830                 :                   papoLayers[iLayer]->GetLayerDefn()->GetName()) )
     831               0 :             return papoLayers[iLayer];
     832                 :     }
     833               0 :     return NULL;
     834                 : }
     835                 : 
     836                 : /************************************************************************/
     837                 : /*                           GetLayerCount()                            */
     838                 : /************************************************************************/
     839                 : 
     840               0 : int ILI1Reader::GetLayerCount()
     841                 : 
     842                 : {
     843               0 :     return nLayers;
     844                 : }
     845                 : 
     846                 : /************************************************************************/
     847                 : /*     Read one logical line, and return split into fields.  The return */
     848                 : /*     result is a stringlist, in the sense of the CSL functions.       */
     849                 : /************************************************************************/
     850                 : 
     851               0 : char ** ILI1Reader::ReadParseLine()
     852                 : {
     853                 :     const char  *pszLine;
     854                 :     char **tokens;
     855                 :     char **conttok;
     856                 :     char *token;
     857                 : 
     858               0 :     CPLAssert( fpItf != NULL );
     859               0 :     if( fpItf == NULL )
     860               0 :         return( NULL );
     861                 : 
     862               0 :     pszLine = CPLReadLine( fpItf );
     863               0 :     if( pszLine == NULL )
     864               0 :         return( NULL );
     865                 : 
     866               0 :     if (strlen(pszLine) == 0) return NULL;
     867                 : 
     868               0 :     tokens = CSLTokenizeString2( pszLine, " ", CSLT_PRESERVEESCAPES );
     869               0 :     token = tokens[CSLCount(tokens)-1];
     870                 : 
     871                 :     //Append CONT lines
     872               0 :     while (strlen(pszLine) && EQUALN(token, "\\", 2))
     873                 :     {
     874                 :        //remove last token
     875               0 :       CPLFree(tokens[CSLCount(tokens)-1]);
     876               0 :       tokens[CSLCount(tokens)-1] = NULL;
     877                 : 
     878               0 :       pszLine = CPLReadLine( fpItf );
     879               0 :       conttok = CSLTokenizeString2( pszLine, " ", CSLT_PRESERVEESCAPES );
     880               0 :       if (!conttok || !EQUAL(conttok[0], "CONT"))
     881                 :       {
     882               0 :           CSLDestroy(conttok);
     883               0 :           break;
     884                 :       }
     885                 : 
     886                 :       //append
     887               0 :       tokens = CSLInsertStrings(tokens, -1, &conttok[1]);
     888               0 :       token = tokens[CSLCount(tokens)-1];
     889                 : 
     890               0 :       CSLDestroy(conttok);
     891                 :     }
     892               0 :     return tokens;
     893                 : }
     894                 : 
     895                 : 
     896                 : 
     897               0 : IILI1Reader *CreateILI1Reader() {
     898               0 :     return new ILI1Reader();
     899                 : }
     900                 : 
     901             174 : void DestroyILI1Reader(IILI1Reader* reader)
     902                 : {
     903             174 :     if (reader)
     904               0 :         delete reader;
     905             174 : }

Generated by: LCOV version 1.7