int ILI1Reader::ReadTable(const char *layername) { char **tokens = NULL; const char *firsttok = NULL; int ret = TRUE; int warned = FALSE; int fIndex; int geomIdx; // curLayer is NULL if we have more than one // point geometry column if(curLayer == NULL) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { if(EQUAL(layername, metaFeature->GetFieldAsString(0))) { const char *geomlayername = metaFeature->GetFieldAsString(2); curLayer = GetLayerByName(geomlayername); break; } } } OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; // get the geometry index of the current layer // only if the model is read if(featureDef->GetFieldCount() != 0) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { if(EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) { geomIdx = metaFeature->GetFieldAsInteger(1); } } } long fpos = VSIFTell(fpItf); while (ret && (tokens = ReadParseLine())) { firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { //Check for features spread over multiple objects if (featureDef->GetGeomType() == wkbPolygon) { //Multiple polygon rings feature = curLayer->GetFeatureRef(atol(CSLGetField(tokens, 2))); } else if (featureDef->GetGeomType() == wkbGeometryCollection) { //AREA lines spread over mutltiple objects } else { feature = NULL; } if (feature == NULL) { if (featureDef->GetFieldCount() == 0) { CPLDebug( "OGR_ILI", "No field definition found for table: %s", featureDef->GetName() ); //Model not read - use heuristics for (fIndex=1; fIndex<CSLCount(tokens); fIndex++) { char szFieldName[32]; sprintf(szFieldName, "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature feature = new OGRFeature(featureDef); int fieldno = 0; for (fIndex=1; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++) { if (!EQUAL(tokens[fIndex], "@")) { //CPLDebug( "READ TABLE OGR_ILI", "Adding Field %d: %s", fieldno, tokens[fIndex]); feature->SetField(fieldno, tokens[fIndex]); if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal && featureDef->GetGeomType() == wkbPoint /* // if there is no ili model read, // we have no chance to detect the // geometry column!! */ && (fieldno-2) == geomIdx) { //add Point geometry OGRPoint *ogrPoint = new OGRPoint(atof(tokens[fIndex-1]), atof(tokens[fIndex])); feature->SetGeometryDirectly(ogrPoint); } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1 && !(featureDef->GetFieldCount() == CSLCount(tokens) && EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))) { CPLDebug( "OGR_ILI", "Field count doesn't match. %d declared, %d found", featureDef->GetFieldCount(), CSLCount(tokens)-1); warned = TRUE; } if (featureDef->GetGeomType() == wkbPolygon) feature->SetFID(atol(feature->GetFieldAsString(1))); else if (feature->GetFieldCount() > 0) feature->SetFID(atol(feature->GetFieldAsString(0))); curLayer->AddFeature(feature); } } else if (EQUAL(firsttok, "STPT")) { ReadGeom(tokens, featureDef->GetGeomType(), feature); if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry")) { AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos); //TODO: append multi-OBJECT geometries } } else if (EQUAL(firsttok, "ELIN")) { //empty geom } else if (EQUAL(firsttok, "EDGE")) { tokens = ReadParseLine(); //STPT ReadGeom(tokens, wkbMultiLineString, feature); if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry")) { AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos); } } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { if(HasMultiplePointGeom(layername) > 0) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { int pntCln = 1; if(EQUAL(layername, metaFeature->GetFieldAsString(0)) && !EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) { pntCln++; OGRILI1Layer *curLayerTmp = GetLayerByName(metaFeature->GetFieldAsString(2)); OGRFeature *tmpFeature = NULL; int geomIdxTmp = metaFeature->GetFieldAsInteger(1); curLayer->ResetReading(); while((tmpFeature = curLayer->GetNextFeature()) != NULL ) { OGRPoint *ogrPoint = new OGRPoint(atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln)), atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln + 1))); tmpFeature->SetGeometryDirectly(ogrPoint); curLayerTmp->AddFeature(tmpFeature); } } } } CSLDestroy(tokens); return TRUE; } else { CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); fpos = VSIFTell(fpItf); } return ret; }
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) { char **tokens = NULL; int ret = TRUE; int warned = FALSE; int geomIdx = -1; OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; bool bFeatureAdded = false; while (ret && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { if (featureDef->GetFieldCount() == 0 && curLayer->GetFeatureCount() == 0) { CPLError( CE_Warning, CPLE_AppDefined, "No field definition found for table: %s", featureDef->GetName() ); // Model not read - use heuristics. for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ ) { char szFieldName[32]; snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature if( !bFeatureAdded ) delete feature; feature = new OGRFeature(featureDef); for( int fIndex=1, fieldno = 0; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++ ) { if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) { #ifdef DEBUG_VERBOSE CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s", fieldno, featureDef->GetFieldDefn(fieldno)->GetType(), tokens[fIndex] ); #endif if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) { // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8 char* pszRecoded = CPLRecode( tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8); // Replace space marks for( char* pszString = pszRecoded; *pszString != '\0'; pszString++ ) { if (*pszString == codeBlank) *pszString = ' '; } feature->SetField(fieldno, pszRecoded); CPLFree(pszRecoded); } else { feature->SetField(fieldno, tokens[fIndex]); } if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) { // Check for Point geometry (Coord type). // If there is no ili model read, // we have no chance to detect the // geometry column. CPLString geomfldname = featureDef->GetFieldDefn(fieldno)->GetNameRef(); // Check if name ends with _1. if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2] == '_') { geomfldname = geomfldname.substr(0, geomfldname.size()-2); geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str()); if (geomIdx == -1) { CPLError( CE_Warning, CPLE_AppDefined, "No matching definition for field '%s' of " "table %s found", geomfldname.c_str(), featureDef->GetName() ); } } else { geomIdx = -1; } if (geomIdx >= 0) { if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { // Add Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex])); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint25D && fieldno > 1 && featureDef->GetFieldDefn(fieldno-2)->GetType() == OFTReal) { // Add 3D Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]) ); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } } } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) { CPLError( CE_Warning, CPLE_AppDefined, "Field count of table %s doesn't match. %d declared, " "%d found (e.g. ignored LINEATTR)", featureDef->GetName(), featureDef->GetFieldCount(), CSLCount(tokens) - 1 ); warned = TRUE; } if (feature->GetFieldCount() > 0) { // USE _TID as FID. TODO: respect IDENT field from model. feature->SetFID(feature->GetFieldAsInteger64(0)); } curLayer->AddFeature(feature); bFeatureAdded = true; geomIdx = -1; //Reset } else if (EQUAL(firsttok, "STPT") && feature != NULL) { //Find next non-Point geometry if (geomIdx < 0) geomIdx = 0; while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { geomIdx++; } OGRwkbGeometryType geomType = (geomIdx < featureDef->GetGeomFieldCount()) ? featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone; if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, geomType, feature); } else if (EQUAL(firsttok, "ELIN")) { // Empty geom. } else if (EQUAL(firsttok, "EDGE") && feature != NULL) { CSLDestroy(tokens); tokens = ReadParseLine(); //STPT //Find next non-Point geometry do { geomIdx++; } while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint); if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, wkbMultiLineString, feature); } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB, curLayer->GetFeatureCount() ); CSLDestroy(tokens); if( !bFeatureAdded ) delete feature; return TRUE; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } if( !bFeatureAdded ) delete feature; return ret; }