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; }