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

📄 query.cpp

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

CString CQuery::GetQueryName()
{
	CString sFeature, sAttr, sName;
	int iFeature = 0;
	int iAttr = 0;
   long lParentFeature = 0;
   CFeature feature;
   CFeatureType ftype;   
    
	// Feature type name

	CQueryElement* pElement = this;
	while (pElement != NULL)
	{
	   // Determine how many features are selected, if only one then include
	   // in name

       if (pElement->GetDataType() == BDFEATURE)
	   {
		  CQueryLink* pLink = (CQueryLink*)pElement;
		  for (int i = 0; i < pLink->m_aFeatures.GetSize(); i++)
		  {
			  if (pLink->m_aFeatures.GetAt(i).GetSelected())
			  {
				  iFeature++;
				  sFeature = pLink->m_aFeatures.GetAt(i).m_sName;

              if (lParentFeature == 0)
                 lParentFeature = pLink->m_aFeatures.GetAt(i).m_lParentFeature;
              else if (lParentFeature != pLink->m_aFeatures.GetAt(i).m_lParentFeature)
                 lParentFeature = -1;
			  }           
		  }		  
	   }

	   // Determine how many attributes are selected, if only one then include in name

	   if (pElement->GetSelected() && (pElement->GetDataType() == BDNUMBER ||
          pElement->GetDataType() == BDTEXT || 
		  pElement->GetDataType() == BDLONGTEXT ||
          pElement->GetDataType() == BDLINK ||
          pElement->GetDataType() == BDBOOLEAN))
	   {
		   iAttr++;
		   sAttr = pElement->GetDesc();
	   }

      if (pElement->GetDataType() == BDQUERYSTATS)
      {
         iAttr++;
         sAttr = pElement->GetDesc();
      }
	          
	   pElement = pElement->GetNextQuery();
	}

	// Create name
   
	if (iAttr == 1)
	{
	   sName = sAttr;
	}

   // Add feature name

   if (iFeature == 1)
   {
      sFeature.TrimRight();
      sName = sFeature;
   }

   if (sName == "") sName = GetDesc();

   // If only one parent feature then include in the name

   if (lParentFeature > 0)
   {  
      BDFTypeParentI(BDHandle(), m_lFType, &ftype);
      feature.m_lId = lParentFeature;
      feature.m_lFeatureTypeId = ftype.m_lId;
      BDFeature(BDHandle(), &feature, BDSELECT);
      BDEnd(BDHandle());
      feature.m_sName.TrimRight();
      sName += ", " + feature.m_sName;
   }	

   // Strip square brackets
   
   CString str = CQuery::StripBrackets(sName);   

   return str;
}

///////////////////////////////////////////////////////////////////////////////
//
// For each feature in the query add an attribute array to the list
//

BOOL CQueryResult::InitFeatures(CQuery* pQuery)
{
   CQueryElement* pElement = pQuery;
   while (pElement != NULL)
   {
      if (pElement->GetDataType() == BDFEATURE)
      {
         CQueryLink* pLink = (CQueryLink*)pElement;
         for (int i = 0; i < pLink->m_aFeatures.GetSize(); i++)
         {
            CQueryFeature *pFeature = &pLink->m_aFeatures[i];
            if (pFeature->GetSelected())
            {
               CQueryAttrArray* pQAA = new CQueryAttrArray(pFeature->m_sName);
               pQAA->m_lFeature = pFeature->m_lId;
               pQAA->m_lFeatureActive = pFeature->m_lId;
               pQAA->m_sFeature = pFeature->m_sName;
               pQAA->m_sFeatureActive = pFeature->m_sName;                
               pQAA->m_lParentFeatureActive = pFeature->m_lParentFeature;

               Add(pQAA);
            }
         }
         break;
      };
      pElement = pElement->GetNextQuery();
   };

   return pElement != NULL;
}

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

