📄 query.cpp
字号:
//////////////////////////////////////////////////////
//
// 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 "query.h"
#include "bdimportexport.h"
#include "bdattribute.h"
#include "projctns.h"
///////////////////////////////////////////////////////////////////////////////
#define SQUARE(x) x*x
#define GROUP -100
#define STATISTIC -101
#define COUNT -102
#define COMPDOUBLE 1e-10
///////////////////////////////////////////////////////////////////////////////
CQueryDate CQuery::m_aQueryDates[] = {{AllDates, "All data"},
{FirstDate, "Earliest data"},
{LastDate, "Latest data"},
{FirstDateRange, "First data in range"},
{LastDateRange, "Last data in range"},
{AllDatesRange, "All data in range"},
{AllDatesAfter, "All data after"},
{AllDatesBefore, "All data before"},{-1,""}};
///////////////////////////////////////////////////////////////////////////////
CQuery::CQuery()
{
m_lFType = 0;
m_nDateCond = LastDate;
m_bShowAllFeatures = FALSE;
}
///////////////////////////////////////////////////////////////////////////////
CQuery::~CQuery()
{
CQueryElement::Delete(m_pNext);
}
///////////////////////////////////////////////////////////////////////////////
CQuery::CQuery(CQuery& rSrc) : CQueryElement(rSrc)
{
*this = rSrc;
}
///////////////////////////////////////////////////////////////////////////////
//
// Initialise a query using the results from a standard report dialog
//
CQuery::CQuery(long lFType, CArray <long, long>& alAttr, CArray <long, long>& alFeatures, int nSortBy)
{
// Convert the list of attributes to a list of attribute selections (includes
// feature type)
CArrayAttrSel aAttr;
for (int i = 0; i < alAttr.GetSize(); i++)
{
CQueryAttrSel attrsel;
attrsel.m_lFType = lFType;
attrsel.m_lAttr = alAttr[i];
aAttr.Add(attrsel);
}
*this = CQuery(lFType, aAttr, alFeatures, nSortBy);
}
///////////////////////////////////////////////////////////////////////////////
CQuery::CQuery(long lFType, CArrayAttrSel& aAttr, CArray <long, long>& alFeatures, int nSortBy)
{
// Initialise query
Initialise(lFType);
// Set date condition
BOOL bDate = FALSE;
for (int i = 0; i < aAttr.GetSize(); i++)
{
if (aAttr[i].m_lAttr == BDDATE)
{
bDate = TRUE;
break;
}
}
if (bDate) SetDateCond(CQuery::AllDates);
else SetDateCond(CQuery::LastDate);
// Select attributes to be displayed
CQueryElement* pQueryElement = this;
while (pQueryElement != NULL)
{
// Select feature
for (int i = 0; i < aAttr.GetSize(); i++)
{
if (pQueryElement->GetFTypeId() == aAttr[i].m_lFType)
{
if ((pQueryElement->GetAttrId() == aAttr[i].m_lAttr &&
pQueryElement->GetDataType() != BDFEATURE) ||
(pQueryElement->GetDataType() == BDFTYPE &&
aAttr[i].m_lAttr == BDFEATURE))
{
pQueryElement->SetSelected();
}
if (pQueryElement->GetAttrId() == nSortBy)
{
pQueryElement->SetSortBy(1);
};
};
}
pQueryElement = pQueryElement->GetNextQuery();
}
// Update the selected features
CQueryElement* pElement = this;
while (pElement != NULL)
{
if (pElement->GetDataType() == BDFEATURE)
{
CQueryLink* pLink = (CQueryLink*)pElement;
for (int i = 0; i < pLink->m_aFeatures.GetSize(); i++)
{
pLink->m_aFeatures[i].SetSelected(FALSE);
for (int j = 0; j < alFeatures.GetSize(); j++)
{
if ((long)alFeatures.GetAt(j) == pLink->m_aFeatures[i].m_lId)
{
pLink->m_aFeatures[i].SetSelected(TRUE);
break;
}
}
}
}
pElement = pElement->GetNextQuery();
}
}
///////////////////////////////////////////////////////////////////////////////
CQuery& CQuery::operator=(CQuery& rSrc)
{
CQueryElement::Delete(m_pNext);
m_lFType = rSrc.m_lFType;
m_nDateCond = rSrc.m_nDateCond;
m_bShowAllFeatures = rSrc.m_bShowAllFeatures;
m_dtStart = rSrc.m_dtStart;
m_dtEnd = rSrc.m_dtEnd;
(CQueryElement&)*this = (CQueryElement&)rSrc;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
void CQuery::Initialise(long lFType)
{
BOOL bInitFeatures = FALSE;
BOOL bInitDates = FALSE;
Initialise(lFType, bInitFeatures, bInitDates);
}
///////////////////////////////////////////////////////////////////////////////
void CQuery::Initialise(long lFType, BOOL& bInitFeatures, BOOL& bInitDates)
{
CAttrArray aAttr;
CFeatureType ftype;
CQueryElement* pPrevElement = NULL;
// Reset dates parameters
m_nDateCond = LastDate;
m_bShowAllFeatures = FALSE;
// Loads the elements according to the feature type
CQueryElement::Delete(m_pNext);
m_lFType = lFType;
// Retrieve feature type description
ftype.m_lId = lFType;
BDFeatureType(BDHandle(), &ftype, BDSELECT);
BDEnd(BDHandle());
// Retrieve the attributes for the feature type
if (BDFTypeAttrInit(BDHandle(), lFType, &aAttr))
{
// First element is the feature type
SetDesc(aAttr.GetFTypeName() + CString(" [" + BDString(IDS_NAME)+ "]"));
SetDataType(BDFTYPE);
SetFTypeId(lFType);
SetAttrId(BDFEATURE);
pPrevElement = this;
CQueryElement* pElement = NULL;
// Next element is the features of the feature type, only provide one
// list of features
if (ftype.m_bManyToOne && !bInitFeatures)
{
pElement = new CQueryLink(lFType);
pElement->SetDesc(aAttr.GetFTypeName() + CString(" ["+ BDString(IDS_NAME) + "]"));
pElement->SetDataType(BDFEATURE);
pElement->SetAttrId(BDFEATURE);
pElement->SetFTypeId(lFType);
pPrevElement->SetNextQuery(pElement);
pPrevElement = pElement;
bInitFeatures = TRUE;
};
// Initialise dates
if (!bInitDates)
{
pElement = new CQueryElement;
pElement->SetDesc(BDString(IDS_DATE));
pElement->SetDataType(BDDATE);
pElement->SetAttrId(BDDATE);
pElement->SetFTypeId(lFType);
pPrevElement->SetNextQuery(pElement);
pPrevElement = pElement;
bInitDates = TRUE;
};
// Add all of the attributes
for (int i = 0; i < aAttr.GetSize(); i++)
{
// Allocate memory
CAttribute* pAttr = aAttr.GetAt(i);
switch (pAttr->GetDataType())
{
case BDFTYPE :
pElement = new CQuery;
break;
case BDLINK :
pElement = new CQueryLink(pAttr->GetFTypeLink());
break;
case BDNUMBER :
pElement = new CQueryNumber;
break;
case BDBOOLEAN :
pElement = new CQueryBoolean;
break;
case BDTEXT: case BDCOORD : case BDMAPLINES : case BDHOTLINK : case BDIMAGE :
case BDLONGTEXT : case BDFILE :
pElement = new CQueryElement;
break;
default :
ASSERT(FALSE);
}
// Initialise
CString sDesc = pAttr->GetDesc();
if (pAttr->GetDataType() == BDMAPLINES) sDesc += " [" + BDString(IDS_POLYLINESTYPE)+"]";
if (pAttr->GetDataType() == BDCOORD) sDesc += " [" + BDString(IDS_COORDTYPE) + "]";
pElement->SetDesc(sDesc);
pElement->SetColName(pAttr->m_sColName);
pElement->SetDataType(pAttr->GetDataType());
pElement->SetAttrId(pAttr->GetAttrId());
pElement->SetFTypeId(lFType);
// Add the list
pPrevElement->SetNextQuery(pElement);
pPrevElement = pElement;
};
};
BDEnd(BDHandle());
// Initialise the parent type
if (ftype.m_lParentFType != 0)
{
CQuery* pQuery = new CQuery;
pQuery->Initialise(ftype.m_lParentFType, bInitFeatures, bInitDates);
pPrevElement->SetNextQuery(pQuery);
}
}
///////////////////////////////////////////////////////////////////////////////
void CQuery::Write(FILE* pFile)
{
fprintf(pFile,"FType=%li\n",m_lFType);
fprintf(pFile,"DateCond=%i\n",m_nDateCond);
if (m_nDateCond == FirstDateRange || m_nDateCond == LastDateRange ||
m_nDateCond == AllDatesRange)
{
fprintf(pFile,"DateStart=%li\n",m_dtStart.GetDateLong());
fprintf(pFile,"DateEnd=%li\n",m_dtEnd.GetDateLong());
};
fprintf(pFile,"ShowAllFeatures=%i\n",m_bShowAllFeatures);
CQueryElement::Write(pFile);
fprintf(pFile,"end\n");
}
///////////////////////////////////////////////////////////////////////////////
BOOL CQuery::Read(FILE* pFile)
{
BOOL bOK = TRUE;
CString s = BDNextItem(pFile);
if (s != "FType") bOK = FALSE;
if (bOK)
{
long lFType = BDNextInt(pFile, FALSE);
if (m_lFType == 0)
{
m_lFType = lFType;
Initialise(m_lFType);
};
m_nDateCond = BDNextInt(pFile);
if (m_nDateCond == FirstDateRange || m_nDateCond == LastDateRange ||
m_nDateCond == AllDatesRange)
{
m_dtStart = CDateTime(BDNextInt(pFile), 0);
m_dtEnd = CDateTime(BDNextInt(pFile), 0);
};
m_bShowAllFeatures = BDNextInt(pFile);
bOK = CQueryElement::Read(pFile);
};
// Add new attribute to the end
while ((s = BDNextItem(pFile)) == "Statistic" && bOK)
{
CQueryStats* pStats = new CQueryStats;
CQueryElement* pElement = this;
pStats->Read(pFile);
while (pElement->GetNextQuery() != NULL && bOK)
{
pElement = pElement->GetNextQuery();
}
pElement->SetNextQuery(pStats);
}
if (s != "end")
{
ASSERT(FALSE);
bOK = FALSE;
}
return bOK;
}
///////////////////////////////////////////////////////////////////////////////
//
// Removes square brackets and their contents from a string
//
CString CQuery::StripBrackets(CString s)
{
CString sName;
BOOL bBracket = FALSE;
for (int i = 0; i < s.GetLength(); i++)
{
if (s[i] == '[') bBracket = TRUE;
else if (s[i] == ']') bBracket = FALSE;
else if (!bBracket) sName += s[i];
}
sName.TrimRight();
return sName;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CQueryElement::Read(FILE* pFile)
{
BOOL bOK = TRUE;
m_nDataType = BDNextInt(pFile);
m_nAttrId = BDNextInt(pFile);
m_lFType = BDNextInt(pFile);
m_bSelected = BDNextInt(pFile);
m_nSortBy = BDNextInt(pFile);
m_nGroupBy = BDNextInt(pFile);
m_nStatGroup = BDNextInt(pFile);
m_nCond = BDNextInt(pFile, "Cond");
m_dCondValue = BDNextDouble(pFile, "CondValue", 0);
m_sCondValue = BDNextStr(pFile, "CondValueStr");
CQueryElement* pQueryElement = GetNextQuery();
if (pQueryElement != NULL)
{
bOK = pQueryElement->Read(pFile);
}
return bOK;
}
///////////////////////////////////////////////////////////////////////////////
void CQueryElement::Write(FILE* pFile)
{
fprintf(pFile,"DataType=%i\n",m_nDataType);
fprintf(pFile,"AttrId=%i\n",m_nAttrId);
fprintf(pFile,"FtypeId=%i\n",m_lFType);
fprintf(pFile,"Selected=%i\n",m_bSelected);
fprintf(pFile,"SortBy=%i\n", m_nSortBy);
fprintf(pFile,"GroupBy=%i\n", m_nGroupBy);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -