📄 makejianpinindexdlg.cpp
字号:
// MakeJianPinIndexDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MakeJianPinIndex.h"
#include "MakeJianPinIndexDlg.h"
#include "chinese/cnpy.h"
#include "dyz.h"
#include <io.h>
#include "zlib.h"
#include "zconf.h"
#include <stdio.h>
#include <string.h>
#include <afxtempl.h>
#include <vector>
#include <algorithm>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static char g_szCharMappingNumber[10] = {'l', 'y', 'e', 's', 's', 'w', 'l', 'q', 'b', 'j'};
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMakeJianPinIndexDlg dialog
CMakeJianPinIndexDlg::CMakeJianPinIndexDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMakeJianPinIndexDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMakeJianPinIndexDlg)
m_strJianPinFile = _T("");
m_strJPName = _T("");
m_strCityAll = _T("");
m_strTxtDir = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMakeJianPinIndexDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMakeJianPinIndexDlg)
DDX_Text(pDX, IDC_EDIT_JIANPIN_FILE, m_strJianPinFile);
DDV_MaxChars(pDX, m_strJianPinFile, 256);
DDX_Text(pDX, IDC_EDIT_JPNAME, m_strJPName);
DDV_MaxChars(pDX, m_strJPName, 10);
DDX_Text(pDX, IDC_EDIT_CityAll, m_strCityAll);
DDX_Text(pDX, IDC_EDIT_TXT_DIR, m_strTxtDir);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMakeJianPinIndexDlg, CDialog)
//{{AFX_MSG_MAP(CMakeJianPinIndexDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnBrowseNidFile)
ON_BN_CLICKED(IDC_BUTTON2, OnBrowseJianPinFile)
ON_BN_CLICKED(IDC_BTN_CHECK_JP, OnBtnCheckJp)
ON_BN_CLICKED(IDC_BUTTON_CityAll, OnBUTTONCityAll)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CMakeJianPinIndexDlg message handlers
BOOL CMakeJianPinIndexDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
char pszDir[MAX_PATH] = "\0";
CString str;
GetModuleFileName(NULL, pszDir, MAX_PATH);
str.Format("%s", pszDir);
str = str.Left(str.ReverseFind('\\'));
m_strTxtDir = "D:\\TestMakeJP\\TXT";
m_strCityAll = "D:\\TestMakeJP\\CityAll.txt";
m_strJianPinFile = "D:\\TestMakeJP\\ruitu.ijp";
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CMakeJianPinIndexDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMakeJianPinIndexDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMakeJianPinIndexDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMakeJianPinIndexDlg::OnBrowseNidFile()
{
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = this->GetSafeHwnd();
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
TCHAR szTargetPath[MAX_PATH] = {0};
SHGetPathFromIDList(pidl, szTargetPath);
m_strTxtDir = szTargetPath;
UpdateData(FALSE);
}
void CMakeJianPinIndexDlg::OnBrowseJianPinFile()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
TCHAR szFilter[] = _T("JianPin file(*.ijp)|*.ijp|All Files(*.*)|*.*|");
CFileDialog dlgFile(FALSE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, NULL);
if (dlgFile.DoModal() == IDOK)
{
m_strJianPinFile = dlgFile.GetPathName();
m_strJianPinFile.MakeLower();
if (strcmp(m_strJianPinFile.Right(4), ".ijp"))
{
m_strJianPinFile += ".ijp";
}
UpdateData(FALSE);
}
}
//int YourAllocHook( int allocType, void *userData, size_t size, int blockType,
// long requestNumber, const unsigned char *filename, int lineNumber)
//{
// if(size == 19)
// size = size;
// return size;
//}
bool lessID( const ST_CityAll &m1, const ST_CityAll &m2 )
{
return ( m1.iCityID < m2.iCityID );
}
int fast_trim(char* buffer, char trim_ch, LPSTR *res, int _max_no)
{
int nn = 0;
char* s = buffer;
_max_no --;
res[nn] = s;
while(*s)
{
if (*s == trim_ch)
{
*s = 0;
nn++;
s ++;
res[nn] = s;
if (nn >= _max_no) return nn+1;
}
else
if (*s == '\r')
{
*s = 0;
break;
}
else
if (*s == '\n')
{
*s = 0;
break;
}
else
{
s++;
}
}
return nn+1;
}
void MatchCityName(vector<ST_CityAll> &vCityAll, int iCityID, CString &strName)
{
int iFirst = 0;
int iLast = vCityAll.size() - 1;
int iMid;
bool bFlag = false;
while(iFirst <= iLast)
{
iMid = (iFirst + iLast) / 2;
ST_CityAll st_CityAll = vCityAll[iMid];
if(st_CityAll.iCityID < iCityID)
iFirst = iMid + 1;
else if(st_CityAll.iCityID > iCityID)
iLast = iMid - 1;
else
{
strName.Format("%s", st_CityAll.szName);
bFlag = true;
break;
}
}
if(!bFlag)
{
TRACE1("CityID not found : %d\n", iCityID);
strName.Format("\0");
}
}
int YourAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine )
{
if (nSize == 4)
{
int test = 0;
}
return 1;
}
const int con_iCity = 31;
void CMakeJianPinIndexDlg::OnOK()
{
UpdateData(TRUE);
// for test
// _CrtSetAllocHook(YourAllocHook);
// parse ID and name of city
ParseCityIDName();
// push cityID into vector
ReadTxt();
// create tree
ParseCity();
// stat cnt of province 、city and subcity
StatCity();
CFile fileJP(m_strJianPinFile, CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone);
// 临时文件
CFile fileData(m_strJianPinFile + "_Data", CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone);
int iProvIdxPos = CJPIndexStruct::FileHeaderFlagLen + sizeof(int);
int iCityIdxPos = iProvIdxPos + m_iProvCnt * sizeof(ST_ProvIndex);
int iSubCityIdxPos = iCityIdxPos + m_iCityCnt * sizeof(ST_CityIndex);
int iCharIdxPos = iSubCityIdxPos + m_iSubCityCnt * sizeof(ST_SubCityIndex);
int iPackIdxPos = iCharIdxPos + m_iSubCityCnt * CHARACTER_NEWINDEX_COUNT * sizeof(ST_CharIndex);
int iPackDataPos = 0;
int iTotalPackNum = 0; // 分包数目
int iTotalPOICnt = 0;
int iTotalRdCnt = 0;
// province cnt
fileJP.Seek(CJPIndexStruct::FileHeaderFlagLen, CFile::begin);
fileJP.Write(&m_iProvCnt, sizeof(m_iProvCnt));
ST_ProvIndex st_ProvIndex;
ST_CityIndex st_CityIndex;
ST_SubCityIndex st_SubCityIndex;
memset(&st_ProvIndex, 0x0, sizeof(st_ProvIndex));
memset(&st_CityIndex, 0x0, sizeof(st_CityIndex));
memset(&st_SubCityIndex, 0x0, sizeof(st_SubCityIndex));
CString strFilePath;
// read tree
ST_ProvList* pProvList = NULL;
ST_CityList* pCityList = NULL;
POSITION pos_prov = m_ProvList.GetHeadPosition();
while(pos_prov)
{
pProvList = m_ProvList.GetNext(pos_prov);
// province info
memset(&st_ProvIndex, 0x0, sizeof(st_ProvIndex));
st_ProvIndex.iProvID = pProvList->iProvID;
st_ProvIndex.iOffset = iCityIdxPos;
st_ProvIndex.usCityNum = pProvList->CityList.GetCount();
CString strProvName;
MatchCityName(m_vSTCityAll, st_ProvIndex.iProvID, strProvName);
strcpy(st_ProvIndex.szName, strProvName);
// write prov info
fileJP.Seek(iProvIdxPos, CFile::begin);
fileJP.Write(&st_ProvIndex, sizeof(ST_ProvIndex));
iProvIdxPos += sizeof(ST_ProvIndex);
POSITION pos_city = pProvList->CityList.GetHeadPosition();
while(pos_city)
{
pCityList = pProvList->CityList.GetNext(pos_city);
// city info
memset(&st_CityIndex, 0x0, sizeof(st_CityIndex));
st_CityIndex.iCityID = pCityList->iCityID;
st_CityIndex.iOffset = iSubCityIdxPos;
st_CityIndex.usSubCityNum = pCityList->vSubCityList.size();
CString strCityName;
MatchCityName(m_vSTCityAll, st_CityIndex.iCityID, strCityName);
strcpy(st_CityIndex.szName, strCityName);
// write city info
fileJP.Seek(iCityIdxPos, CFile::begin);
fileJP.Write(&st_CityIndex, sizeof(ST_CityIndex));
iCityIdxPos += sizeof(ST_CityIndex);
for(int i = 0; i < st_CityIndex.usSubCityNum; i++)
{
// subcity info
memset(&st_SubCityIndex, 0x0, sizeof(st_SubCityIndex));
st_SubCityIndex.iCityID = pCityList->vSubCityList[i];
st_SubCityIndex.iOffset = iCharIdxPos;
CString strSubCityName;
MatchCityName(m_vSTCityAll, st_SubCityIndex.iCityID, strSubCityName);
strcpy(st_SubCityIndex.szName, strSubCityName);
// write subcity info
fileJP.Seek(iSubCityIdxPos, CFile::begin);
fileJP.Write(&st_SubCityIndex, sizeof(ST_SubCityIndex));
iSubCityIdxPos += sizeof(ST_SubCityIndex);
CCity *pCity = new CCity;
ASSERT(pCity != NULL);
pCity->SetID(pCityList->vSubCityList[i]);
// parse name
pCity->ParseTxt(m_strTxtDir);
iTotalPOICnt += pCity->GetPOICnt();
iTotalRdCnt += pCity->GetRdCnt();
iTotalPackNum += pCity->Write(fileJP, fileData, iCharIdxPos, iPackIdxPos, iPackDataPos);
delete pCity;
pCity = NULL;
}
}
}
ASSERT(iPackIdxPos == fileJP.GetLength());
int k = 0;
TRACE1("OrgTotalPOICnt: %d\n", iTotalPOICnt);
TRACE1("OrgTotalRdCnt: %d\n", iTotalRdCnt);
// 更新PackDataOffset
iPackDataPos = iPackIdxPos;
iPackIdxPos -= iTotalPackNum * sizeof(ST_PackIndex);
ST_PackIndex* pst_PackIndex = new ST_PackIndex[iTotalPackNum];
fileJP.Seek(iPackIdxPos, CFile::begin);
fileJP.Read(pst_PackIndex, iTotalPackNum * sizeof(ST_PackIndex));
for(k = 0; k < iTotalPackNum; k++)
pst_PackIndex[k].iOffset += iPackDataPos;
fileJP.Seek(iPackIdxPos, CFile::begin);
fileJP.Write(pst_PackIndex, iTotalPackNum * sizeof(ST_PackIndex));
delete[] pst_PackIndex;
pst_PackIndex = NULL;
// 合并文件
BYTE pBuffer[BLOCK_SIZE];
UINT unReadContent = 0;
fileData.SeekToBegin();
while (unReadContent = fileData.Read(pBuffer, BLOCK_SIZE))
{
fileJP.Write(pBuffer, unReadContent);
if (unReadContent < BLOCK_SIZE)
break;
}
fileJP.Close();
fileData.Close();
DeleteFile(m_strJianPinFile + "_Data");
// 释放资源
pos_prov = m_ProvList.GetHeadPosition();
while(pos_prov)
{
pProvList = m_ProvList.GetNext(pos_prov);
POSITION pos_city = pProvList->CityList.GetHeadPosition();
while(pos_city)
{
pCityList = pProvList->CityList.GetNext(pos_city);
if(pCityList != NULL)
{
if(!pCityList->vSubCityList.empty())
pCityList->vSubCityList.clear();
delete pCityList;
}
}
if(pProvList != NULL)
delete pProvList;
}
m_ProvList.RemoveAll();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -