Exemple #1
0
int ILI1Reader::ReadModel(const char *pszModelFilename) {

  IOM_BASKET model;
  IOM_ITERATOR modelelei;
  IOM_OBJECT modelele;

  iom_init();

  // set error listener to a iom provided one, that just
  // dumps all errors to stderr
  iom_seterrlistener(iom_stderrlistener);

  // compile ili model
  char *iomarr[1] = {(char *)pszModelFilename};
  model=iom_compileIli(1, iomarr);
  if(!model){
    CPLError( CE_Failure, CPLE_FileIO, "iom_compileIli failed." );
    iom_end();
    return FALSE;
  }

  // create new layer with meta information (ILI table name and geometry column index)
  // while reading the features from the ITF we have to know which column is the geometry column
  metaLayer = new OGRILI1Layer("Metatable", NULL, 0, wkbUnknown, NULL);
  OGRFieldDefn fieldDef1("layername", OFTString);
  metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef1);
  OGRFieldDefn fieldDef2("geomIdx", OFTInteger);
  metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef2);
  OGRFieldDefn fieldDef3("geomlayername", OFTString);
  metaLayer->GetLayerDefn()->AddFieldDefn(&fieldDef3);


  // read tables
  int j = 0;
  modelelei=iom_iteratorobject(model);
  modelele=iom_nextobject(modelelei);
  while(modelele){
    const char *tag=iom_getobjecttag(modelele);

    if (tag && EQUAL(tag,"iom04.metamodel.Table")) {

      const char* topic = iom_getattrvalue(GetAttrObj(model, modelele, "container"), "name");

      if (!EQUAL(topic, "INTERLIS")) {

        const char* layername = GetLayerName(model, modelele);
        OGRSpatialReference *poSRSIn = NULL;
        int bWriterIn = 0;
        OGRwkbGeometryType eReqType = wkbUnknown;
        OGRILI1DataSource *poDSIn = NULL;

        CPLDebug( "OGR_ILI", "Reading table model '%s'", layername );

        // read fields
        IOM_OBJECT fields[255];
        IOM_OBJECT roledefs[255];
        memset(fields, 0, 255);
        memset(roledefs, 0, 255);
        int maxIdx = -1;
        IOM_ITERATOR fieldit=iom_iteratorobject(model);
        std::vector<IOM_OBJECT> attributes;

        for (IOM_OBJECT fieldele=iom_nextobject(fieldit); fieldele; fieldele=iom_nextobject(fieldit)){
          const char *etag=iom_getobjecttag(fieldele);

          if (etag && (EQUAL(etag,"iom04.metamodel.ViewableAttributesAndRoles"))) {
            IOM_OBJECT table = GetAttrObj(model, fieldele, "viewable");

            if (table == modelele) {

              IOM_OBJECT obj = GetAttrObj(model, fieldele, "attributesAndRoles");
              int ili1AttrIdx = GetAttrObjPos(fieldele, "attributesAndRoles")-1;

              if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.RoleDef")) {
                int ili1AttrIdxOppend = atoi(iom_getattrvalue(GetAttrObj(model, obj, "oppend"), "ili1AttrIdx"));

                if (ili1AttrIdxOppend>=0) {
                  roledefs[ili1AttrIdxOppend] = obj;
                  if (ili1AttrIdxOppend > maxIdx) maxIdx = ili1AttrIdxOppend;
                }
              } else {
                fields[ili1AttrIdx] = obj;
                if (ili1AttrIdx > maxIdx) maxIdx = ili1AttrIdx;
              }
            }
          }
          iom_releaseobject(fieldele);
        }
        iom_releaseiterator(fieldit);

        // if multiple gets positive we have more than one geometry column (only points)
        int multiple = -1;

        for (int i=0; i<=maxIdx; i++) {
          IOM_OBJECT obj = fields[i];
          if (obj) {
           attributes.push_back(obj);
           if (EQUAL(GetTypeName(model, obj), "iom04.metamodel.CoordType")) multiple++;
          }
        }

        std::vector<IOM_OBJECT>::iterator it = attributes.begin();
        for (int i=0; i<=maxIdx; i++) {
          IOM_OBJECT obj = roledefs[i];
          if (obj) attributes.insert(attributes.begin() + i, obj);
        }

        OGRFeature *feature = NULL;
        char* geomlayername = '\0';
        OGRILI1Layer* layer = NULL;

        for(int i=0; i<attributes.size(); i++) {
          IOM_OBJECT obj = attributes.at(i);
          const char* typenam = GetTypeName(model, obj);
          if (EQUAL(typenam, "iom04.metamodel.CoordType")  || EQUAL(typenam, "iom04.metamodel.AreaType")) {
            feature = OGRFeature::CreateFeature(metaLayer->GetLayerDefn());
            feature->SetFID(j+1);
            feature->SetField("layername", layername);
            feature->SetField("geomIdx", i);

            if(multiple > 0) {
              geomlayername = GetPointLayerName(layername, iom_getattrvalue(obj, "name"));
              feature->SetField("geomlayername", geomlayername);
              layer = new OGRILI1Layer(geomlayername, poSRSIn, bWriterIn, eReqType, poDSIn);
              AddLayer(layer);

            } else {
              feature->SetField("geomlayername", layername);
              layer = new OGRILI1Layer(layername, poSRSIn, bWriterIn, eReqType, poDSIn);
              AddLayer(layer);
            }
            metaLayer->AddFeature(feature);
          }
        }

        if(layer == NULL) {
          layer = new OGRILI1Layer(layername, poSRSIn, bWriterIn, eReqType, poDSIn);
          AddLayer(layer);
        }

        OGRFieldDefn fieldDef("_TID", OFTString);
        layer->GetLayerDefn()->AddFieldDefn(&fieldDef);

        for(int i=0; i<attributes.size(); i++) {
          IOM_OBJECT obj = attributes.at(i);
          AddField(layer, model, obj);
        }

        // additional point layer added
        if(multiple > 0) {
          for(int i = 1; i <= multiple; i++) {
             OGRILI1Layer* pointLayer = papoLayers[nLayers-(i+1)];
             for (int j=0; j < layer->GetLayerDefn()->GetFieldCount(); j++) {
               pointLayer->CreateField(layer->GetLayerDefn()->GetFieldDefn(j));
             }
          if (pointLayer->GetLayerDefn()->GetGeomType() == wkbUnknown) pointLayer->GetLayerDefn()->SetGeomType(wkbPoint);
          }
        }

        if (papoLayers[nLayers-1]->GetLayerDefn()->GetFieldCount() == 0) {
            //Area layer added
            OGRILI1Layer* areaLayer = papoLayers[nLayers-1];
            for (int i=0; i < layer->GetLayerDefn()->GetFieldCount(); i++) {
              areaLayer->CreateField(layer->GetLayerDefn()->GetFieldDefn(i));
            }
        }
      }
    }
    iom_releaseobject(modelele);

    modelele=iom_nextobject(modelelei);
    j++;
  }

  iom_releaseiterator(modelelei);

  iom_releasebasket(model);

  iom_end();

  return 0;
}
int OGRILI1DataSource::Create( const char *pszFilename,
                              char **papszOptions )

