📄 mitab_miffile.cpp
字号:
* MIFFile::GetLayerDefn()
*
* Returns a reference to the OGRFeatureDefn that will be used to create
* features in this dataset.
*
* Returns a reference to an object that is maintained by this MIFFile
* object (and thus should not be modified or freed by the caller) or
* NULL if the OGRFeatureDefn has not been initialized yet (i.e. no file
* opened yet)
**********************************************************************/
OGRFeatureDefn *MIFFile::GetLayerDefn()
{
return m_poDefn;
}
/**********************************************************************
* MIFFile::SetFeatureDefn()
*
* Pass a reference to the OGRFeatureDefn that will be used to create
* features in this dataset. This function should be called after
* creating a new dataset, but before writing the first feature.
* All features that will be written to this dataset must share this same
* OGRFeatureDefn.
*
* This function will use poFeatureDefn to create a local copy that
* will be used to build the .MID file, etc.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int MIFFile::SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
TABFieldType *paeMapInfoNativeFieldTypes /* =NULL */)
{
int numFields;
int nStatus = 0;
/*-----------------------------------------------------------------
* Check that call happens at the right time in dataset's life.
*----------------------------------------------------------------*/
if ( m_eAccessMode == TABWrite && m_bHeaderWrote )
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"SetFeatureDefn() must be called after opening a new "
"dataset, but before writing the first feature to it.");
return -1;
}
/*-----------------------------------------------------------------
* Delete current feature defn if there is already one.
* AddFieldNative() will take care of creating a new one for us.
*----------------------------------------------------------------*/
if (m_poDefn && m_poDefn->Dereference() == 0)
delete m_poDefn;
m_poDefn = NULL;
/*-----------------------------------------------------------------
* Copy field information
*----------------------------------------------------------------*/
numFields = poFeatureDefn->GetFieldCount();
for(int iField=0; iField<numFields; iField++)
{
TABFieldType eMapInfoType;
OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn(iField);
if (paeMapInfoNativeFieldTypes)
{
eMapInfoType = paeMapInfoNativeFieldTypes[iField];
}
else
{
/*---------------------------------------------------------
* Map OGRFieldTypes to MapInfo native types
*--------------------------------------------------------*/
switch(poFieldDefn->GetType())
{
case OFTInteger:
eMapInfoType = TABFInteger;
break;
case OFTReal:
eMapInfoType = TABFFloat;
break;
case OFTString:
default:
eMapInfoType = TABFChar;
}
}
nStatus = AddFieldNative(poFieldDefn->GetNameRef(), eMapInfoType,
poFieldDefn->GetWidth(),
poFieldDefn->GetPrecision(), FALSE, FALSE);
}
return nStatus;
}
/**********************************************************************
* MIFFile::AddFieldNative()
*
* Create a new field using a native mapinfo data type... this is an
* alternative to defining fields through the OGR interface.
* This function should be called after creating a new dataset, but before
* writing the first feature.
*
* This function will build/update the OGRFeatureDefn that will have to be
* used when writing features to this dataset.
*
* A reference to the OGRFeatureDefn can be obtained using GetLayerDefn().
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int MIFFile::AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
int nWidth /*=0*/, int nPrecision /*=0*/,
GBool bIndexed /*=FALSE*/, GBool bUnique/*=FALSE*/)
{
OGRFieldDefn *poFieldDefn;
char *pszCleanName = NULL;
int nStatus = 0;
/*-----------------------------------------------------------------
* Check that call happens at the right time in dataset's life.
*----------------------------------------------------------------*/
if ( m_eAccessMode == TABWrite && m_bHeaderWrote )
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"AddFieldNative() must be called after opening a new "
"dataset, but before writing the first feature to it.");
return -1;
}
/*-----------------------------------------------------------------
* Validate field width... must be <= 254
*----------------------------------------------------------------*/
if (nWidth > 254)
{
CPLError(CE_Warning, CPLE_IllegalArg,
"Invalid size (%d) for field '%s'. "
"Size must be 254 or less.", nWidth, pszName);
nWidth = 254;
}
/*-----------------------------------------------------------------
* Map fields with width=0 (variable length in OGR) to a valid default
*----------------------------------------------------------------*/
if (eMapInfoType == TABFDecimal && nWidth == 0)
nWidth=20;
else if (nWidth == 0)
nWidth=254; /* char fields */
/*-----------------------------------------------------------------
* Create new OGRFeatureDefn if not done yet...
*----------------------------------------------------------------*/
if (m_poDefn == NULL)
{
char *pszFeatureClassName = TABGetBasename(m_pszFname);
m_poDefn = new OGRFeatureDefn(pszFeatureClassName);
CPLFree(pszFeatureClassName);
// Ref count defaults to 0... set it to 1
m_poDefn->Reference();
}
/*-----------------------------------------------------------------
* Make sure field name is valid... check for special chars, etc.
* (pszCleanName will have to be freed.)
*----------------------------------------------------------------*/
pszCleanName = TABCleanFieldName(pszName);
/*-----------------------------------------------------------------
* Map MapInfo native types to OGR types
*----------------------------------------------------------------*/
poFieldDefn = NULL;
switch(eMapInfoType)
{
case TABFChar:
/*-------------------------------------------------
* CHAR type
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTString);
poFieldDefn->SetWidth(nWidth);
break;
case TABFInteger:
/*-------------------------------------------------
* INTEGER type
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTInteger);
break;
case TABFSmallInt:
/*-------------------------------------------------
* SMALLINT type
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTInteger);
break;
case TABFDecimal:
/*-------------------------------------------------
* DECIMAL type
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTReal);
poFieldDefn->SetWidth(nWidth);
poFieldDefn->SetPrecision(nPrecision);
break;
case TABFFloat:
/*-------------------------------------------------
* FLOAT type
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTReal);
break;
case TABFDate:
/*-------------------------------------------------
* DATE type (V450, returned as a string: "DD/MM/YYYY" or "YYYYMMDD")
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTString);
poFieldDefn->SetWidth(10);
m_nVersion = MAX(m_nVersion, 450);
break;
case TABFTime:
/*-------------------------------------------------
* TIME type (v900, returned as a string: "HH:MM:SS" or "HHMMSSmmm")
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTString);
poFieldDefn->SetWidth(9);
m_nVersion = MAX(m_nVersion, 900);
break;
case TABFDateTime:
/*-------------------------------------------------
* DATETIME type (v900, returned as a string: "DD/MM/YYYY HH:MM:SS",
* "YYYY/MM/DD HH:MM:SS" or "YYYYMMDDHHMMSSmmm")
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTString);
poFieldDefn->SetWidth(19);
break;
m_nVersion = MAX(m_nVersion, 900);
case TABFLogical:
/*-------------------------------------------------
* LOGICAL type (value "T" or "F")
*------------------------------------------------*/
poFieldDefn = new OGRFieldDefn(pszCleanName, OFTString);
poFieldDefn->SetWidth(1);
break;
default:
CPLError(CE_Failure, CPLE_NotSupported,
"Unsupported type for field %s", pszName);
return -1;
}
/*-----------------------------------------------------
* Add the FieldDefn to the FeatureDefn
*----------------------------------------------------*/
m_poDefn->AddFieldDefn(poFieldDefn);
delete poFieldDefn;
/*-----------------------------------------------------------------
* Keep track of native field type
*----------------------------------------------------------------*/
m_paeFieldType = (TABFieldType *)CPLRealloc(m_paeFieldType,
m_poDefn->GetFieldCount()*
sizeof(TABFieldType));
m_paeFieldType[m_poDefn->GetFieldCount()-1] = eMapInfoType;
/*-----------------------------------------------------------------
* Extend array of Indexed/Unique flags
*----------------------------------------------------------------*/
m_pabFieldIndexed = (GBool *)CPLRealloc(m_pabFieldIndexed,
m_poDefn->GetFieldCount()*
sizeof(GBool));
m_pabFieldUnique = (GBool *)CPLRealloc(m_pabFieldUnique,
m_poDefn->GetFieldCount()*
sizeof(GBool));
m_pabFieldIndexed[m_poDefn->GetFieldCount()-1] = bIndexed;
m_pabFieldUnique[m_poDefn->GetFieldCount()-1] = bUnique;
CPLFree(pszCleanName);
return nStatus;
}
/**********************************************************************
* MIFFile::GetNativeFieldType()
*
* Returns the native MapInfo field type for the specified field.
*
* Returns TABFUnknown if file is not opened, or if specified field index is
* invalid.
**********************************************************************/
TABFieldType MIFFile::GetNativeFieldType(int nFieldId)
{
if ( m_poDefn==NULL || m_paeFieldType==NULL ||
nFieldId < 0 || nFieldId >= m_poDefn->GetFieldCount())
return TABFUnknown;
return m_paeFieldType[nFieldId];
}
/************************************************************************
* MIFFile::SetFieldIndexed()
************************************************************************/
int MIFFile::SetFieldIndexed( int nFieldId )
{
if ( m_poDefn==NULL || m_pabFieldIndexed==NULL ||
nFieldId < 0 || nFieldId >= m_poDefn->GetFieldCount())
return -1;
m_pabFieldIndexed[nFieldId] = TRUE;
return 0;
}
/************************************************************************
* MIFFile::IsFieldIndexed()
************************************************************************/
GBool MIFFile::IsFieldIndexed( int nFieldId )
{
if ( m_poDefn==NULL || m_pabFieldIndexed==NULL ||
nFieldId < 0 || nFieldId >= m_poDefn->GetFieldCount())
return FALSE;
return m_pabFieldIndexed[nFieldId];
}
/************************************************************************
* MIFFile::IsFieldUnique()
************************************************************************/
GBool MIFFile::IsFieldUnique( int nFieldId )
{
if ( m_poDefn==NULL || m_pabFieldUnique==NULL ||
nFieldId < 0 || nFieldId >= m_poDefn->GetFieldCount())
return FALSE;
return m_pabFieldUnique[nFieldId];
}
/************************************************************************/
/* MIFFile::SetSpatialRef() */
/************************************************************************/
int MIFFile::SetSpatialRef( OGRSpatialReference * poSpatialRef )
{
CPLFree( m_pszCoordSys );
m_pszCoordSys = MITABSpatialRef2CoordSys( poSpatialRef );
return( m_pszCoordSys != NULL );
}
/************************************************************************/
/* MIFFile::SetMIFCoordSys() */
/************************************************************************/
int MIFFile::SetMIFCoordSys(const char * pszMIFCoordSys)
{
char **papszFields, *pszCoordSys;
int iBounds;
// Extract the word 'COORDSYS' if present
if (EQUALN(pszMIFCoordSys,"COORDSYS",8) )
{
pszCoordSys = CPLStrdup(pszMIFCoordSys + 9);
}
else
{
pszCoordSys = CPLStrdup(pszMIFCoordSys);
}
// Extract bounds if present
papszFields = CSLTokenizeStringComplex(pszCoordSys, " ,()\t",
TRUE, FALSE );
iBounds = CSLFindString( papszFields, "Bounds" );
if (i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -