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

📄 query.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      if (pElement->GetSelected())
      {
         bFound = FALSE;

          // Feature name
                  
         if ((long)pElement->GetDataType() == BDFEATURE ||
             (long)pElement->GetDataType() == BDFTYPE)
         {
            bFound = TRUE;
         }          

         // Date

         if ((long)pElement->GetDataType() == BDDATE)
         {
            CAttribute* pAttr = new CAttribute(BDDATE);         
            pAttr->SetAttrId(BDDATE);            
            pAttr->SetFTypeId(pQuery->GetFType());
            pAttr->SetDate(aAttr.m_lDate);
            CDateTime date(aAttr.m_lDate, 0);            
            date.DateAsString(sDate);            
            pAttr->SetDesc(sDate.GetBuffer(0));
            pAttrArray->Add(pAttr);
            bFound = TRUE;
         }

         // Other attributes
         
         for (int j = 0; !bFound && j < aAttr.GetSize(); j++)
         {
            if (aAttr[j]->GetAttrId() == pElement->GetAttrId())
            {
               CAttribute* pAttr = new CAttribute(aAttr[j]->GetDataType());
               *pAttr = *aAttr[j];
            
               pAttrArray->Add(pAttr);                              
               bFound = TRUE;
            };
         };                     
      }   
      // Store the date of the data
      
      pAttrArray->m_dateActive = CDateTime(aAttr.m_lDate, 0);      

      // Get next element

      pElement = pElement->GetNextQuery();
   }
   while (pElement != NULL && pElement->GetDataType() != BDFTYPE);

   // Retrieve data for statistics

   pElement = m_pQuery;
   while (pElement != NULL)
   {
      if (pElement->GetDataType() == BDQUERYSTATS)
      {
         CQueryStats* pStats = (CQueryStats*)pElement;
         for (int j = 0; j < aAttr.GetSize(); j++)
         {
            if ((aAttr[j]->GetAttrId() == pStats->GetAttrId() &&
                aAttr[j]->GetFTypeId() == pStats->GetFTypeId()) ||
                (aAttr[j]->GetAttrId() == pStats->GetAttrId2() &&
                 aAttr[j]->GetFTypeId() == pStats->GetFTypeId2()))
            {
               CAttribute* pAttr = new CAttribute(aAttr[j]->GetDataType());
               *pAttr = *aAttr[j];               
            
               pAttrArray->Add(pAttr);                              
               bFound = TRUE;
            };
         };                     
      }
      pElement = pElement->GetNextQuery();
   };


   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// For each attribute, if it has no value assigned then assign its value can
// be replaced with another attribute meeting the required conditions
//

