?? mitab_tabview.cpp
字號:
char *pszTableName = TABGetBasename(m_pszFname);
if ( m_poRelation->Init(pszTableName,
m_papoTABFiles[0], m_papoTABFiles[1],
m_papszWhereClause[4], m_papszWhereClause[2],
m_papszFieldNames) != 0 )
{
// An error should already have been reported
CPLFree(pszTableName);
Close();
return -1;
}
CPLFree(pszTableName);
return 0;
}
/**********************************************************************
* TABView::OpenForWrite()
*
* Create a new TABView dataset
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::OpenForWrite(const char *pszFname)
{
int nFnameLen = 0;
m_eAccessMode = TABWrite;
/*-----------------------------------------------------------------
* Read main .TAB (text) file
*----------------------------------------------------------------*/
m_pszFname = CPLStrdup(pszFname);
#ifndef _WIN32
/*-----------------------------------------------------------------
* On Unix, make sure extension uses the right cases
* We do it even for write access because if a file with the same
* extension already exists we want to overwrite it.
*----------------------------------------------------------------*/
TABAdjustFilenameExtension(m_pszFname);
#endif
/*-----------------------------------------------------------------
* Extract the path component from the main .TAB filename
*----------------------------------------------------------------*/
char *pszPath = CPLStrdup(m_pszFname);
nFnameLen = strlen(pszPath);
for( ; nFnameLen > 0; nFnameLen--)
{
if (pszPath[nFnameLen-1] == '/' ||
pszPath[nFnameLen-1] == '\\' )
{
break;
}
pszPath[nFnameLen-1] = '\0';
}
char *pszBasename = TABGetBasename(m_pszFname);
/*-----------------------------------------------------------------
* Create the 2 TAB files for the view.
*
* __TODO__ For now, we support only 2 files linked through a single
* field... not sure if anything else than that can be useful
* anyways.
*----------------------------------------------------------------*/
m_numTABFiles = 2;
m_papszTABFnames = NULL;
m_nMainTableIndex = 0;
m_bRelFieldsCreated = FALSE;
m_papoTABFiles = (TABFile**)CPLCalloc(m_numTABFiles, sizeof(TABFile*));
for (int iFile=0; iFile < m_numTABFiles; iFile++)
{
m_papszTABFnames = CSLAppendPrintf(m_papszTABFnames, "%s%s%d.tab",
pszPath, pszBasename, iFile+1);
#ifndef _WIN32
TABAdjustFilenameExtension(m_papszTABFnames[iFile]);
#endif
m_papoTABFiles[iFile] = new TABFile;
if ( m_papoTABFiles[iFile]->Open(m_papszTABFnames[iFile], "wb") != 0)
{
// Open Failed... an error has already been reported, just return.
CPLFree(pszPath);
CPLFree(pszBasename);
Close();
return -1;
}
}
/*-----------------------------------------------------------------
* Create TABRelation...
*----------------------------------------------------------------*/
m_poRelation = new TABRelation;
if ( m_poRelation->Init(pszBasename,
m_papoTABFiles[0], m_papoTABFiles[1],
NULL, NULL, NULL) != 0 )
{
// An error should already have been reported
CPLFree(pszPath);
CPLFree(pszBasename);
Close();
return -1;
}
CPLFree(pszPath);
CPLFree(pszBasename);
return 0;
}
/**********************************************************************
* TABView::ParseTABFile()
*
* Scan the lines of the TAB file, and store any useful information into
* class members. The main piece of information being the sub-table
* names, and the list of fields to include in the view that we will
* use to build the OGRFeatureDefn for this file.
*
* It is assumed that the TAB header file is already loaded in m_papszTABFile
*
* This private method should be used only during the Open() call.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::ParseTABFile(const char *pszDatasetPath,
GBool bTestOpenNoError /*=FALSE*/)
{
int iLine, numLines;
char **papszTok=NULL;
GBool bInsideTableDef = FALSE;
if (m_eAccessMode != TABRead)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"ParseTABFile() can be used only with Read access.");
return -1;
}
numLines = CSLCount(m_papszTABFile);
for(iLine=0; iLine<numLines; iLine++)
{
/*-------------------------------------------------------------
* Tokenize the next .TAB line, and check first keyword
*------------------------------------------------------------*/
CSLDestroy(papszTok);
papszTok = CSLTokenizeStringComplex(m_papszTABFile[iLine], " \t(),;",
TRUE, FALSE);
if (CSLCount(papszTok) < 2)
continue; // All interesting lines have at least 2 tokens
if (EQUAL(papszTok[0], "!version"))
{
m_pszVersion = CPLStrdup(papszTok[1]);
}
else if (EQUAL(papszTok[0], "!charset"))
{
CPLFree(m_pszCharset);
m_pszCharset = CPLStrdup(papszTok[1]);
}
else if (EQUAL(papszTok[0], "open") &&
EQUAL(papszTok[1], "table") &&
CSLCount(papszTok) >= 3)
{
// Source table name may be either "filename" or "filename.tab"
int nLen = strlen(papszTok[2]);
if (nLen > 4 && EQUAL(papszTok[2]+nLen-4, ".tab"))
papszTok[2][nLen-4] = '\0';
m_papszTABFnames = CSLAppendPrintf(m_papszTABFnames,
"%s%s.tab",
pszDatasetPath, papszTok[2]);
}
else if (EQUAL(papszTok[0], "create") &&
EQUAL(papszTok[1], "view") )
{
bInsideTableDef = TRUE;
}
else if (bInsideTableDef &&
(EQUAL(papszTok[0],"Select")))
{
/*---------------------------------------------------------
* We found the list of table fields (comma-delimited list)
*--------------------------------------------------------*/
int iTok;
for(iTok=1; papszTok[iTok] != NULL; iTok++)
m_papszFieldNames = CSLAddString(m_papszFieldNames,
papszTok[iTok]);
}
else if (bInsideTableDef &&
(EQUAL(papszTok[0],"where")))
{
/*---------------------------------------------------------
* We found the where clause that relates the 2 tables
* Something in the form:
* where table1.field1=table2.field2
* The tokenized array will contain:
* {"where", "table1", "field1", "table2", "field2"}
*--------------------------------------------------------*/
m_papszWhereClause =CSLTokenizeStringComplex(m_papszTABFile[iLine],
" \t(),;=.",
TRUE, FALSE);
/*---------------------------------------------------------
* For now we are very limiting on the format of the WHERE
* clause... we will be more permitting as we learn more about
* what it can contain... (I don't want to implement a full SQL
* parser here!!!). If you encountered this error,
* (and are reading this!) please report the test dataset
* that produced the error and I'll see if we can support it.
*--------------------------------------------------------*/
if (CSLCount( m_papszWhereClause ) != 5)
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"WHERE clause in %s is not in a supported format: \"%s\"",
m_pszFname, m_papszTABFile[iLine]);
return -1;
}
}
else
{
// Simply Ignore unrecognized lines
}
}
CSLDestroy(papszTok);
/*-----------------------------------------------------------------
* The main table is the one from which we read the geometries, etc...
* For now we assume it is always the first one in the list
*----------------------------------------------------------------*/
m_nMainTableIndex = 0;
/*-----------------------------------------------------------------
* Make sure all required class members are set
*----------------------------------------------------------------*/
m_numTABFiles = CSLCount(m_papszTABFnames);
if (m_pszCharset == NULL)
m_pszCharset = CPLStrdup("Neutral");
if (m_pszVersion == NULL)
m_pszVersion = CPLStrdup("100");
if (CSLCount(m_papszFieldNames) == 0 )
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"%s: header contains no table field definition. "
"This type of .TAB file cannot be read by this library.",
m_pszFname);
return -1;
}
if (CSLCount(m_papszWhereClause) == 0 )
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"%s: WHERE clause not found or missing in header. "
"This type of .TAB file cannot be read by this library.",
m_pszFname);
return -1;
}
return 0;
}
/**********************************************************************
* TABView::WriteTABFile()
*
* Generate the TAB header file. This is usually done during the
* Close() call.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::WriteTABFile()
{
FILE *fp;
CPLAssert(m_eAccessMode == TABWrite);
CPLAssert(m_numTABFiles == 2);
CPLAssert(GetLayerDefn());
char *pszTable = TABGetBasename(m_pszFname);
char *pszTable1 = TABGetBasename(m_papszTABFnames[0]);
char *pszTable2 = TABGetBasename(m_papszTABFnames[1]);
if ( (fp = VSIFOpen(m_pszFname, "wt")) != NULL)
{
// Version is always 100, no matter what the sub-table's version is
fprintf(fp, "!Table\n");
fprintf(fp, "!Version 100\n");
fprintf(fp, "Open Table \"%s\" Hide\n", pszTable1);
fprintf(fp, "Open Table \"%s\" Hide\n", pszTable2);
fprintf(fp, "\n");
fprintf(fp, "Create View %s As\n", pszTable);
fprintf(fp, "Select ");
OGRFeatureDefn *poDefn = GetLayerDefn();
for(int iField=0; iField<poDefn->GetFieldCount(); iField++)
{
OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField);
if (iField == 0)
fprintf(fp, "%s", poFieldDefn->GetNameRef());
else
fprintf(fp, ",%s", poFieldDefn->GetNameRef());
}
fprintf(fp, "\n");
fprintf(fp, "From %s, %s\n", pszTable2, pszTable1);
fprintf(fp, "Where %s.%s=%s.%s\n", pszTable2,
m_poRelation->GetRelFieldName(),
pszTable1,
m_poRelation->GetMainFieldName());
VSIFClose(fp);
}
else
{
CPLError(CE_Failure, CPLE_FileIO,
"Failed to create file `%s'", m_pszFname);
return -1;
}
CPLFree(pszTable);
CPLFree(pszTable1);
CPLFree(pszTable2);
return 0;
}
/**********************************************************************
* TABView::Close()
*
* Close current file, and release all memory used.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABView::Close()
{
// In write access, the main .TAB file has not been written yet.
if (m_eAccessMode == TABWrite && m_poRelation)
WriteTABFile();
for(int i=0; m_papoTABFiles && i<m_numTABFiles; i++)
{
if (m_papoTABFiles[i])
delete m_papoTABFiles[i]; // Automatically closes.
}
CPLFree(m_papoTABFiles);
m_papoTABFiles = NULL;
m_numTABFiles = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -