OGRErr OGRShapeLayer::CreateField( OGRFieldDefn *poFieldDefn, int bApproxOK ) { CPLAssert( NULL != poFieldDefn ); int iNewField; if( !bUpdateAccess ) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields on a read-only shapefile layer.\n"); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Normalize field name */ /* -------------------------------------------------------------------- */ char szNewFieldName[10 + 1]; char * pszTmp = NULL; int nRenameNum = 1; size_t nNameSize = strlen( poFieldDefn->GetNameRef() ); pszTmp = CPLScanString( poFieldDefn->GetNameRef(), MIN( nNameSize, 10) , TRUE, TRUE); strncpy(szNewFieldName, pszTmp, 10); szNewFieldName[10] = '\0'; if( !bApproxOK && ( DBFGetFieldIndex( hDBF, szNewFieldName ) >= 0 || !EQUAL(poFieldDefn->GetNameRef(),szNewFieldName) ) ) { CPLError( CE_Failure, CPLE_NotSupported, "Failed to add field named '%s'", poFieldDefn->GetNameRef() ); CPLFree( pszTmp ); return OGRERR_FAILURE; } while( DBFGetFieldIndex( hDBF, szNewFieldName ) >= 0 && nRenameNum < 10 ) sprintf( szNewFieldName, "%.8s_%.1d", pszTmp, nRenameNum++ ); while( DBFGetFieldIndex( hDBF, szNewFieldName ) >= 0 && nRenameNum < 100 ) sprintf( szNewFieldName, "%.8s%.2d", pszTmp, nRenameNum++ ); CPLFree( pszTmp ); pszTmp = NULL; if( DBFGetFieldIndex( hDBF, szNewFieldName ) >= 0 ) { CPLError( CE_Failure, CPLE_NotSupported, "Too many field names like '%s' when truncated to 10 letters " "for Shapefile format.", poFieldDefn->GetNameRef() );//One hundred similar field names!!? } if( !EQUAL(poFieldDefn->GetNameRef(),szNewFieldName) ) CPLError( CE_Warning, CPLE_NotSupported, "Normalized/laundered field name: '%s' to '%s'", poFieldDefn->GetNameRef(), szNewFieldName ); // Set field name with normalized value OGRFieldDefn oModFieldDefn(poFieldDefn); oModFieldDefn.SetName(szNewFieldName); /* -------------------------------------------------------------------- */ /* Add field to layer */ /* -------------------------------------------------------------------- */ if( oModFieldDefn.GetType() == OFTInteger ) { if( oModFieldDefn.GetWidth() == 0 ) iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTInteger, 10,0); else iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTInteger, oModFieldDefn.GetWidth(), 0 ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } else if( oModFieldDefn.GetType() == OFTReal ) { if( oModFieldDefn.GetWidth() == 0 ) iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTDouble, 24, 15 ); else iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTDouble, oModFieldDefn.GetWidth(), oModFieldDefn.GetPrecision() ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } else if( oModFieldDefn.GetType() == OFTString ) { if( oModFieldDefn.GetWidth() < 1 ) iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTString, 80, 0 ); else iNewField = DBFAddField( hDBF, oModFieldDefn.GetNameRef(), FTString, oModFieldDefn.GetWidth(), 0 ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } else if( oModFieldDefn.GetType() == OFTDate ) { iNewField = DBFAddNativeFieldType( hDBF, oModFieldDefn.GetNameRef(), 'D', 8, 0 ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } else if( oModFieldDefn.GetType() == OFTDateTime ) { CPLError( CE_Warning, CPLE_NotSupported, "Field %s create as date field, though DateTime requested.\n", oModFieldDefn.GetNameRef() ); iNewField = DBFAddNativeFieldType( hDBF, oModFieldDefn.GetNameRef(), 'D', 8, 0 ); if( iNewField != -1 ) { oModFieldDefn.SetType( OFTDate ); poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } } else { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields of type %s on shapefile layers.\n", OGRFieldDefn::GetFieldTypeName(oModFieldDefn.GetType()) ); return OGRERR_FAILURE; } if( iNewField != -1 ) { return OGRERR_NONE; } else { CPLError( CE_Failure, CPLE_AppDefined, "Can't create field %s in Shape DBF file, reason unknown.\n", oModFieldDefn.GetNameRef() ); return OGRERR_FAILURE; } }
OGRErr OGRPCIDSKLayer::CreateField( OGRFieldDefn *poFieldDefn, int bApproxOK ) { try { if( poFieldDefn->GetType() == OFTInteger ) { poVecSeg->AddField( poFieldDefn->GetNameRef(), PCIDSK::FieldTypeInteger, "", "" ); poFeatureDefn->AddFieldDefn( poFieldDefn ); } else if( poFieldDefn->GetType() == OFTReal ) { poVecSeg->AddField( poFieldDefn->GetNameRef(), PCIDSK::FieldTypeDouble, "", "" ); poFeatureDefn->AddFieldDefn( poFieldDefn ); } else if( poFieldDefn->GetType() == OFTString ) { poVecSeg->AddField( poFieldDefn->GetNameRef(), PCIDSK::FieldTypeString, "", "" ); poFeatureDefn->AddFieldDefn( poFieldDefn ); } else if( poFieldDefn->GetType() == OFTIntegerList ) { poVecSeg->AddField( poFieldDefn->GetNameRef(), PCIDSK::FieldTypeCountedInt, "", "" ); poFeatureDefn->AddFieldDefn( poFieldDefn ); } else if( bApproxOK ) { // Fallback to treating everything else as a string field. OGRFieldDefn oModFieldDefn(poFieldDefn); oModFieldDefn.SetType( OFTString ); poVecSeg->AddField( poFieldDefn->GetNameRef(), PCIDSK::FieldTypeString, "", "" ); poFeatureDefn->AddFieldDefn( &oModFieldDefn ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create field '%s' of unsupported data type.", poFieldDefn->GetNameRef() ); } } /* -------------------------------------------------------------------- */ /* Trap exceptions and report as CPL errors. */ /* -------------------------------------------------------------------- */ catch( PCIDSK::PCIDSKException ex ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", ex.what() ); return OGRERR_FAILURE; } catch(...) { CPLError( CE_Failure, CPLE_AppDefined, "Non-PCIDSK exception trapped." ); return OGRERR_FAILURE; } return OGRERR_NONE; }