BOOL CQueryResult::RetrieveMissing(CQuery* pQuery, CAttrArray& aAttr, 
                                CQueryAttrArray* pAttrArray)
{
   BOOL bOK = TRUE;

   for (int i = 0; i < aAttr.GetSize(); i++)
   {
      for (int j = 0; j < pAttrArray->GetSize(); j++)
      {
         if (aAttr[i]->GetFTypeId() == pAttrArray->GetAt(j)->GetFTypeId() &&
             aAttr[i]->GetAttrId() == pAttrArray->GetAt(j)->GetAttrId())
         {
            CAttribute* pAttr = pAttrArray->GetAt(j);
            if (pAttr->IsNull() && !aAttr[i]->IsNull())
            {
             // Only do this for coordinate and maplines, otherwise
             // user may be confused when value is presented with wrong date

               if (pAttr->GetDataType() == BDMAPLINES || pAttr->GetDataType() == BDCOORD)
               {
                  delete pAttr;
                  pAttr = new CAttribute(aAttr[i]->GetDataType());
                  *pAttr = *aAttr[i];            
                  pAttrArray->SetAt(j, pAttr);
               };
            }
         }             
      }
   }

   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Retrieves the feature names if selected
//

void CQueryResult::InitNullAttr(CQuery* pQuery, CAttrArray& aAttr, CQueryAttrArray* pAttrArray)
{
   // Determine which attributes are required
   
   CQueryElement* pElement = pQuery;   

   ASSERT(pElement != NULL);   
   do
   {                            
      if (pElement->GetSelected())
      {
          // Feature name

         if ((long)pElement->GetDataType() == BDFEATURE ||
             (long)pElement->GetDataType() == BDFTYPE)
         {
			 // Skip
         }        
         else if ((long)pElement->GetDataType() == BDDATE)
         {
            // Add blank date

            CAttribute* pAttr = new CAttribute(BDDATE);         
            pAttr->SetAttrId(BDDATE);            
            pAttr->SetFTypeId(pQuery->GetFType());            
            pAttr->SetDesc("");
            pAttrArray->Add(pAttr);            
         }
         else
         {
            // Add blank attribute

            for (int j = 0; j < aAttr.GetSize(); j++)
            {
               if (aAttr[j]->GetAttrId() == pElement->GetAttrId())
               {
                  CAttribute* pAttr = new CAttribute(aAttr[j]->GetDataType());                                
                  pAttr->SetDesc(aAttr[j]->GetDesc());
                  pAttrArray->Add(pAttr);                              
                  break;
               };
            };                     
         };
      };
       pElement = pElement->GetNextQuery();
   }
   while (pElement != NULL && pElement->GetDataType() != BDFTYPE);

}

///////////////////////////////////////////////////////////////////////////////
//
// Performs calculations whereby two attributes for the same feature will
// be combined using a mathematic operator
//

void CQueryResult::CalcRowBasedStats()
{
   int iAttr = -1;

   // Find whether statistics are required

   CQueryElement* pElement = m_pQuery;
   while (pElement != NULL)
   {
      if (pElement->GetDataType() == BDQUERYSTATS)
      {
         int nDP = 0;

         CQueryStats* pStats = (CQueryStats*)pElement;
         
         for (int i = 0; i < GetSize(); i++)
         {
            CalcRowBasedStats(pStats, *GetAt(i), iAttr, nDP);
         }
         iAttr--; 
      }        
      pElement = pElement->GetNextQuery();
   }
}

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

void CQueryResult::CalcRowBasedStats(CQueryStats* pStats, CQueryAttrArray& aAttr, int iAttr, int nDP)
{
   CAttribute *pAttr1 = NULL, *pAttr2 = NULL;   
   double d1 = 0, d2 = 0;
   int iAttr1 = -1, iAttr2 = -1;

  // Find attributes used for the statistic

    for (int i = 0; i < aAttr.GetSize(); i++)
    {
       if (aAttr.GetAt(i)->GetFTypeId() == pStats->GetFTypeId() &&
           aAttr.GetAt(i)->GetAttrId() == pStats->GetAttrId())
       {
          pAttr1 = aAttr.GetAt(i);          
          iAttr1 = i;
       }
       if (aAttr.GetAt(i)->GetFTypeId() == pStats->GetFTypeId2() &&
           aAttr.GetAt(i)->GetAttrId() == pStats->GetAttrId2())
       {
          pAttr2 = aAttr.GetAt(i);          
          iAttr2 = i;
       }
    }    

    // Determine if a value is to be used

    if (pStats->GetAttrId() == 0) d1 = pStats->GetValue1();
    if (pStats->GetAttrId2() == 0) d2 = pStats->GetValue2();

    // Perform calculation

    double dResult = AFX_RFX_DOUBLE_PSEUDO_NULL;

    // Numeric statistic

    if (pStats->GetAttrId() == 0 || pAttr1->GetDataType() == BDNUMBER)
    {
       if (pAttr1 != NULL) d1 = *pAttr1->GetDouble();
       if (pAttr2 != NULL) d2 = *pAttr2->GetDouble();

       // Check for divide by zero

       if ((pStats->GetStatistic() == CQueryStats::divide || 
           pStats->GetStatistic() == CQueryStats::percent) && 
           d1 == 0)
       {
          // Ignore
       }
       else if (d1 != AFX_RFX_DOUBLE_PSEUDO_NULL && 
           d2 != AFX_RFX_DOUBLE_PSEUDO_NULL)
       {       
          switch(pStats->GetStatistic())
          {
             case CQueryStats::add : dResult = d1+d2; break;
             case CQueryStats::subtract : dResult = d1-d2; break;
             case CQueryStats::multiply : dResult = d1*d2; break;
             case CQueryStats::divide : if (d2 != 0) dResult = d1/d2; break;
             case CQueryStats::percent : if (d2 != 0) dResult = d1/d2*100; break;
          }
       };        
    }
        
    dResult = SetDP(dResult, pStats->GetDecPlaces());
  
    // Substitute values for result

    CAttribute* pAttr = new CAttribute(BDNUMBER);
    pAttr->SetDouble(dResult);
    pAttr->SetDesc(pStats->GetDesc());
    pAttr->SetAttrId(iAttr);
    pAttr->SetFTypeId(m_pQuery->GetFType());
    aAttr.Add(pAttr);    

  // Remove the attributes from the list 
    
   if (pAttr1 != NULL)
   {
     aAttr.RemoveAt(iAttr1);
     delete pAttr1;      
   };

   if (pAttr1 != pAttr2 && pAttr2 != NULL)
   {
     if (iAttr2 > iAttr1 && iAttr1 != -1) iAttr2--;
     aAttr.RemoveAt(iAttr2);
     delete pAttr2;       
   };   
}


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

double CQueryResult::SetDP(double dResult, int nDP)
{
   int n = 1;
   for (int i = 0; i < nDP; i++) n *= 10;
   
   return floor(dResult * n + 0.5) / n;
}

///////////////////////////////////////////////////////////////////////////////
//
// This routine will sort the results of the query according to the selected
// elements
//

void CQueryResult::SortQueryResults()
{
   CQueryResult aSorted;

   BDProgressRange(0, GetSize());
   BDProgressText("Sorting...");

   for (int i = 0; i < GetSize(); i++)
   {
      for (int j = 0; j < aSorted.GetSize(); j++)
      {
         if (Compare(GetAt(i), aSorted[j]) >= 0)
         {            
            break;
         }
      }      
      aSorted.InsertAt(j, GetAt(i));

      BDProgressPos(i);
   }
   // When removing don't use RemoveAllX as pointers are preserved

   RemoveAll(); 
   Copy(aSorted);
   aSorted.RemoveAll();

   BDProgressRange(0, 0);
}

///////////////////////////////////////////////////////////////////////////////
//
// Compares two arrays of attributes according to the items selection in CQuery
// returns 0 if they are equal, or negative if A occurs first or positive if
// B occurs first.
//

int CQueryResult::Compare(CQueryAttrArray* pAttrA, CQueryAttrArray* pAttrB, int nSortId)
{
   int nCompare = 0;   
   int nAttrStats = 0;
   BOOL bFound = FALSE;

   // Sort by multiple attributes from 1 upwards until none found

   for (int i = 0; i < m_aAttrSel.GetSize(); i++)
   {
      if (m_aAttrSel[i].m_nSortBy == nSortId)
      {
         bFound = TRUE;

         // Search for attribute

         for (int j = 0; j < pAttrA->GetSize(); j++)
         {
            CAttribute* pA = pAttrA->GetAt(j);
            CAttribute* pB = pAttrB->GetAt(j);

            if (pA->GetAttrId() == m_aAttrSel[i].m_lAttr &&
                pA->GetFTypeId() == m_aAttrSel[i].m_lFType)
            {
               nCompare = Compare(pA, pB);
               break;
            }
         };
         break;            
      }      
   }

   // If the results are the same then check if there is another sort attribute

   if (nCompare == 0)
   {
      for (int i = 0; i < m_aAttrSel.GetSize(); i++)
      {
         if (m_aAttrSel[i].m_nSortBy == nSortId+1)
         {
            nCompare = Compare(pAttrA, pAttrB, nSortId+1);
            break;
         };
      }
   };

   return nCompare;
}

///////////////////////////////////////////////////////////////////////////////
//
// Compares two attributes

int CQueryResult::Compare(CAttribute* pA, CAttribute* pB)
{
   int nCompare = 0;   

   // Numbers

   if (pA->GetDataType() == BDNUMBER)
   {
      if (*pA->GetDouble() != AFX_RFX_DOUBLE_PSEUDO_NULL && 
          *pB->GetDouble() != AFX_RFX_DOUBLE_PSEUDO_NULL)
      {
         if (*pA->GetDouble() < *pB->GetDouble()) nCompare = 1;
         else if (*pA->GetDouble() > *pB->GetDouble()) nCompare = -1;
      }
      else if (*pA->GetDouble() == AFX_RFX_DOUBLE_PSEUDO_NULL &&
               *pB->GetDouble() != AFX_RFX_DOUBLE_PSEUDO_NULL)
      {
         nCompare = 1;
      }
      else if (*pA->GetDouble() != AFX_RFX_DOUBLE_PSEUDO_NULL &&
               *pB->GetDouble() == AFX_RFX_DOUBLE_PSEUDO_NULL)
      {
         nCompare = -1;
      }

   }

   // Dates
   else if (pA->GetDataType() == BDDATE)
   {
      if (CDateTime(*pA->GetDate(),0) < CDateTime(*pB->GetDate(),0)) nCompare = 1;
      else if (CDateTime(*pA->GetDate(),0) > CDateTime(*pB->GetDate(),0)) nCompare = -1;                  

   }

   // Compare map lines

   else if (pA->GetDataType() == BDMAPLINES)
   {
      CLongBinary *pLongBin1 = pA->GetLongBinary();
      CLongBinary *pLongBin2 = pB->GetLongBinary();

      if (pLongBin1->m_dwDataLength == pLongBin2->m_dwDataLength)
      {
         CLongLines maplines1(*pLongBin1);
         CLongLines maplines2(*pLongBin2);

         

⌨️ 快捷键说明

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