importftype.cpp

来自「一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和c」· C++ 代码 · 共 549 行

CPP
549
字号
//////////////////////////////////////////////////////
//
// 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 "nrdb.h"
#include "ImportFType.h"
#include "comboboxftype.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CImportFType::CImportFType(CImportDB* pImportDB, LPCSTR sDataSource)
{
   m_pImportDB = pImportDB;   
   m_sDataSource = sDataSource;
   m_lFType = 0;
   m_lParentFType = 0;   
}

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

CImportFType::~CImportFType()
{

}

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

int CImportFType::Import()
{
   BOOL bCancel = FALSE;
   int nTables = 0;   
   BOOL bOK = TRUE;
   CString sError;
   int nImported = 0;

   // Count the number of selected tables

   for (int i = 0;i < m_pImportDB->GetSize(); i++)
   {
      if (m_pImportDB->GetAt(i).m_bImport) nTables++;
   }
   nTables *= 3;

   // Connect

   if (BDConnect(m_sDataSource, &m_hConnect))
   {      
     // Copy ftypes

   // First retrieve the projection

   if (m_projectionI.InitialiseProjection(m_hConnect))
   {
      AfxMessageBox("Converting from " + m_projectionI.GetProjectionName() +  
                 " to " + BDProjection()->GetProjectionName() + ".");
   } else
   {
      AfxMessageBox("No valid projection defined for database being imported");
      bOK = FALSE;
   }

      for (int i = 0; bOK && !bCancel && i < m_pImportDB->GetSize(); i++)
      {
         if (m_pImportDB->GetAt(i).m_bImport)
         {            
            TRY
            {
               // Import feature type definition

               bOK = ImportFTypes(m_pImportDB->GetAt(i).m_lId);
               
               if (!m_dlgProgress.SetPercent(((++nImported) * 100) / nTables)) bCancel = TRUE;                           
               m_dlgProgress.SetText(m_pImportDB->GetAt(i).m_sFType);

               if (bOK) 
               {                   
                   fprintf(m_pImportDB->m_pLogFile, BDString(IDS_IMPORTEDDEF) + ": %s\r\n", m_pImportDB->GetAt(i).m_sTableImport);

                   bOK = ImportFeatures(m_pImportDB->GetAt(i).m_lId);

                   if (!m_dlgProgress.SetPercent(((++nImported) * 100) / nTables)) bCancel = TRUE;                           

                   // Import attributes

                   if (bOK)
                   {
                      fprintf(m_pImportDB->m_pLogFile, BDString(IDS_IMPORTEDFEATURES) +  ": %s\r\n", m_pImportDB->GetAt(i).m_sTableImport);

                      bOK = ImportAttr(m_pImportDB->GetAt(i).m_lId);

                      if (bOK)
                      {
                         fprintf(m_pImportDB->m_pLogFile, BDString(IDS_IMPORTEDDATA) + 
                            ":%s\r\n", m_pImportDB->GetAt(i).m_sTableImport);

                         if (!m_dlgProgress.SetPercent(((++nImported) * 100) / nTables)) bCancel = TRUE;                           
                      }
                   }
               }                                                                                          
            }
            CATCH (CDBException, pEx)
            { 
               BDGetError(BDHandle(), sError);
               fprintf(m_pImportDB->m_pLogFile, "%s: %s\r\n",m_pImportDB->GetAt(i).m_sTableImport, (LPCSTR)sError);
            }    
            END_CATCH          
         };
      };

      BDDisconnect(m_hConnect);
   }
   
   // Reset sectors

   CComboBoxFType::InitDictionary(TRUE);

   // Return

   if (bCancel) return -1;
   return nImported/3;
}

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