{
    std::string osBasename, osModelFilename;
    char **filenames = CSLTokenizeString2( pszFilename, ",", 0 );

    osBasename = filenames[0];

    if( CSLCount(filenames) > 1 )
        osModelFilename = filenames[1];

    CSLDestroy( filenames );

    if( osModelFilename.length() == 0 )
    {
      //TODO: create automatic model
    }

/* -------------------------------------------------------------------- */
/*      Create the empty file.                                          */
/* -------------------------------------------------------------------- */
    fpTransfer = VSIFOpen( osBasename.c_str(), "w+b" );

    if( fpTransfer == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to create %s:\n%s",
                  osBasename.c_str(), VSIStrerror( errno ) );

        return FALSE;
    }


/* -------------------------------------------------------------------- */
/*      Parse model                                                     */
/* -------------------------------------------------------------------- */
    iom_init();

    // set error listener to a iom provided one, that just
    // dumps all errors to stderr
    iom_seterrlistener(iom_stderrlistener);

    IOM_BASKET model = 0;
    if( osModelFilename.length() != 0 ) {
    // compile ili model
    char *iliFiles[1] = {(char *)osModelFilename.c_str()};
    model=iom_compileIli(1,iliFiles);
    if(!model){
        CPLError( CE_Warning, CPLE_OpenFailed,
                  "iom_compileIli %s, %s.",
                  pszName, VSIStrerror( errno ) );
        iom_end();
        return FALSE;
    }
    }

/* -------------------------------------------------------------------- */
/*      Write headers                                                   */
/* -------------------------------------------------------------------- */
    VSIFPrintf( fpTransfer, "SCNT\n" );
    VSIFPrintf( fpTransfer, "OGR/GDAL %s, INTERLIS Driver\n", GDAL_RELEASE_NAME );
    VSIFPrintf( fpTransfer, "////\n" );
    VSIFPrintf( fpTransfer, "MTID INTERLIS1\n" );
    const char* modelname = model ? GetAttrObjName(model, "iom04.metamodel.DataModel") : osBasename.c_str(); //TODO: remove file extension (= table name)
    VSIFPrintf( fpTransfer, "MODL %s\n", modelname );

    return TRUE;
}