BOOL CQueryResult::RetrieveData(CQuery* pQuery)
{
   BOOL bOK = TRUE;   
   CFeature feature;
   CFeatureType ftype;

   m_bBaseFType = TRUE;
 
   // Firstly determine which attributes are selected for all feature types
   
   CQueryElement* pElement = pQuery;
   int iAttr = -1;
   while (pElement != NULL)
   {      
      CQueryAttrSel attrsel;

      if (pElement->GetSelected())
      {                         
         attrsel.m_lAttr = pElement->GetAttrId();
         attrsel.m_lFType = pElement->GetFTypeId();
         attrsel.m_lDataType = pElement->GetDataType();                        
      };      
      
      if (pElement->GetDataType() == BDQUERYSTATS)
      {
         attrsel.m_lAttr = iAttr--;
         attrsel.m_lFType = m_pQuery->GetFTypeId();
         attrsel.m_lDataType = BDNUMBER;
      }

      if (pElement->GetSelected() || pElement->GetDataType() == BDQUERYSTATS)
      {
         attrsel.m_nGroupBy = pElement->GetGroupBy();
         attrsel.m_nSortBy = pElement->GetSortBy();
         attrsel.m_nStatGroup = pElement->GetGroupStat();      

         m_aAttrSel.Add(attrsel);               
      };      

      pElement = pElement->GetNextQuery();      
   };

   // Retrieve the data for these attributes, even if no attributes are
   // selected as the feature may be removed if conditions are not met

      bOK = LoadDataAll(pQuery, pQuery->GetFType());

    // Set the date

      for (int i = 0; i < GetSize(); i++)
      {         
         if (GetAt(i)->m_dateActive.IsValid())
         {
            GetAt(i)->m_lDate = GetAt(i)->m_dateActive.GetDateLong();         
         };
      };

   // Retrieve attributes for remaining feature types   

   m_bBaseFType = FALSE;

   while (bOK && pQuery != NULL)
   {     
     // Determine if the feature is one to one or one to many

      ftype.m_lId = pQuery->GetFType();
      BDFeatureType(BDHandle(), &ftype, BDSELECT);
      BDEnd(BDHandle());

     // Determine next element

      pQuery = (CQuery*)pQuery->GetNextQuery();
      while (pQuery != NULL && pQuery->GetDataType() != BDFTYPE)
      {
         pQuery = (CQuery*)pQuery->GetNextQuery();
      }

      if (pQuery != NULL)
      {
         // Reset dates

         for (i = 0; i < GetSize(); i++)
         {
            GetAt(i)->m_dateActive = CDateTime(0,0);
         };       

        // Change the active feature to the parent feature for the type     

         if (ftype.m_bManyToOne)
         {
           // Update active features

            for (int i = 0; i < GetSize(); i++)
            {
               GetAt(i)->m_lFeatureActive = GetAt(i)->m_lParentFeatureActive;               
            }

			// Reset the parent names incase parent feature cannot be found!

		   for (i = 0; i < GetSize(); i++)
		   {
			   GetAt(i)->m_sFeatureActive = "";
		   }

            // Update name and parent of features

            feature.m_lFeatureTypeId = pQuery->GetFType();
            BOOL bFound = BDFeature(BDHANDLE(), &feature, BDSELECT2);
            while (bFound)
            {
               for (int i = 0; i < GetSize(); i++)
               {
                  if (GetAt(i)->m_lFeatureActive == feature.m_lId)
                  {
                     GetAt(i)->m_lParentFeatureActive = feature.m_lParentFeature;
                     GetAt(i)->m_sFeatureActive = feature.m_sName;
                  }
               };
               bFound = BDGetNext(BDHandle());
            }
            BDEnd(BDHandle());
         };
         
         // Retrieve the data for the parent feature type
         
         ASSERT(pQuery->GetDataType() == BDFTYPE);
         bOK = LoadDataAll(pQuery, pQuery->GetFType());      
      };
   };

   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// This is a faster way of retrieving large numbers of values.  
// Retrieves the attributes for all features rather than querying for every one
//

BOOL CQueryResult::LoadDataAll(CQuery* pQuery, long lFType)
{
   CAttrArray aAttr;   
   CFeature feature;   
   BOOL bOK = TRUE;
   long lFeatureMin, lFeatureMax;
   int iCount = 0;

   // Display name of ftype

   CString s = pQuery->GetDesc();
   BDProgressText("Loading " + s.Left(s.Find('[')) + "...");

   // No need to load if no features

   if (GetSize() == 0) return FALSE;

    // Retrieve the selected feature names for the query

   for (int i = 0; i < GetSize(); i++)
   {
      RetrieveFeatures(pQuery, GetAt(i));      
   }

   // If no attributes or conditions selected then no need to load data
   // This also handles where parent features have no attributes set

   int nRet = IsFTypeSelected(pQuery, lFType);
   if (!m_bBaseFType && nRet != yes)
   {
      return TRUE;
   }

   // Re-initialise the 'conditions met' flags

   for (i = 0; i < GetSize(); i++)
   {
      CQueryAttrArray* pAttrArray = GetAt(i);
      pAttrArray->SetCondMet(FALSE);
   }

   // Determine the maximum and minimum feature ids

   ASSERT(GetSize() > 0);
   lFeatureMax = lFeatureMin = GetAt(0)->GetActiveFeature();
   for (i = 0; i < GetSize(); i++)
   {           
      lFeatureMin = min(lFeatureMin, GetAt(i)->GetActiveFeature());
      lFeatureMax = max(lFeatureMax, GetAt(i)->GetActiveFeature());    
   }

   // Initialise attribute array 

   BDFTypeAttrInit(BDHandle(), lFType, &aAttr);

   // Retrieve all data and then extract what is needed   
   
   BDProgressRange(0, GetSize());
   
    CString sFilter;
    sFilter = GetQueryFilter(pQuery, aAttr);
    BOOL bFound = BDAttributeCond(BDHandle(), &aAttr, lFeatureMin, lFeatureMax, sFilter, BDGETINIT);

   
   while (bFound && bOK)
   {
     // For each record, determine whether the feature is selected

      for (int i = 0; i < GetSize(); i++)
      {
         CQueryAttrArray* pAttrArray = GetAt(i);
         if (aAttr.m_lFeature == pAttrArray->GetActiveFeature())
         {                 
            // Check the conditions imposed are valid
            
            if (CheckConditions(pQuery, aAttr)
                && CheckValueCond(pQuery, aAttr)
               )
            {             
               // Check the conditions are met

               pAttrArray->SetCondMet();

               // If so determine whether the data is to replace the existing
               // data, or to be created as a new feature

               int nStatus = UpdateDates(pQuery, aAttr, pAttrArray);
               if (nStatus == Replace)
               {                              
                  RetrieveAttr(pQuery, aAttr, pAttrArray);                            
               }

               // If a new reading then set the count to the penultimate value
               // to prevent more than one new value being created

               else if (nStatus == New)
               {
                  i = GetSize()-2;
               }

               // Where the required data already exists, fill in missing attributes

               else if (nStatus == Keep)
               {
                  RetrieveMissing(pQuery, aAttr, pAttrArray);
               }

               if (!BDProgressPos(iCount++)) bOK = FALSE;
               if (iCount >= GetSize()) 
               {                  
                  iCount = 0;
                  BDProgressRange(0,GetSize());
               };
            }          
         }
      }

      bFound = BDGetNext(BDHandle());      
   }
   BDEnd(BDHandle());   
   BDProgressRange(0,0);
   
   // Remove all features with no data
   
   for (i = 0; i < GetSize(); i++)
   {       
      CQueryAttrArray* pAttrArray = GetAt(i);
      if (!pAttrArray->GetCondMet())
      {           
         if (!m_pQuery->IsShowAllFeatures())
         {
            delete pAttrArray; 
            RemoveAt(i);
            i--;         
         } else
         {
            InitNullAttr(pQuery, aAttr, pAttrArray);
         }
      };
   };
   
   return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Creates a filter for the SQL query to optimise the retrieval of data 
// accordinate to conditions
//

CString CQueryResult::GetQueryFilter(CQuery* pQuery, CAttrArray& aAttr)
{
   CString sFilter;   

   CQueryElement* pElement = pQuery->GetNextQuery();
   while (pElement != NULL)
   {
      if (pElement->GetCond() != CQueryElement::none)
      {        
         // Find the corresponding attribute

         for (int i = 0; i < aAttr.GetSize(); i++)
         {
            if (aAttr.GetAt(i)->GetAttrId() == pElement->GetAttrId() && 
                aAttr.GetAt(i)->GetFTypeId() == pElement->GetFTypeId())
            {           
               // Check numerical conditions

               if (aAttr.GetAt(i)->GetDataType() == BDNUMBER)
               {
                  double dValue = *aAttr.GetAt(i)->GetDouble();
                  double dCondValue = pElement->GetCondValue();

                  // Column name

                  if (sFilter != "") sFilter += " and ";
                  sFilter += "`" + CString(pElement->GetColName()) + "`";

                  // Condition

                  switch (pElement->GetCond())
                  {

⌨️ 快捷键说明

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