BOOL CImportFType::ImportFTypes(long lFTypeI)
{
   CAttrArray aAttr;
   BOOL bOK = TRUE;
   CFeatureType ftypeI, ftype, ftypeP;
   CFTypeAttr ftypeattr;
   CDictionary dictionaryI, dictionary;


   // Determine next id
      
   BDNextId(BDHandle(), BDFTYPE, 0, &m_lFType);

   // Retrieve feature definition

   ftypeI.m_lId = lFTypeI;
   
   // Retrieve attribute definition
   
   if (BDFeatureType(m_hConnect, &ftypeI, BDSELECT) && 
       BDFTypeAttrInit(m_hConnect, ftypeI.m_lId, &aAttr))
   {
      // Check the sector exists, if it does not then add it

      dictionaryI.m_lId = ftypeI.m_lDictionary;
      BDDictionary(m_hConnect, &dictionaryI, BDSELECT);
      dictionary.m_sDesc = dictionaryI.m_sDesc;
      if (!BDDictionary(BDHandle(), &dictionary, BDSELECT2))
      {
         BDNextId(BDHandle(), BDDICTIONARY, 0, &dictionaryI.m_lId);

         BDDictionary(BDHandle(), &dictionaryI, BDADD);
         BDEnd(BDHandle());         
         ftypeI.m_lDictionary = dictionaryI.m_lId;
      } else
      {
         ftypeI.m_lDictionary = dictionary.m_lId;
      }

      // Determine the ftype parent

      if (ftypeI.m_lParentFType > 0)
      {
         m_lParentFType = GetFType(ftypeI.m_lParentFType);
         if (m_lParentFType < 0) bOK = FALSE;
      } else
      {
         m_lParentFType = 0;
      }
      
      // If the feature type exists then update the name

      int i = 1;
      m_sFType = ftypeI.m_sDesc;
      ftype.m_sDesc = m_sFType;
      if (BDFeatureType(BDHandle(), &ftype, BDSELECT2))
      {
         bOK = FALSE;
         fprintf(m_pImportDB->m_pLogFile, BDString(IDS_FEATUREEXISTS) + ": %s\r\n", ftypeI.m_sDesc);         
      }
      BDEnd(BDHandle());

      // Create feature type
      
      ftype = ftypeI;
      ftype.m_lId = m_lFType;
      ftype.m_sDesc = m_sFType;
      ftype.m_sInternal = m_sFType;
      ftype.m_lParentFType = m_lParentFType;
      if (bOK && BDFeatureType(BDHandle(), &ftype, BDADD))
      {
         // Create attribute definitions

         for (int j = 0; bOK && j < aAttr.GetSize(); j++)
         {
            ftypeattr = *(CFTypeAttr*)aAttr[j];  
            ftypeattr.m_lFType = m_lFType;

            // Match the column name to the attribute name

            ftypeattr.m_sColName = ftypeattr.m_sDesc;

            if (ftypeattr.m_lDataType == BDLINK)
            {
               long lLinkFType = GetFTypeLink(ftypeattr.GetFTypeLink());
               if (lLinkFType > 0)
               {               
                  ftypeattr.SetFTypeLink(lLinkFType);
               } else
               {
                  bOK = FALSE;
               }
            }
            if (bOK) bOK = BDFTypeAttr(BDHandle(), &ftypeattr, BDADD);
         }

         // Create corresponding table for attributes

         if (bOK)
         {
            bOK = BDFTypeCreate(BDHandle(), m_lFType);
         };            

      } else
      {
         bOK = FALSE;
      }
   } else
   {
      bOK = FALSE;
   }
   
   BDEnd(BDHandle());
   BDEnd(m_hConnect);
      
   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Returns the ftype from the ftype in the database being imported
//

long CImportFType::GetFType(long lFTypeI)
{
   BOOL bOK = TRUE;
   CFeatureType ftype, ftypeI;

   // Get the feature type

   ftypeI.m_lId = lFTypeI;
   BDFeatureType(m_hConnect, &ftypeI, BDSELECT);

   ftype.m_sDesc = ftypeI.m_sDesc;
   if (BDFeatureType(BDHandle(), &ftype, BDSELECT2))
   {         
      return ftype.m_lId;
   } else
   {
      fprintf(m_pImportDB->m_pLogFile, BDString(IDS_NOFEATURE) + ": %s\r\n", ftypeI.m_sDesc);
      bOK = FALSE;
   }
   return -1;
}

///////////////////////////////////////////////////////////////////////////////
//
// Imports features

BOOL CImportFType::ImportFeatures(long lFTypeI)
{
   CFeature feature;
   CFeatureType ftype;
   CArray <CFeature, CFeature> aFeatures;
   BOOL bOK = TRUE;
  
   // Retrieve features to be imported

   feature.m_lFeatureTypeId = lFTypeI;

   BOOL bFound = BDFeature(m_hConnect, &feature, BDGETINIT);
   while (bFound)
   {           
      aFeatures.Add(feature);

      bFound = BDGetNext(m_hConnect);
   }
   BDEnd(m_hConnect);

   // Determine if the parent features match

   ftype.m_lId = lFTypeI;   
   if (!BDFeatureType(m_hConnect, &ftype, BDSELECT) ||
       (ftype.m_lParentFType != 0 &&
        GetFTypeLink(ftype.m_lParentFType, m_lParentFType) <= 0))
   {
      bOK = FALSE;
   }
   BDEnd(m_hConnect);

   
   // Check if many to one

   ftype.m_lId = lFTypeI;
   if (BDFeatureType(m_hConnect, &ftype, BDSELECT) && 
       (ftype.m_bManyToOne || ftype.m_lParentFType == 0))
   {
      // Save the features   

      for (int i = 0; bOK && i < aFeatures.GetSize(); i++)
      {
         feature = aFeatures[i];
         feature.m_lFeatureTypeId = m_lFType;      
         bOK = BDFeature(BDHandle(), &feature, BDADD);
         BDEnd(BDHandle());
      }
   } 
   BDEnd(m_hConnect);

   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Determines which feature type the link belongs to 
// Returns the ftype or -1 if not found
//

long CImportFType::GetFTypeLink(long lFTypeI, long lFType)
{
   CFeature feature;
   CFeatureType ftype;
   CArray <CFeature, CFeature> aFeatures;
   BOOL bOK = TRUE;

   // If the feature type is undefined then determine its value

   if (lFType == 0)
   {
      lFType = GetFType(lFTypeI);
      if (lFType < 0) return -1;
   }

   // Retrieve features of the link type

   feature.m_lFeatureTypeId = lFTypeI;

   BOOL bFound = BDFeature(m_hConnect, &feature, BDGETINIT);
   while (bFound)
   {
      feature.m_sName.TrimRight();
      aFeatures.Add(feature);

      bFound = BDGetNext(m_hConnect);
   }
   BDEnd(m_hConnect);

   // Determine if the features match

   for (int i = 0; bOK && i < aFeatures.GetSize(); i++)
   {      
      feature.m_lFeatureTypeId = lFType;
      feature.m_lId = aFeatures[i].m_lId;
      BDFeature(BDHandle(), &feature, BDSELECT);
      feature.m_sName.TrimRight();

      if (feature.m_sName != aFeatures[i].m_sName)
      {
         ftype.m_lId = lFTypeI;
         BDFeatureType(m_hConnect, &ftype, BDSELECT);
         aFeatures[i].m_sName.TrimRight();
         fprintf(m_pImportDB->m_pLogFile, BDString(IDS_NOMATCH) + ":%s, %s\r\n",aFeatures[i].m_sName, ftype.m_sDesc);
         bOK = FALSE;
      }
   }

   if (!bOK) return -1;
   else return lFType;
}

///////////////////////////////////////////////////////////////////////////////
//
// Imports the data for the feature type
//

BOOL CImportFType::ImportAttr(long lFTypeI)
{
   CAttrArray aAttrI, aAttrL, aAttr;
   CFTypeAttr ftypeattr;
   BOOL bOK = TRUE;   
  
   // Copy data
   
   bOK = BDFTypeAttrInit(BDHandle(), m_lFType, &aAttrL);   

   // Save the data

   aAttrI.m_lFType = lFTypeI;
   BOOL bFound = BDAttribute(m_hConnect, &aAttrI, BDGETINIT);
   while (bFound && bOK)
   {
      // Update the link ftypes

      aAttr = aAttrI;
      aAttr.m_lFType = m_lFType;
      for (int i = 0; i < aAttrI.GetSize(); i++)
      {                  
         aAttr[i]->SetFTypeId(m_lFType);
         aAttr[i]->m_sColName = aAttr[i]->m_sDesc;
         if (aAttr[i]->GetDataType() == BDLINK)
         {
            aAttr[i]->SetFTypeLink(aAttrL[i]->GetFTypeLink());
         };
      };

      // Make the internal name the same as the external

      aAttr.SetFTypeInternal(aAttr.GetFTypeName());

      // Convert to the current projection

      ConvertProjection(aAttr);

      // Save the value

      bOK = BDAttribute(BDHandle(), &aAttr, BDADD);
      BDEnd(BDHandle());

      // Retrieve next

      bFound = BDGetNext(m_hConnect);
   }
   BDEnd(BDHandle());
   BDEnd(m_hConnect);

   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Convert the projection from that of the database being imported from to
// that being imported to
//

BOOL CImportFType::ConvertProjection(CAttrArray& aAttr)
{
   BOOL bOK = TRUE;
   for (int i = 0; i < aAttr.GetSize(); i++)
   {
      if (aAttr.GetAt(i)->GetDataType() == BDCOORD)
      {
         // Convert coord
         
         if (!aAttr.GetAt(i)->GetCoord()->IsNull())
         {
            ConvertProjection(*aAttr.GetAt(i)->GetCoord());
         }          
         else
         {
            // Convert to psuedo null from dbl_max for compatability
            // with other databases

            aAttr.GetAt(i)->GetCoord()->SetNull();
         }
      } else if (aAttr.GetAt(i)->GetDataType() == BDMAPLINES)
      {         
         CLongBinary* pLongBin = aAttr.GetAt(i)->GetLongBinary();
         CLongLines maplines(*pLongBin);

         for (int j = 0; j < maplines.GetSize(); j++)
         {
            if (!maplines.GetAt(i).IsNull())
            {
               ConvertProjection(maplines.GetAt(j));
            } else
            {
               maplines.GetAt(j).SetNull();
            }
         }

         // Convert back

         maplines.GetLongBinary(*aAttr.GetAt(i)->GetLongBinary());


      }
   }
   return bOK;
};

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

void CImportFType::ConvertProjection(CLongCoord& coord)
{
  // Convert to latlon

   double dLat, dLon;

   m_projectionI.TransMercatorToLatLon(coord.x, coord.y, &dLat, &dLon);
   BDProjection()->LatLonToTransMercator(dLat, dLon, &coord.x,  &coord.y);
}

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

void CImportFType::ConvertProjection(CCoord& coord)
{
   // Convert to latlon

   double dLat, dLon;

   m_projectionI.TransMercatorToLatLon(coord.x, coord.y, &dLat, &dLon);
   BDProjection()->LatLonToTransMercator(dLat, dLon, &coord.x,  &coord.y);
}

⌨️ 快捷键说明

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