⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 importodbc.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// NRDB Pro is part of the Natural Resources Database Project 
// 
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
// 

#include "stdafx.h"
#include <io.h>
#include <fcntl.h>
#include <odbcinst.h>

#include "nrdb.h"
#include "importodbc.h"
#include "dlgimportodbc.h"
#include "dlgimportfeature.h"
#include "bdimportexport.h"
#include "dlgimportstatus.h"
#include "utils.h"
#include "dlgprogress.h"
#include "dlgeditfeature.h"
#include "dlgimportdate.h"
#include "importmaplines.h"
#include "shapefile.h"
#include "importftype.h"
#include "mainfrm.h"
#include "dlgimportrename.h"
#include "dlgimportprimarykey.h"
#include "dlgprotect.h"

///////////////////////////////////////////////////////////////////////////////           

CImportColumn::CImportColumn()
{      
   m_bAttr = FALSE;
   m_bShapeFile = FALSE;
   m_sText[0] = '\0';
   m_lItemData = 0;
}

CImportColumn::CImportColumn(CImportColumn& rSrc)
{
   m_sNameImport = rSrc.m_sNameImport;
   m_sNameAttr = rSrc.m_sNameAttr;
   m_bAttr = rSrc.m_bAttr;
   m_bShapeFile = rSrc.m_bShapeFile;
   m_lItemData = rSrc.m_lItemData;
   strncpy(m_sText, rSrc.m_sText, BD_SHORTSTR);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

CImportFeature::CImportFeature()
{
   m_lFeature = 0;
   m_lFType = 0;
}

///////////////////////////////////////////////////////////////////////////////

CImportDB& CImportDB::operator=(CImportDB& rSrc)
{
   RemoveAll();
   for (int i = 0; i < rSrc.GetSize(); i++) Add(rSrc[i]);   
   return *this;
}

///////////////////////////////////////////////////////////////////////////////

CImportDB::CImportDB()
{
   m_pDlgProgress = NULL;
}

///////////////////////////////////////////////////////////////////////////////
//
// Retrieve the data source and open it and the municipality that the ODBC
// data is to be imported for
//

void CImportDB::ImportODBC(LPCSTR sDataSource, LPCSTR sTable, BOOL bSysTables, int nFileType)
{
   CDatabase database;
   BOOL bCancel = FALSE;
   BOOL bNRDB = FALSE;
  
// Initialise variables

   m_nImported = 0;

// Open the log file

   m_sLogFile = GetTempFileName();
   m_pLogFile = fopen(m_sLogFile,"w");
   fprintf(m_pLogFile, BDString(IDS_IMPORTING) + "...\r\n");

// Start the transaction here so that OnCreate can also be cancelled

   if (BDGetTransLevel(BDHandle()) > 0) BDCommit(BDHandle());
   BDBeginTrans(BDHandle());


   // Open dialog to select data source and format

   CDlgImportODBC dlg(sDataSource, sTable, bSysTables, nFileType);
   int nRet = dlg.DoModal();

   // Begin the transaction

   BDOnError(BDHandle(), ThrowException);

   if (nRet == IDOK)
   {  
      *this = dlg.GetImportDB();      

     // Retrieve the format

      bNRDB = dlg.IsNRDB();
      if (bNRDB)
      {
          CImportFType importftype(this, sDataSource);
          m_nImported = importftype.Import();
          if (m_nImported < 0)
          {
             bCancel = TRUE;
          }
      }
      
      // Connect to the database

		else if (database.Open(dlg.GetDatabase()))
		{
         m_pDlgProgress = new CDlgProgress;

         for (int i = 0; i < GetSize(); i++)
         {
            if (GetAt(i).m_bImport)
            {               
               GetAt(i).Import(database, *this, nFileType);
            };

            if (!m_pDlgProgress->SetPercent((100*i)/GetSize()))
            {
               bCancel = TRUE;
            }
         };
        
        // Close the database

			database.Close();

         delete m_pDlgProgress;
         m_pDlgProgress = NULL;
		};	      
   } else
   {
      bCancel = TRUE;
   }

   // Output the log file

   // Report number of records imported

   if (bCancel)
   {
      fprintf(m_pLogFile, BDString(IDS_IMPORTCANCEL) + "\r\n");                       

   } 
   else
   {      
      fprintf(m_pLogFile, BDString(IDS_NUMRECORDS) + ": %i\r\n", m_nImported);                       
      if (m_nImported == 0 && !bNRDB)
      {
         fprintf(m_pLogFile,"\r\n" + BDString(IDS_IMPORTTIP) + "\r\n");
      }
   };

   if (m_pLogFile != NULL) fclose(m_pLogFile);

   CDlgImportStatus dlgStatus(m_sLogFile, !bCancel && m_nImported != 0);

   if (dlgStatus.DoModal() == IDOK)
   {
      BDCommit(BDHandle());
   } else
   {
	  bCancel = TRUE;
      BDRollBack(BDHandle());
   }

   remove(m_sLogFile);
   BDOnError(BDHandle(), DisplayMessage);

   // Compact database

   if (m_nImported != 0 && !bCancel)
   {
      CompactDatabase();
   }

};


///////////////////////////////////////////////////////////////////////////////

CImportTable::CImportTable()
{   
   m_bImport = FALSE;   
   m_lId = 0;
   m_pImportDB = NULL;
   m_lAttrIdShapefile = 0;
   m_bAutoCreate = FALSE;
};

CImportTable::CImportTable(CImportTable& rSrc)
{
   *this = rSrc;      
}

CImportTable& CImportTable::operator=(CImportTable& rSrc)
{	
   m_sTableImport = rSrc.m_sTableImport;
   m_sFType = rSrc.m_sFType;   
   m_bImport = rSrc.m_bImport;
   m_lId = rSrc.m_lId;
   m_sFeature = rSrc.m_sFeature;
   m_sParentFeature = rSrc.m_sParentFeature;
   m_sGrandParentFeature = rSrc.m_sGrandParentFeature;
   m_sGreatGrandParentFeature = rSrc.m_sGreatGrandParentFeature;
   m_sShapeFile = rSrc.m_sShapeFile;
   m_bAutoCreate = rSrc.m_bAutoCreate;

   m_aColumn.RemoveAll();
   for (int i = 0; i < rSrc.m_aColumn.GetSize(); i++) m_aColumn.Add(rSrc.m_aColumn[i]);   
   return *this;
}
///////////////////////////////////////////////////////////////////////////////

BOOL CImportTable::Import(CDatabase& database, CImportDB& importDB, int nFileType)
{	
   SDWORD dwLength;   
   BOOL bOK = TRUE;
   CString sSQL;
   HSTMT hstmt;   
   int nRet;
   CFeatureType ftype;
   CAttrArray aAttr;      
   char sFeature[BD_SHORTSTR] = "";
   char sParentFeature[BD_SHORTSTR] = "";
   char sGrandParentFeature[BD_SHORTSTR] = "";
   char sGreatGrandParentFeature[BD_SHORTSTR] = "";
   char sDate[32] = "";
   char sID[32] = "";
   CDateTime date, dateDefault;
   CString sError;
   CString sProgress;
   m_nRecord = 1;   
   BOOL bCancel = FALSE;
   CMapLayer maplayer;   
   int nShape = 0;   
   m_nPrimaryKey = -1;

   m_pImportDB = &importDB;

// Retrieve attribute defintion for feature type from BEMO database

   ftype.m_sDesc = m_sFType;
   bOK = BDFeatureType(BDHandle(), &ftype, BDSELECT2);   
   if (bOK)
   {
      bOK = BDFTypeAttrInit(BDHandle(), ftype.m_lId, &aAttr);
   };   

// For DBase files construct a short file name

   CString sTable = m_sTableImport;
   if (nFileType == CImportDB::shapefile || nFileType == CImportDB::dbase)
   {
      sTable = GetShortFileTitle(database);
   }

// Count the number of records

   long lRecords = GetCountRecords(database.m_hdbc, sTable);

// Determine if shapefile data is to be loaded

   if (bOK) bOK = LoadShapefile(importDB, maplayer);
   
// Open statement
                          
   if (SQLAllocStmt(database.m_hdbc, &hstmt) == SQL_SUCCESS)
   {                 
      TRY
      {
		  // Construct SQL

       BOOL bFirst = TRUE;
       sSQL = "select ";
		 for (int i  = 0; i < m_aColumn.GetSize(); i++)
		 {			       
          if (!m_aColumn[i].m_bShapeFile)
          {
             if (!bFirst) sSQL += ", ";
			    sSQL += "`" + m_aColumn[i].m_sNameImport + "`";
             bFirst = FALSE;
          };
		 }
       if (sSQL == "select ") sSQL += "*";

       sSQL += " from `" + CString(sTable) + "`";

   // Execute statement
                        
       nRet = SQLExecDirect(hstmt, (UCHAR*)sSQL.GetBuffer(0), sSQL.GetLength()); 
      
   // Bind values to variables
      
       int iCol = 1;
		 for (i = 0; i < m_aColumn.GetSize() && nRet == SQL_SUCCESS; i++)
		 {
          // Handle date
       
          if (m_aColumn[i].m_sNameAttr == IMPORT_DATE)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sDate, sizeof(sDate), &dwLength);
          } 

          // Handle id

          else if (m_aColumn[i].m_sNameAttr == IMPORT_ID)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sID, sizeof(sID), &dwLength);
          } 
       
          // Retrieve feature name (if any)

          else if (m_aColumn[i].m_sNameAttr == m_sFeature + IMPORT_NAME)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sFeature, BD_SHORTSTR, &dwLength);                          
          }

          else if (m_aColumn[i].m_sNameAttr == m_sParentFeature  + IMPORT_NAME)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sParentFeature, BD_SHORTSTR, &dwLength);
          }

          else if (m_aColumn[i].m_sNameAttr == m_sGrandParentFeature + IMPORT_NAME)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sGrandParentFeature, BD_SHORTSTR, &dwLength);
          }
		  else if (m_aColumn[i].m_sNameAttr == m_sGreatGrandParentFeature + IMPORT_NAME)
          {
             nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, sGreatGrandParentFeature, BD_SHORTSTR, &dwLength);
          }

          // Import the corresponding shapefile data

          else if ((m_aColumn[i].m_sNameImport == SHAPEFILE_POINTS || 
                   m_aColumn[i].m_sNameImport == SHAPEFILE_POLYLINES) && 
                   m_aColumn[i].m_sNameAttr != IMPORT_SKIP)
          {                           
             m_aColumn[i].m_bAttr = TRUE;
          }          

          // Skip columns not to be imported
       
          else if (m_aColumn[i].m_sNameAttr == IMPORT_SKIP)
          {            
          }
       
          // Bind columns

          else
          {
             m_aColumn[i].m_bAttr = TRUE;

             CAttribute* pAttr = NULL;
             int iAttr = GetAttr(aAttr, m_aColumn[i].m_sNameAttr);
          
             if (iAttr == Undefined)
             {
                ASSERT(FALSE);           
                AfxThrowDBException(0,&database, hstmt);
             }

             for (int j = 0; j < aAttr.GetSize(); j++)
             {
                if (aAttr.GetAt(j)->GetAttrId() == LOWORD(iAttr))
                {
                   pAttr = aAttr.GetAt(j);
                }
             }
             ASSERT(pAttr != NULL);
             if (pAttr == NULL) AfxThrowDBException(0,&database, hstmt);

             WORD wFlag = HIWORD(iAttr);

             switch (pAttr->GetDataType())
             {
             case  BDNUMBER :                    
                   nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength); 
                   break;
             case BDTEXT :        			
			       nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, pAttr->GetString(), BD_SHORTSTR, &dwLength);                    
                   break;       

			// For long text, use SQLGetData to retrieve values

             case BDLONGTEXT :
                   nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, NULL, 0, &dwLength);                    				  
				   break;
             case BDCOORD :             
                   if (wFlag == X_COORD)
                   {
                      nRet = SQLBindCol(hstmt, iCol, SQL_C_DOUBLE, &pAttr->GetCoord()->x, sizeof(double), &dwLength);
                   } else if (wFlag == Y_COORD)
                   {
                      nRet = SQLBindCol(hstmt, iCol, SQL_C_DOUBLE, &pAttr->GetCoord()->y, sizeof(double), &dwLength); 
                   } else if (wFlag == LAT_COORD)
                   {
                      nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
                   } else if (wFlag == LON_COORD)
                   {
                      nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
                   } else if (wFlag == IMP_COORD)
                   {
                      nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
                   }

                   break;
             case BDLINK:                
                nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);
                   break;

             case BDBOOLEAN:
                nRet = SQLBindCol(hstmt, iCol, SQL_C_CHAR, m_aColumn[i].m_sText, BD_SHORTSTR, &dwLength);                
                break;             
             };             
          };
          if (!m_aColumn[i].m_bShapeFile) iCol++;
		 }
    } CATCH (CDBException, pEx)
    {
       bOK = FALSE;
    } END_CATCH

    // Set progress bar for shapefiles
    
      BDProgressRange(0,  lRecords);

	  // Retrieve the data and save it to the database

	   int nRet;
       while (!bCancel && bOK && SQL_SUCCEEDED(nRet = SQLFetch(hstmt)))
       {
		  // For longtext, retrieve data now
          
			 RetrieveLongText(hstmt, aAttr);			  
		  
          try
          {          

          // Determine feature

          long lFeature = 0;
          if (sID[0] == '\0')
          {
             lFeature = DetermineFeature(ftype.m_lId, sFeature, sParentFeature, 
                                           sGrandParentFeature, sGreatGrandParentFeature);
          } 
          else
          {
             lFeature = DetermineFeature(ftype.m_lId, sID, m_aColumn);
          }
          if (lFeature == -1) bOK = FALSE;
                    
          // Convert the date to a long

          if (sDate[0] != '\0') 
          {             
             if (!date.StringAsDate(sDate))
             {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -