西安80平面坐标转WGS84球面坐标

第一版本:https://my.oschina.net/u/2930533/blog/1486756

第二版本:首先打开一个dwg图纸,然后在dwg上拾取一段有标注的多段线,把该多段线上的点的xy坐标转化成平面坐标,导出到kml文件里面,该kml文件可以导入到谷歌地图等里面成图.

acrxEntryPoint.cpp

virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
	AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
		
	// 自动加载dwg
	CDwgDataToXml::OnLoadDWG();
	return (retCode) ;
}

static void HHCDwgPt2XmlApp(void)
{
	CCoordManageDlg pDlg;
	pDlg.DoModal();
}

static void HHOpenDwg(void)
{
	CDwgDataToXml::OnLoadDWG();
}

IMPLEMENT_ARX_ENTRYPOINT(CDwgPt2KmlApp)
//注册命令
ACED_ARXCOMMAND_ENTRY_AUTO(CDwgPt2KmlApp,HH, OpenDwg,		HHOPENDWG,	ACRX_CMD_TRANSPARENT, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CDwgPt2KmlApp,HH, CDwgPt2XmlApp, HHDCKML,	ACRX_CMD_TRANSPARENT, NULL)//坐标转换

具体实现:

坐标转换界面:

CoordManageDlg.h

#pragma once
#include "Resource.h"
#include "DHCT.h"
#include <vector>

class CKmlXmlns;
class CCoordTransArr;
struct CPoleData;

struct CSevenParam
{
	CString m_strCur;
	CString m_strTar;
	double m_dDX;
	double m_dDY;
	double m_dDZ;
	double m_dRX;
	double m_dRY;
	double m_dRZ;
	double m_dK;
};

// CCoordManageDlg		坐标转换	对话框			2017.1.18		
class CCoordManageDlg : public CDialog
{
	DECLARE_DYNAMIC(CCoordManageDlg)
public:
	CCoordManageDlg(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CCoordManageDlg();

// 对话框数据
	enum { IDD = IDD_DLG_COORD_MG };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	DECLARE_MESSAGE_MAP()
	virtual BOOL OnInitDialog();
	afx_msg void OnBnClickedBtnGetline();//拾取线路
	afx_msg void OnBnClickedBtnSet();//设置
	afx_msg void OnCbnSelchangeCmbTarcoordsystem();//目标坐标系改变
	afx_msg void OnCbnSelchangeCmbDecimalsnum();//小数点
	afx_msg void OnLvnEndlabeleditListCoord(NMHDR *pNMHDR, LRESULT *pResult);//edit编辑结束
	afx_msg void OnBnClickedBtnCoordtrans();//坐标转换
	afx_msg void OnBnClickedOk();//导出klm
	afx_msg void OnBnClickedBtnCoord();//导出东北坐标
	afx_msg void OnNMRClickListCoord(NMHDR *pNMHDR, LRESULT *pResult);//右键菜单
	afx_msg void OnMenuClickedAdd();//添加
	afx_msg void OnMenuClickedModify();//修改
	afx_msg void OnMenuClickDelete();//删除
private:
	//初始化下拉框
	void InitCombox();
	//初始化参数转换
	void InitSevenParam();
	//初始化表头
	void InitListHead();
	//初始化xy坐标
	void InitListYX(bool bIsUpData = false);
	//初始化经纬度坐标
	void InitListBL();

	//加载配置文件,得到转换参数
	void LoadCoordParameter();
	//保存7参数
	void SaveSevenParam();

	//写入xml文件
	bool WriteXml(CKmlXmlns& arrPointData);
	//获取用户选择的路径
	bool GetUserSelectDir(CString & strPath);
private:
	CComboBox m_cmbCurCoordSystem;//当前坐标系
	CComboBox m_cmbCoordType;	  //坐标类型
	CComboBox m_cmbDecimalsNum;	  //保留小数位数
	CComboBox m_cmbCoordStyle;	  //坐标风格
	CEdit m_editLongitude;		  //中央经线
	CStatic m_staticLongitude;	  //中央经线
	CStatic m_staticZoning;		  //投影分带
	CComboBox m_cmbZoning;		  //投影分带
	
	CComboBox m_cmbTarCoordSystem;//目标坐标系
	CComboBox m_cmbTarCoordType;  //坐标类型
	CComboBox m_cmbCoordParameter;//转换参数

	CEdit m_editLineName;//线路名称
	CListCtrl m_listCoord;
	std::vector<CPoleData> m_vecPoleData;//点位信息
	std::map<CString,CSevenParam> m_mapSevenParam;//七参数
};

CoordManageDlg.cpp

// CoordManageDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "CoordManageDlg.h"
#include "afxdialogex.h"
#include "PrjStruct.h"
#include "DwgDataToXml.h"
#include "CoordEditDlg.h"
#include "ParameterManageDlg.h"
#include "rxmfcapi.h"
#include "Fun.h"
#include "ExcelReaderLibXl.h"

// CCoordManageDlg 对话框
IMPLEMENT_DYNAMIC(CCoordManageDlg, CDialog)
CCoordManageDlg::CCoordManageDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCoordManageDlg::IDD, pParent)
{

}

CCoordManageDlg::~CCoordManageDlg()
{
}

void CCoordManageDlg::DoDataExchange(CDataExchange* pDX)
{
	__super::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CMB_CURCOORDSYSTEM, m_cmbTarCoordSystem );
	DDX_Control(pDX, IDC_CMB_TARCOORDSYSTEM, m_cmbCurCoordSystem);
	DDX_Control(pDX, IDC_CMB_COORDTYPE, m_cmbCoordType);
	DDX_Control(pDX, IDC_CMB_DECIMALSNUM, m_cmbDecimalsNum);
	DDX_Control(pDX, IDC_CMB_COORDSTYLE, m_cmbCoordStyle);
	DDX_Control(pDX, IDC_STATIC_LONGITUDE, m_staticLongitude);
	DDX_Control(pDX, IDC_EDIT_LONGITUDE, m_editLongitude);
	DDX_Control(pDX, IDC_STATIC_ZONING, m_staticZoning);
	DDX_Control(pDX, IDC_CMB_ZONING, m_cmbZoning);
	DDX_Control(pDX, IDC_LIST_COORD, m_listCoord);
	DDX_Control(pDX, IDC_CMB_TARCOORDTYPE, m_cmbTarCoordType);
	DDX_Control(pDX, IDC_CMB_COORDPARAMETER, m_cmbCoordParameter);
	DDX_Control(pDX, IDC_EDIT_NAME, m_editLineName);
}

BEGIN_MESSAGE_MAP(CCoordManageDlg, CDialog)
	ON_BN_CLICKED(IDOK, &CCoordManageDlg::OnBnClickedOk)
	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST_COORD, &CCoordManageDlg::OnLvnEndlabeleditListCoord)
	ON_CBN_SELCHANGE(IDC_CMB_TARCOORDSYSTEM, &CCoordManageDlg::OnCbnSelchangeCmbTarcoordsystem)
	ON_BN_CLICKED(IDC_BTN_GETLINE, &CCoordManageDlg::OnBnClickedBtnGetline)
	ON_BN_CLICKED(IDC_BTN_COORDTRANS, &CCoordManageDlg::OnBnClickedBtnCoordtrans)
	ON_BN_CLICKED(IDC_BTN_SET, &CCoordManageDlg::OnBnClickedBtnSet)
	ON_NOTIFY(NM_RCLICK, IDC_LIST_COORD, &CCoordManageDlg::OnNMRClickListCoord)
	ON_COMMAND(ID_Add, &CCoordManageDlg::OnMenuClickedAdd)
	ON_COMMAND(ID_MODIFY, &CCoordManageDlg::OnMenuClickedModify)
	ON_COMMAND(ID_DELETE, &CCoordManageDlg::OnMenuClickDelete)
	ON_BN_CLICKED(IDC_BTN_COORD, &CCoordManageDlg::OnBnClickedBtnCoord)
	ON_CBN_SELCHANGE(IDC_CMB_DECIMALSNUM, &CCoordManageDlg::OnCbnSelchangeCmbDecimalsnum)
END_MESSAGE_MAP()

// CCoordManageDlg 消息处理程序
BOOL CCoordManageDlg::OnInitDialog()
{
	__super::OnInitDialog();

	//加载配置文件,得到转换参数
	LoadCoordParameter();
	//初始化下拉框
	InitCombox();
	//初始化表头
	InitListHead();
	
	return TRUE;  
}

void CCoordManageDlg::OnBnClickedOk()
{
	UpdateData(FALSE);

	CString strLineName;
	m_editLineName.GetWindowText(strLineName);
	if (strLineName.IsEmpty())
	{
		MessageBox(_T("请填写当前线路的名称!"), _T("提示框"), MB_OK | MB_ICONHAND ); 
		return;
	}

	CString strName;
	CString strCoord;
	CString strTempName;
	CString strTempX;
	CString strTempY;
	CString strtempCoord;
	for (int nRow = 0; nRow < m_listCoord.GetItemCount(); ++nRow)
	{
		strTempName = m_listCoord.GetItemText(nRow,0);
		strTempX = m_listCoord.GetItemText(nRow,3);
		strTempY = m_listCoord.GetItemText(nRow,4);
		if (strTempX.IsEmpty() || strTempY.IsEmpty())
		{
			AfxMessageBox(_T("还未进行坐标转换!"));
			return;
		}
		strtempCoord.Format(_T("%s,%s,0"),strTempX,strTempY);

		if (!strName.IsEmpty())
			strName += _T(";");
		strName += strTempName;

		if (!strCoord.IsEmpty())
			strCoord += _T(" ");
		strCoord += strtempCoord;
	}

	CKmlXmlns arrPointData;
	arrPointData.m_Document.m_Placemark.m_strName = strLineName;
	arrPointData.m_Document.m_Placemark.m_Point.m_strName = strName;
	arrPointData.m_Document.m_Placemark.m_Point.m_strCoord = strCoord;

	//写入kml文件
	WriteXml(arrPointData);

	__super::OnOK();
}

bool CCoordManageDlg::GetUserSelectDir( CString & strPath )
{
	strPath ='\0';
	TCHAR szPath[MAX_PATH];
	BROWSEINFO br;
	ITEMIDLIST * pItem; 
	br.hwndOwner = GetSafeHwnd();
	br.iImage = 0;
	br.pszDisplayName = 0;
	br.lParam = 0 ;
	br.lpfn = 0 ;
	br.lpszTitle = _T("请选择存放kml路径");
	br.pidlRoot = 0 ;
	br.ulFlags = BIF_RETURNONLYFSDIRS|BIF_USENEWUI;
	pItem = SHBrowseForFolder(&br);
	if (SHGetPathFromIDList(pItem,szPath) != TRUE)
	{
		return false;
	}

	strPath = szPath;
	return true;
}

bool CCoordManageDlg::WriteXml(CKmlXmlns& arrPointData)
{
	CString strPath;
	if (!GetUserSelectDir(strPath))
		return true;
	
	CTime timeCurr = CTime::GetCurrentTime();
	CString strXmlName;
	strXmlName.Format(_T("\\桩位点数据%d%d%d%d%d%d.kml"),timeCurr.GetYear(),timeCurr.GetMonth(),timeCurr.GetDay(),
		timeCurr.GetHour(),timeCurr.GetMinute(),timeCurr.GetSecond());
	strPath+=strXmlName;
	strPath.Replace(_T("\\\\"), _T("\\"));

	if(arrPointData.SaveXMLFile(strPath))
		AfxMessageBox(_T("导出成功!"));
	else 
		AfxMessageBox(_T("写kml失败!"));

	return true;
}

void CCoordManageDlg::InitCombox()
{
	//当前坐标系
	int nIndex = m_cmbCurCoordSystem.AddString(_T("1954北京坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,1);
	nIndex = m_cmbCurCoordSystem.AddString(_T("1980西安坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,2);
	nIndex = m_cmbCurCoordSystem.AddString(_T("WGS84坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,3);
	m_cmbCurCoordSystem.SetCurSel(1);

	//坐标风格
	nIndex = m_cmbCoordStyle.AddString(_T("米"));
	m_cmbCoordStyle.SetItemData(nIndex,1);
	m_cmbCoordStyle.SetCurSel(0);

	//中央经线
	m_editLongitude.SetWindowText(_T("111"));

	//坐标类型
	nIndex = m_cmbCoordType.AddString(_T("平面坐标"));
	m_cmbCoordType.SetItemData(nIndex,1);
	nIndex = m_cmbCoordType.AddString(_T("大地坐标"));
	m_cmbCoordType.SetItemData(nIndex,2);
	m_cmbCoordType.SetCurSel(0);

	//保留小数
	CString strNum;
	for (int nNum = 0; nNum < 7; ++nNum)
	{
		strNum.Format(_T("%d"), nNum);
		nIndex = m_cmbDecimalsNum.AddString(strNum);
		m_cmbDecimalsNum.SetItemData(nIndex,nNum);
	}
	m_cmbDecimalsNum.SetCurSel(4);

	//投影分带
	nIndex = m_cmbZoning.AddString(_T("3度分带"));
	m_cmbZoning.SetItemData(nIndex,1);
	nIndex = m_cmbZoning.AddString(_T("6度分带"));
	m_cmbZoning.SetItemData(nIndex,2);
	m_cmbZoning.SetCurSel(0);

	//目标坐标系
	nIndex = m_cmbTarCoordSystem.AddString(_T("WGS84坐标系"));
	m_cmbTarCoordSystem.SetItemData(nIndex,1);
	m_cmbTarCoordSystem.SetCurSel(0);

	//坐标类型
	nIndex = m_cmbTarCoordType.AddString(_T("大地坐标"));
	m_cmbTarCoordType.SetItemData(nIndex,1);
	m_cmbTarCoordType.SetCurSel(0);

	//转换参数
	InitSevenParam();
}

void CCoordManageDlg::InitListHead()
{
	CRect rect; 
 	m_listCoord.GetClientRect(&rect);
	m_listCoord.SetExtendedStyle(m_listCoord.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	m_listCoord.InsertColumn(0, _T("桩/塔名"), LVCFMT_CENTER, rect.Width()/5, 0);
	m_listCoord.InsertColumn(1, _T("东坐标" ), LVCFMT_CENTER, rect.Width()/5, 1);   
	m_listCoord.InsertColumn(2, _T("北坐标"	), LVCFMT_CENTER, rect.Width()/5, 2);
	m_listCoord.InsertColumn(3, _T("经度"   ), LVCFMT_CENTER, rect.Width()/5, 3);   
	m_listCoord.InsertColumn(4, _T("纬度"	), LVCFMT_CENTER, rect.Width()/5, 4); 
}

void CCoordManageDlg::OnCbnSelchangeCmbTarcoordsystem()
{
	
}

void CCoordManageDlg::OnBnClickedBtnGetline()
{
	// 隐藏对话框
	acedGetAcadFrame()->EnableWindow(TRUE);
	ShowWindow(SW_HIDE);

	m_vecPoleData.clear();
	CDwgDataToXml::Inlet(m_vecPoleData);
	// 显示对话框
	acedGetAcadFrame()->EnableWindow(FALSE);
	ShowWindow(SW_SHOW);	
	EnableWindow(TRUE);
	if (m_vecPoleData.size() > 0)
		InitListYX();
}

void CCoordManageDlg::InitListYX( bool bIsUpData)
{
	//小数点位数
	CString strNum;
	m_cmbDecimalsNum.GetWindowText(strNum);
	int nNum = _ttoi(strNum);
	CString strRow;
	CString strPoint;
	for (int nRow = 0; nRow < m_vecPoleData.size();++nRow)
	{
		CPoleData poleData = m_vecPoleData[nRow];
		if (!bIsUpData)
		{
			strRow.Format(_T("%d"),nRow);
			m_listCoord.InsertItem(nRow, strRow); 
		}
		m_listCoord.SetItemText(nRow, 0, poleData.strName); 
		strPoint.Format(_T("%.*f"),nNum,poleData.ptPolePoint.x);
		m_listCoord.SetItemText(nRow, 1, strPoint); 
		strPoint.Format(_T("%.*f"),nNum,poleData.ptPolePoint.y);
		m_listCoord.SetItemText(nRow, 2, strPoint); 
	} 
}

void CCoordManageDlg::InitListBL()
{
	DHCOORDTRANSFORMPARAM mParam;
	CString strTemp;
	m_cmbCurCoordSystem.GetWindowText(strTemp);
	if (_T("1954北京坐标系") == strTemp)
		mParam.nCoordMode = DHE3_COORMODE_BJ54;
	else if (_T("WGS84坐标系") == strTemp)
		mParam.nCoordMode = DHE3_COORMODE_WGS84UTM;
	else 
		mParam.nCoordMode = DHE3_COORMODE_XA80;

	m_cmbCoordParameter.GetWindowText(strTemp);
	CSevenParam SevenParam = m_mapSevenParam[strTemp];

	mParam.nLongLatFormat = DHE3_LONGLAT_FORMAT_DU;
	m_editLongitude.GetWindowText(strTemp);
	mParam.dCenterLong = _ttol(strTemp);
	mParam.spSevenParam.dPitch = SevenParam.m_dRX;
	mParam.spSevenParam.dRoll = SevenParam.m_dRZ;
	mParam.spSevenParam.dScale = SevenParam.m_dK;
	mParam.spSevenParam.dXOffset = SevenParam.m_dDX;
	mParam.spSevenParam.dYaw = SevenParam.m_dRY;
	mParam.spSevenParam.dYOffset = SevenParam.m_dDY;
	mParam.spSevenParam.dZOffset = SevenParam.m_dDZ;
	double dLong(0.0l), dLat(0.0l), dH(0.0l);

	//小数点位数
	CString strNum;
	m_cmbDecimalsNum.GetWindowText(strNum);
	int nNum = _ttoi(strNum);

	CString strRow;
	CString strPoint;
	for (int nRow = 0; nRow < m_vecPoleData.size();++nRow)
	{
		OnTransformToBLH(mParam.nCoordMode,true,mParam.dCenterLong,&mParam.spSevenParam,m_vecPoleData[nRow].ptPolePoint.x,m_vecPoleData[nRow].ptPolePoint.y, 0, dLong, dLat, dH);

		strRow.Format(_T("%d"),nRow);
		strPoint.Format(_T("%.*f"),nNum,dLong);
		m_listCoord.SetItemText(nRow, 3, strPoint); 
		strPoint.Format(_T("%.*f"),nNum,dLat);
		m_listCoord.SetItemText(nRow, 4, strPoint);
	} 
}

void CCoordManageDlg::OnLvnEndlabeleditListCoord( NMHDR *pNMHDR, LRESULT *pResult )
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	*pResult = 0;

	CString strName = pDispInfo->item.pszText;
	int nSel = pDispInfo->item.iItem;
	m_listCoord.SetFocus();

	if( ( ! strName.IsEmpty() ) && nSel >= 0 )
		m_listCoord.SetItemText( nSel, 0, strName);
}


void CCoordManageDlg::OnBnClickedBtnCoordtrans()
{
	if (m_vecPoleData.size() < 1)
	{
		AfxMessageBox(_T("没有桩塔坐标可以转换,请先拾取线路!"));
		return;
	}

	CString strTemp;
	m_cmbCoordParameter.GetWindowText(strTemp);
	if (strTemp.IsEmpty())
	{
		AfxMessageBox(_T("转换参数为空,请先设置可用的七参数!"));
		return;
	}
	InitListBL();
}

void CCoordManageDlg::OnBnClickedBtnSet()
{
	CParameterManageDlg dlg(m_mapSevenParam,this);
	if (IDOK == dlg.DoModal())
	{
		if (m_mapSevenParam.size() < 1)
			return;

		// 参数转换
		InitSevenParam();
		//保存七参数
		SaveSevenParam();
	}
}

void CCoordManageDlg::LoadCoordParameter()
{
	std::wstring strPath;
	bool bRet = CDwgDataToXml::GetUserConfigFilePath(_T("CoordTransPara.xml"), strPath);
	if (!bRet)
		return;

	//解析配置文件
	CCoordTransArr CoordTransArr;
	CoordTransArr.LoadXMLFile(strPath.c_str());
	for (int nIndex = 0; nIndex < CoordTransArr.size(); ++nIndex)
	{
		CSevenParam SevenParam;
		SevenParam.m_strCur = CoordTransArr[nIndex].m_strCur;
		SevenParam.m_strTar = CoordTransArr[nIndex].m_strTar;
		SevenParam.m_dDX = CoordTransArr[nIndex].m_dDX;
		SevenParam.m_dDY = CoordTransArr[nIndex].m_dDY;
		SevenParam.m_dDZ = CoordTransArr[nIndex].m_dDZ;
		SevenParam.m_dRX = CoordTransArr[nIndex].m_dRX;
		SevenParam.m_dRY = CoordTransArr[nIndex].m_dRY;
		SevenParam.m_dRZ = CoordTransArr[nIndex].m_dRZ;
		SevenParam.m_dK = CoordTransArr[nIndex].m_dK;

		m_mapSevenParam[CoordTransArr[nIndex].m_strName] = SevenParam;
	}
}

void CCoordManageDlg::InitSevenParam()
{
	m_cmbCoordParameter.ResetContent();
	int nIndex = 0;
	std::map<CString,CSevenParam>::iterator it = m_mapSevenParam.begin();
	for(;it != m_mapSevenParam.end(); ++it)
	{
		nIndex = m_cmbCoordParameter.AddString(it->first);
		m_cmbCoordParameter.SetItemData(nIndex,1);
		m_cmbCoordParameter.SetCurSel(0);
	}
}

void CCoordManageDlg::SaveSevenParam()
{
	CCoordTransArr CoordTransArr;
	std::map<CString,CSevenParam>::iterator it = m_mapSevenParam.begin();
	for (; it != m_mapSevenParam.end(); ++it)
	{
		CCoordTrans CoordTrans;
		CoordTrans.m_strName = it->first;
		CoordTrans.m_strCur = it->second.m_strCur;
		CoordTrans.m_strTar = it->second.m_strTar;
		CoordTrans.m_dDX = it->second.m_dDX;
		CoordTrans.m_dDY = it->second.m_dDY;
		CoordTrans.m_dDZ = it->second.m_dDZ;
		CoordTrans.m_dRX = it->second.m_dRX;
		CoordTrans.m_dRY = it->second.m_dRY;
		CoordTrans.m_dRZ = it->second.m_dRZ;
		CoordTrans.m_dK = it->second.m_dK;
		
		CoordTransArr.push_back(CoordTrans);
	}

	std::wstring strPath;
	CDwgDataToXml::GetUserConfigFilePath(_T("CoordTransPara.xml"),strPath);

	CoordTransArr.SaveXMLFile(strPath.c_str());
}


void CCoordManageDlg::OnNMRClickListCoord(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	POINT point;
	GetCursorPos(&point);
	ScreenToClient(&point);

	if (point.x == -1 && point.y == -1)           //判断是否在窗口外面
	{
		CRect rect;
		m_listCoord.GetClientRect(rect);  //得到窗口客户区的大小      
		m_listCoord.ClientToScreen(rect); //转化为屏幕坐标
		point = rect.TopLeft();//获取左上角坐标
		//point.Offset(5, 5);    //坐标偏移5,5
	}

	CMenu menu;//声明菜单对象
	menu.LoadMenu(IDR_MENU1);//从应用程序的可执行文件中加载菜单资源
	CMenu* pPopup  = NULL;
	pPopup= menu.GetSubMenu(0);  //获得第一个弹出菜单的指针,也就是菜单中的第一个弹出菜单
	if (NULL == pPopup)
		return;

	// 将坐标值由客户坐标转换为屏幕坐标   
	ClientToScreen(&point); 

	ASSERT(pPopup != NULL); //p断言不为空
	CWnd* pWndPopupOwner = this;//当前类的指针

	//下面就是弹出菜单
	pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner);
}


void CCoordManageDlg::OnMenuClickedAdd()
{
	// 增加
	int nSel=m_listCoord.GetSelectionMark();
	CString strName,strXCoord,strYCoord,strLong,strLat;
	CCoordEditDlg dlg(strName,strXCoord,strYCoord,strLong,strLat); 
	if (dlg.DoModal() != IDOK)         
		return;

	dlg.GetData(strName,strXCoord,strYCoord,strLong,strLat);
	CString strCurID;
	strCurID.Format (_T("%d"),nSel + 1);
	m_listCoord.InsertItem(nSel + 1, strCurID); 
	m_listCoord.SetItemText(nSel + 1, 0, strName); 
	m_listCoord.SetItemText(nSel + 1, 1, strXCoord);
	m_listCoord.SetItemText(nSel + 1, 2, strYCoord);
	m_listCoord.SetItemText(nSel + 1, 3, strLong);
	m_listCoord.SetItemText(nSel + 1, 4, strLat);
}


void CCoordManageDlg::OnMenuClickedModify()
{
	int nSel=m_listCoord.GetSelectionMark();
	CString strName = m_listCoord.GetItemText(nSel,0);
	CString strXCoord = m_listCoord.GetItemText(nSel,1);
	CString strYCoord = m_listCoord.GetItemText(nSel,2);
	CString strLong = m_listCoord.GetItemText(nSel,3);
	CString strLat = m_listCoord.GetItemText(nSel,4);
	CCoordEditDlg  dlg(strName,strXCoord,strYCoord,strLong,strLat); 
	if (dlg.DoModal() != IDOK)         
		return;

	dlg.GetData(strName,strXCoord,strYCoord,strLong,strLat);
	m_listCoord.SetItemText(nSel, 0, strName); 
	m_listCoord.SetItemText(nSel, 1, strXCoord);
	m_listCoord.SetItemText(nSel, 2, strYCoord);
	m_listCoord.SetItemText(nSel, 3, strLong);
	m_listCoord.SetItemText(nSel, 4, strLat);
}

void CCoordManageDlg::OnMenuClickDelete()
{
	int nSel=m_listCoord.GetSelectionMark();
	m_listCoord.DeleteItem(nSel); 
}


void CCoordManageDlg::OnBnClickedBtnCoord()
{
	//得到模板表格
	std::wstring strTempPath;
	if (!(CDwgDataToXml::GetUserConfigFilePath(_T("东北坐标导出模板.xls"), strTempPath)))
	{
		AfxMessageBox(_T("没有 东北坐标导出模板.xls 模板!"));
		return;
	}
	
	//用户选择路径
	CString strPath;
	if (!GetUserSelectDir(strPath))
		return;

	strPath += _T("\\桩位表.xls");
	BOOL bRet = CopyFile(strTempPath.c_str(),strPath,FALSE);

	CExcelReaderLibXl xlsReader;
	if ( !xlsReader.Open(strPath))
		return;

	//把坐标填充到表格
	CString strTempName;
	CString strTempX;
	CString strTempY;
	for (int nRow = 0; nRow < m_listCoord.GetItemCount(); ++nRow)
	{
		strTempName = m_listCoord.GetItemText(nRow,0);
		xlsReader.WirteCellText( 0 ,nRow + 1,0,strTempName);

		strTempX = m_listCoord.GetItemText(nRow,1);
		xlsReader.WirteCellText( 0 ,nRow + 1,1,strTempX);

		strTempY = m_listCoord.GetItemText(nRow,2);
		xlsReader.WirteCellText( 0 ,nRow + 1,2,strTempY);
	}

	xlsReader.Save();
	if (_taccess(strPath, 0) == -1)
		AfxMessageBox(_T("导出失败"));
	else
		AfxMessageBox(_T("导出成功!"));
}


void CCoordManageDlg::OnCbnSelchangeCmbDecimalsnum()
{
	InitListYX(true);
}

拾取线路:

DwgDataToXml.h

#pragma once
#include <vector>
#include "PrjStruct.h"

struct CPoleData
{
	AcGePoint3d ptPolePoint;//桩位点
	CString strName;//标注名称
};

//把dwg中的点位数据整理成kml文件	
class CDwgDataToXml
{
public:
	CDwgDataToXml(void);
	~CDwgDataToXml(void);

public:
	//外部入口
	static void Inlet(std::vector<CPoleData>& vecPoleData);
	//加载dwg图纸
	static void OnLoadDWG();
	//读取用户配置文件路径 
	static bool GetUserConfigFilePath(LPCTSTR lpFileName, std::wstring& strFilePath);

	//得到桩名对应位置
	std::vector<CPoleData> GetPoleData(AcGePoint3dArray vecXYPoint);
	//得到上一级目录
	void GetParentPath(CString & strPath);
	//设置图层名
	void SetLayerName(CString strLayerName);
private:
	// 由选择集得到实体ID
	BOOL GetIdArrayFromSS(ads_name selectSet,AcDbObjectIdArray &idArray);
	//通过实体id获得坐标点和图层
	bool GetPosAndLayerFromId(const AcDbObjectId &polyId,AcGePoint3dArray &vecPoint,CString &strLayer);
	//得到离点最近的标注
	CString GetNearestLable(const AcGePoint3d ptPoint);
	
	//通过标注id得到标注名称和位置
	bool GetLableDataFromId(AcDbObjectId &Id);
	//通过选择集得到标注信息
	bool GetLabelFromXZJ(CString& strLayer);
	//得到桩位XY坐标点和图层
	bool GetXYPoints(AcGePoint3dArray &vecPoint,CString& strLayer);

	//得到dwg图纸路径
	CString GetDwgPath();
	//打开dwg图纸
	BOOL OpenDwg(CString &strPath);
private:
	std::map<CString,AcGePoint3d> m_mapLable;//标注名称的位置
	CString m_strLayerName;//图层名称
	std::vector<CPoleData> m_vecPoleData;//桩位数据
};

DwgDataToXml.cpp

#include "StdAfx.h"
#import <MSXML.DLL> named_guids 
#include "DwgDataToXml.h"
#include <afxdlgs.h>
#include "CoordManageDlg.h"
#include <winuser.h>
#include <tchar.h>


CDwgDataToXml::CDwgDataToXml(void)
{
}


CDwgDataToXml::~CDwgDataToXml(void)
{
}

void CDwgDataToXml::Inlet(std::vector<CPoleData>& vecPoleData)
{
	//1.选择实体,得到多段线的点和图层
	CDwgDataToXml dwgDataToxml;
	AcGePoint3dArray vecXYPoint;//桩位XY坐标点
	CString strLayer;//图层名称
	dwgDataToxml.GetXYPoints(vecXYPoint,strLayer);
	if (vecXYPoint.length() <= 0)
	{
		AfxMessageBox(_T("选择实体不正确!,请选择多段线"));
		return;
	}
		
	//2.通过选择集得到标注位置和名称
	dwgDataToxml.GetLabelFromXZJ(strLayer);

	//3.得到杆的位置和坐标
	vecPoleData = dwgDataToxml.GetPoleData(vecXYPoint);
	if (vecPoleData.size() < 1)
		AfxMessageBox(_T("未提取到正确的线路,请重新提取!"));
}

BOOL CDwgDataToXml::GetIdArrayFromSS( ads_name selectSet,AcDbObjectIdArray &idArray )
{
	idArray.setLogicalLength(0);

	long len = 0;
	acedSSLength(selectSet,&len);

	if (acedSSLength(selectSet,&len) != RTNORM)		return FALSE;

	for(long i = 0; i < len; i++)
	{
		ads_name en_SS;
		if (acedSSName(selectSet,i,en_SS) != RTNORM)		return FALSE;

		AcDbObjectId enId_SS;
		if (acdbGetObjectId(enId_SS,en_SS) != Acad::eOk)		return FALSE;

		if (!enId_SS.isNull() && !idArray.contains(enId_SS))
		{
			idArray.append(enId_SS);
		}
	}

	return TRUE;
}

bool CDwgDataToXml::GetPosAndLayerFromId( const AcDbObjectId &polyId,AcGePoint3dArray &vecPoint,CString &strLayer)
{
	//得到实体
	AcDbEntity* pEnt = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pEnt,polyId,AcDb::kForRead);
	if (es != Acad::eOk)
		return false;

	//得到图层
	ACHAR* pTemp = pEnt->layer();
	if (NULL != pTemp)
		strLayer = pTemp;

	if (pEnt->isA() == AcDbPolyline::desc())//多段线
	{
		AcDbPolyline *pPolyline = AcDbPolyline::cast(pEnt);
		for (int i = 0; i < pPolyline->numVerts(); i++)
		{
			AcGePoint3d pt;
			pPolyline->getPointAt(i,pt);
			vecPoint.append(pt);
		}
		pPolyline = NULL;
	}

	return true;
}

void CDwgDataToXml::OnLoadDWG()
{
	//得到dwg图纸路径
	CDwgDataToXml dwgDataToxml;
	CString strPath = dwgDataToxml.GetDwgPath();

	//打开dwg图纸
	if(!dwgDataToxml.OpenDwg(strPath))
		acdbFail(_T("打开dwg图纸失败"));
}

void CDwgDataToXml::GetParentPath( CString & strPath )
{
	int nPos = strPath.ReverseFind(_T('\\'));
	strPath = strPath.Left(nPos);
	//strPath.TrimRight(_T("\\"));
}

CString CDwgDataToXml::GetDwgPath()
{
	TCHAR szFilePath[MAX_PATH+1];
	memset(szFilePath, 0, MAX_PATH+1);
	GetModuleFileName(_hdllInstance, szFilePath, MAX_PATH);

	CString strPath(szFilePath);
	GetParentPath(strPath);
	GetParentPath(strPath);
	GetParentPath(strPath);
	strPath = strPath + _T("\\Dwg\\CAD选线成果样例1.dwg");
	if (_taccess(strPath, 0) != -1)
	{
		//用户选择dwg
		CFileDialog dlg(TRUE, _T("*.dwg"), NULL, OFN_HIDEREADONLY, _T("AutoCAD File(*.dwg)|*.dwg||"),NULL);
		if ( dlg.DoModal() == IDOK )
			strPath = dlg.GetPathName();
	}

	return strPath;
}

BOOL CDwgDataToXml::OpenDwg( CString &strPath )
{
	//判断文件是否存在
	TCHAR fullpath[356]; 
	if (acedFindFile(strPath,fullpath) != RTNORM)
	{
		acdbFail(_T("工程文件没有找到!"));
		return TRUE;
	}
	//打开文件
	if (!acDocManager->isApplicationContext()) 
		return FALSE;

	// 查看文件是否已经打开,打开则不作处理
	AcApDocument *pDocOld;
	CString strFileName;
	AcApDocumentIterator *pIter  = acDocManager->newAcApDocumentIterator();
	Acad::ErrorStatus es = Acad::eOk;
	for(; !pIter->done(); pIter->step())
	{
		pDocOld = pIter->document();
		strFileName = pDocOld->fileName();
		if(strFileName.CompareNoCase(strPath) == 0)
		{
			delete pIter;
			es = acDocManager->setCurDocument(pDocOld,AcAp::kNone,true);

			return TRUE;
		}
	}
	delete pIter;

	// 没有打开
	if (!acDocManager->isApplicationContext()) 
		return FALSE;

	es = acDocManager->appContextOpenDocument((const TCHAR*)fullpath);
	if(es != Acad::eOk && es != Acad::eFilerError)	//注意!!!!如果是系统加载的时候会返回eFilerError
		return FALSE;

	return TRUE;
}

bool CDwgDataToXml::GetXYPoints(AcGePoint3dArray &vecPoint,CString& strLayer )
{
	//选择实体
	acutPrintf(_T("\n请选择实体:\n"));

	struct resbuf eb;  
	TCHAR sbuf[20];  
	eb.restype=0; //实体名  
	_tcscpy_s(sbuf,_T("LWPOLYLINE"));  
	eb.resval.rstring=sbuf;  
	eb.rbnext=NULL; //无其他内容  

	ads_name selectset;
	int rc = acedSSGet(_T(":S"),NULL,NULL,&eb,selectset);// :S表示单选
	if (rc == RTCAN)//用户取消请求
	{
		acedSSFree(selectset);
		return false;
	}
	else if (rc != RTNORM)   
	{
		acutPrintf(_T("\n选择实体不正确:\n"));
		acedSSFree(selectset);
		return false;
	}

	//获得实体ID
	AcDbObjectIdArray arrMemberId;
	BOOL bRet = GetIdArrayFromSS(selectset,arrMemberId);
	acedSSFree(selectset);
	if (!bRet)
		return false;

	//获得实体的坐标点
	if (arrMemberId.length() == 1)
		GetPosAndLayerFromId(arrMemberId[0], vecPoint,strLayer);

	return true;
}

bool CDwgDataToXml::GetLabelFromXZJ(CString& strLayer)
{
	//图层
	struct resbuf* eb = NULL;
	eb = acutBuildList(-4, _T("<or"), 8, strLayer,                        
		-4, _T("or>"),NULL);

	ads_name SelName;
	int rc = acedSSGet(_T("X"), NULL, NULL,eb, SelName);
	acutRelRb(eb);
	if (rc != RTNORM)   
	{
		acedSSFree(SelName);
		return false;
	}

	long len = 0; 
	acedSSLength(SelName,&len);
	for (long i = 0; i < len; i++)
	{
		ads_name entName;
		if (acedSSName(SelName, i, entName) != RTNORM) continue;

		AcDbObjectId eid = AcDbObjectId::kNull;
		acdbGetObjectId(eid, entName);
		if (eid == AcDbObjectId::kNull)
			continue;

		GetLableDataFromId(eid);
	}

	acedSSFree(SelName);
	return true;
}

bool CDwgDataToXml::GetLableDataFromId( AcDbObjectId &Id)
{
	//得到实体
	AcDbEntity* pEnt = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
	if (es != Acad::eOk || NULL == pEnt)
		return false;

	bool bRet = true;
	AcGePoint3d ptPoint;//点位置
	CString strName;//标注
	if (pEnt->isA() == AcDbText::desc())//单文本
	{
		//标注
		AcDbText *pText = AcDbText::cast(pEnt);
		if (NULL == pText)
			bRet = false;
		else
		{
			strName = pText->textString();
			ptPoint = pText->position();
			pText->close();
		}	
	}
	else if (pEnt->isA() == AcDbMText::desc())//多文本
	{
		AcDbMText *pText = AcDbMText::cast(pEnt);
		if (NULL == pText)
			bRet = false;
		else
		{
			strName = pText->text();
			ptPoint = pText->location();
			pText->close();
		}
	}
	else
		bRet = false;

	if (!bRet)
	{
		pEnt->close();
		return true;
	}
	
	m_mapLable[strName] = ptPoint;

	pEnt->close();
	return true;
}

CString CDwgDataToXml::GetNearestLable(const AcGePoint3d ptPoint)
{
	double dCurDistance = 0.0;
	std::map<CString,AcGePoint3d>::iterator it = m_mapLable.begin();
	CString strName = it->first;
	double dMinDistance = (ptPoint - m_mapLable[strName]).length();
	for (; it != m_mapLable.end(); ++it)
	{
		dCurDistance = (ptPoint - m_mapLable[it->first]).length();
		if(dCurDistance < dMinDistance)
		{
			dMinDistance = dCurDistance;
			strName = it->first;	
		}	
	}

	return strName;
}

std::vector<CPoleData> CDwgDataToXml::GetPoleData(AcGePoint3dArray vecXYPoint)
{
	m_vecPoleData.clear();
	if (m_mapLable.size() < 1)
		return m_vecPoleData;

	for (int nIndex = 0; nIndex < vecXYPoint.length(); ++nIndex)
	{
		CPoleData poleData;
		poleData.ptPolePoint = vecXYPoint[nIndex];
		poleData.strName = GetNearestLable(vecXYPoint[nIndex]);
		
		m_vecPoleData.push_back(poleData);
	}
	
	return m_vecPoleData;
}

bool CDwgDataToXml::GetUserConfigFilePath( LPCTSTR lpFileName, std::wstring& strFilePath )
{
	strFilePath.clear();
	// 取得APP Data的路径
	TCHAR szFilePath[MAX_PATH+1];
	memset(szFilePath, 0, MAX_PATH+1);
	GetModuleFileName(_hdllInstance, szFilePath, MAX_PATH);
	CString strPath(szFilePath);
	CDwgDataToXml kml;
	kml.GetParentPath(strPath);
	kml.GetParentPath(strPath);
	kml.GetParentPath(strPath);

	// 在用户路径下查找文件
	std::wstring strUFilePath = strPath + _T("\\Config\\") + lpFileName;
	if (-1 != _taccess(strUFilePath.c_str(), 0))
	{
		strFilePath = strUFilePath;
		return true;
	}

	return !strFilePath.empty();
}

void CDwgDataToXml::SetLayerName( CString strLayerName )
{
	m_strLayerName = strLayerName;
}

设置7参数界面:

ParameterManageDlg.h

#pragma once
#include "resource.h"
#include "CoordManageDlg.h"

// CParameterManageDlg		参数管理	对话框		2017.10.18		
class CParameterManageDlg : public CDialog
{
	DECLARE_DYNAMIC(CParameterManageDlg)

public:
	CParameterManageDlg(std::map<CString,CSevenParam>& mapSevenParam,CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CParameterManageDlg();

// 对话框数据
	enum { IDD = IDD_DLG_PARAMETER_MG };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
	virtual BOOL OnInitDialog();
	afx_msg void OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult);//单击事件
	afx_msg void OnBnClickedBtnClear();//清除
	afx_msg void OnBnClickedBtnSave();//保存
	afx_msg void OnBnClickedOk();//确定

private:
	//初始化下拉框
	void InitCombox();
	//初始化表
	void InitList();

	//清除小数点和多余的0
	CString ClearZero(double dValue);

	//校验是否添加列表(返回false,名称重复,返回true,nrow大于-1时修改现有list,否则增加一行)
	bool CheckIsAddList(CString strName,CString strCur,CString strTar,int &nRow );
private:
	CComboBox m_cmbCurCoordSystem;
	CComboBox m_cmbTarCoordSystem;
	CEdit m_editName;
	CEdit m_editDX;
	CEdit m_editDY;
	CEdit m_editDZ;
	CEdit m_editK;
	CEdit m_editRX;
	CEdit m_editRY;
	CEdit m_editRZ;
	CListCtrl m_list;

	std::map<CString,CSevenParam>& m_mapSevenParam;
};

ParameterManageDlg.cpp

// ParameterManageDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "ParameterManageDlg.h"
#include "afxdialogex.h"
#include "PrjStruct.h"


// CParameterManageDlg 对话框

IMPLEMENT_DYNAMIC(CParameterManageDlg, CDialog)

CParameterManageDlg::CParameterManageDlg(std::map<CString,CSevenParam>& mapSevenParam,CWnd* pParent /*=NULL*/)
	: CDialog(CParameterManageDlg::IDD, pParent)
	,m_mapSevenParam(mapSevenParam)
{

}

CParameterManageDlg::~CParameterManageDlg()
{
}

void CParameterManageDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CMB_CURCOORDSYSTEM, m_cmbCurCoordSystem);
	DDX_Control(pDX, IDC_CMB_TARCOORDSYSTEM, m_cmbTarCoordSystem);
	DDX_Control(pDX, IDC_EDIT_NAME, m_editName);
	DDX_Control(pDX, IDC_EDIT_DX, m_editDX);
	DDX_Control(pDX, IDC_EDIT_DY, m_editDY);
	DDX_Control(pDX, IDC_EDIT_DZ, m_editDZ);
	DDX_Control(pDX, IDC_EDIT_K , m_editK );
	DDX_Control(pDX, IDC_EDIT_RX, m_editRX);
	DDX_Control(pDX, IDC_EDIT_RY, m_editRY);
	DDX_Control(pDX, IDC_EDIT_RZ, m_editRZ);
	DDX_Control(pDX, IDC_LIST, m_list);
}


BEGIN_MESSAGE_MAP(CParameterManageDlg, CDialog)
	ON_BN_CLICKED(IDC_BTN_CLEAR, &CParameterManageDlg::OnBnClickedBtnClear)
	ON_BN_CLICKED(IDC_BTN_SAVE, &CParameterManageDlg::OnBnClickedBtnSave)
	ON_BN_CLICKED(IDOK, &CParameterManageDlg::OnBnClickedOk)
	ON_NOTIFY(NM_CLICK, IDC_LIST, &CParameterManageDlg::OnNMClickList)
END_MESSAGE_MAP()


// CParameterManageDlg 消息处理程序
BOOL CParameterManageDlg::OnInitDialog()
{
	__super::OnInitDialog();

	InitCombox();
	InitList();

	return TRUE;  
}

void CParameterManageDlg::InitCombox()
{
	//当前坐标系
	int nIndex = m_cmbCurCoordSystem.AddString(_T("1954北京坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,1);
	nIndex = m_cmbCurCoordSystem.AddString(_T("1980西安坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,2);
	nIndex = m_cmbCurCoordSystem.AddString(_T("WGS84坐标系"));
	m_cmbCurCoordSystem.SetItemData(nIndex,3);
	m_cmbCurCoordSystem.SetCurSel(0);

	//当前坐标系
	nIndex = m_cmbTarCoordSystem.AddString(_T("1954北京坐标系"));
	m_cmbTarCoordSystem.SetItemData(nIndex,1);
	nIndex = m_cmbTarCoordSystem.AddString(_T("1980西安坐标系"));
	m_cmbTarCoordSystem.SetItemData(nIndex,2);
	nIndex = m_cmbTarCoordSystem.AddString(_T("WGS84坐标系"));
	m_cmbTarCoordSystem.SetItemData(nIndex,3);
	m_cmbTarCoordSystem.SetCurSel(2);
}


void CParameterManageDlg::OnBnClickedBtnClear()
{
	CString strTemp = _T("");
	m_editName.SetWindowText(strTemp);
	m_editDX.SetWindowText(strTemp);
	m_editDY.SetWindowText(strTemp);
	m_editDZ.SetWindowText(strTemp);
	m_editRX.SetWindowText(strTemp);
	m_editRY.SetWindowText(strTemp);
	m_editRZ.SetWindowText(strTemp);
	m_editK.SetWindowText(strTemp);
}

void CParameterManageDlg::OnBnClickedBtnSave()
{
	CString strError;
	CString strName;
	m_editName.GetWindowText(strName);
	if (strName.IsEmpty())
		strError = _T("名称");

	CString strDX;
	m_editDX.GetWindowText(strDX);
	if (strDX.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("DX");
	}

	CString strDY;
	m_editDY.GetWindowText(strDY);
	if (strDY.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("DY");
	}

	CString strDZ;
	m_editDZ.GetWindowText(strDZ);
	if (strDZ.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("DZ");
	}

	CString strRX;
	m_editRX.GetWindowText(strRX);
	if (strRX.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("RX");
	}

	CString strRY;
	m_editRY.GetWindowText(strRY);
	if (strRY.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("RY");
	}

	CString strRZ;
	m_editRZ.GetWindowText(strRZ);
	if (strRZ.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("RZ");
	}

	CString strK;
	m_editK.GetWindowText(strK);
	if (strK.IsEmpty())
	{
		if (!strError.IsEmpty())
			strError += _T(",");
		strError += _T("K");
	}

	if (!strError.IsEmpty())
	{
		CString strTemp;
		strTemp.Format(_T("%s为空,请先填写完整!"),strError);
		AfxMessageBox(strTemp);
		return;
	}

	int nRow = -1;
	CString strCur;
	m_cmbCurCoordSystem.GetWindowText(strCur);
	CString strTar;
	m_cmbTarCoordSystem.GetWindowText(strTar);

	if (!CheckIsAddList(strName,strCur,strTar,nRow))
		return;

	//加入表格
	CString strRow;
	if (-1 == nRow)
	{
		nRow = m_list.GetItemCount();
		strRow.Format(_T("%d"),nRow);
		m_list.InsertItem(nRow, strRow); 
	}
	
	m_list.SetItemText(nRow, 0, strCur); 
	m_list.SetItemText(nRow, 1, strTar);
	m_list.SetItemText(nRow, 2, strDX);
	m_list.SetItemText(nRow, 3, strDY);
	m_list.SetItemText(nRow, 4, strDZ);
	m_list.SetItemText(nRow, 5, strRX);
	m_list.SetItemText(nRow, 6, strRY);
	m_list.SetItemText(nRow, 7, strRZ);
	m_list.SetItemText(nRow, 8, strK);
	m_list.SetItemText(nRow, 9, strName);
}

void CParameterManageDlg::InitList()
{
	CRect rect; 
	m_list.GetClientRect(&rect);
	m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	m_list.InsertColumn(0, _T("源坐标系"), LVCFMT_CENTER, rect.Width()/9, 0);
	m_list.InsertColumn(1, _T("目标坐标系" ), LVCFMT_CENTER, rect.Width()/9, 1);   
	m_list.InsertColumn(2, _T("DX"	), LVCFMT_CENTER, rect.Width()/9, 2);
	m_list.InsertColumn(3, _T("DY"   ), LVCFMT_CENTER, rect.Width()/9, 3);   
	m_list.InsertColumn(4, _T("DZ"	), LVCFMT_CENTER, rect.Width()/9, 4);
	m_list.InsertColumn(5, _T("RX"	), LVCFMT_CENTER, rect.Width()/9, 5);
	m_list.InsertColumn(6, _T("RY"   ), LVCFMT_CENTER, rect.Width()/9, 6);   
	m_list.InsertColumn(7, _T("RZ"	), LVCFMT_CENTER, rect.Width()/9, 7);
	m_list.InsertColumn(8, _T("K" ), LVCFMT_CENTER, rect.Width()/9, 8);  
	m_list.InsertColumn(9,_T("名称"),LVCFMT_CENTER,0,9);

	CString strTemp;
	CString strRow;
	std::map<CString,CSevenParam>::iterator it = m_mapSevenParam.begin();
	for (int nRow = 0; it != m_mapSevenParam.end(); ++it,++nRow)
	{
		strRow.Format(_T("%d"),nRow);
		m_list.InsertItem(nRow, strRow); 
		m_list.SetItemText(nRow, 0, it->second.m_strCur); 
		m_list.SetItemText(nRow, 1, it->second.m_strTar);
		m_list.SetItemText(nRow, 2, ClearZero(it->second.m_dDX)); 
		m_list.SetItemText(nRow, 3, ClearZero(it->second.m_dDY)); 
		m_list.SetItemText(nRow, 4, ClearZero(it->second.m_dDZ)); 
		m_list.SetItemText(nRow, 5, ClearZero(it->second.m_dRX)); 
		m_list.SetItemText(nRow, 6, ClearZero(it->second.m_dRY)); 
		m_list.SetItemText(nRow, 7, ClearZero(it->second.m_dRZ)); 
		m_list.SetItemText(nRow, 8, ClearZero(it->second.m_dK)); 
		m_list.SetItemText(nRow, 9, it->first); 
	} 
}

bool CParameterManageDlg::CheckIsAddList(CString strName, CString strCur,CString strTar,int &nRow )
{
	UpdateData(FALSE);
	CString strText;
	for (int row = 0; row < m_list.GetItemCount(); ++row)
	{
		strText = m_list.GetItemText(row,0);
		if (strText == strCur)
		{
			strText = m_list.GetItemText(row,1);
			if (strText == strTar)
			{
				nRow = row;
				break;
			}
		}
	}

	//校验名称
	for (int row = 0; row < m_list.GetItemCount(); ++row)
	{
		if (nRow == row)
			continue;
		
		strText = m_list.GetItemText(row,9);
		if (strText == strName)
		{
			strText.Format(_T("%s名称已经存在,不能保存!"),strName);
			AfxMessageBox(strText);
			return false;
		}
	}

	return true;
}

void CParameterManageDlg::OnBnClickedOk()
{
	m_mapSevenParam.clear();
	CString strText;
	for (int nRow = 0; nRow < m_list.GetItemCount(); ++nRow)
	{
		CSevenParam SevenParam;
		strText = m_list.GetItemText(nRow,9);
		
		SevenParam.m_strCur = m_list.GetItemText(nRow,0);
		SevenParam.m_strTar = m_list.GetItemText(nRow,1);
		CString str = m_list.GetItemText(nRow,2);
		SevenParam.m_dDX = _tstof(m_list.GetItemText(nRow,2));
		SevenParam.m_dDY = _tstof(m_list.GetItemText(nRow,3));	
		SevenParam.m_dDZ = _tstof(m_list.GetItemText(nRow,4));	
		SevenParam.m_dRX = _tstof(m_list.GetItemText(nRow,5));	
		SevenParam.m_dRY = _tstof(m_list.GetItemText(nRow,6));	
		SevenParam.m_dRZ = _tstof(m_list.GetItemText(nRow,7));	
		SevenParam.m_dK  = _tstof(m_list.GetItemText(nRow,8));	

		m_mapSevenParam[strText] = SevenParam;
	}
	
	__super::OnOK();
}


void CParameterManageDlg::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	int nSel=m_list.GetSelectionMark();
	CString strCur = m_list.GetItemText(nSel,0);
	m_cmbCurCoordSystem.SetWindowText(strCur);
	CString strTar = m_list.GetItemText(nSel,1);
	m_cmbTarCoordSystem.SetWindowText(strTar);
	CString strDX = m_list.GetItemText(nSel,2);
	m_editDX.SetWindowText(strDX);
	CString strDY = m_list.GetItemText(nSel,3);
	m_editDY.SetWindowText(strDY);
	CString strDZ = m_list.GetItemText(nSel,4);
	m_editDZ.SetWindowText(strDZ);
	CString strRX = m_list.GetItemText(nSel,5);
	m_editRX.SetWindowText(strRX);
	CString strRY = m_list.GetItemText(nSel,6);
	m_editRY.SetWindowText(strRY);
	CString strRZ = m_list.GetItemText(nSel,7);
	m_editRZ.SetWindowText(strRZ);
	CString strK = m_list.GetItemText(nSel,8);
	m_editK.SetWindowText(strK);
	CString strName = m_list.GetItemText(nSel,9);
	m_editName.SetWindowText(strName);
}

CString CParameterManageDlg::ClearZero( double dValue )
{
	CString strValue ;
	strValue.Format(_T("%.20f"),dValue);
	strValue.TrimRight(_T("0"));
	strValue.TrimRight(_T("."));
	return strValue;
}

7参数是保存到配置文件里的, XMLExt.cpp 用的还是第一版本的, PrjStruct.h 中把xml改为了kml,以及7参数的保存的xml

PrjStruct.h

#pragma once
#include <vector>
#include <msxml2.h>
#import <MSXML.DLL> named_guids

class CIniFileN;
/////////////////////////////////////////////////////////////////////////////////////////////
// class CXMLElement 保存、合成XML格式的基类 
/////////////////////////////////////////////////////////////////////////////////////////////
interface __declspec(dllexport) CXMLElement
{
public:
	CXMLElement():m_strverencoding(_T("version=\'1.0\'")){}
	virtual ~CXMLElement(){}
public:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadXML(IN LPCTSTR lpXMLStr)=0;
	virtual bool LoadXML(MSXML::IXMLDOMNodePtr pNode)=0;

	// 将成员值,保存为XML格式
	virtual bool SaveXML( CString* strXML)const=0;
	virtual bool SaveXML( MSXML::IXMLDOMNodePtr pNode)const=0;

	// 函数自测试 
	virtual bool SelfTest(){return false;};

	// 取得根节点名
	LPCTSTR GetRootNodeIn()const{return GetRootNode();}
public:
	// 保存到XML文件 
	virtual bool SaveXMLFile(LPCTSTR lpFileName)const;

	// 读取XML文件 
	virtual bool LoadXMLFile(LPCTSTR lpFileName);

	// [需要GetRootNode()节点] 
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode)=0;

	// 将成员值,保存为XML格式 
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const=0;

	// 取得根节点名 
	virtual LPCTSTR GetRootNode()const=0;

	// 设置xml文件头部的version='1.0' encoding='GB2312',默认为 version='1.0',不指定编码方式
	void SetVersionEncoding(LPCTSTR lpverencod);

private:
	CString m_strverencoding;
};
/////////////////////////////////////////////////////////////////////////////////////////////
// struct CHHElement: public CXMLElement 对基类的次级封装,目的统一完成某几个函数 
/////////////////////////////////////////////////////////////////////////////////////////////
struct __declspec(dllexport) CHHElement: public CXMLElement
{
public:
	CHHElement();
	~CHHElement();
public:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadXML(IN LPCTSTR lpXMLStr);
	virtual bool LoadXML(MSXML::IXMLDOMNodePtr pNode){return LoadNodeXML(pNode);}

	// 将成员值,保存为XML格式 
	virtual bool SaveXML(CString* strXML)const;
	virtual bool SaveXML(MSXML::IXMLDOMNodePtr pNode)const{return SaveNodeXML(pNode);}
};


/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrBase  数组封装 
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
struct __declspec(dllexport) CArrBase: public std::vector<T>
{
public:

	// 查找序号 
	template<class _Pr>
	int Find(_Pr op )const
	{
		std::vector<T>::const_iterator mIter = std::find_if(begin(), end(), op);
		if ( mIter == end() )
			return -1;
		return mIter-begin();
	}

	template<class _Pr>
	std::vector<int> FindAll(_Pr op )const
	{
		std::vector<int> arrRet;
		for (int i=0; i<(int)size(); ++i)
		{
			if ( op(at(i)))
			{
				arrRet.push_back(i);
			}
		}
		return arrRet;
	}
	// 排序 
	template<class _Pr>
	__inline void Sort(_Pr op) { std::sort(begin(), end(), op); }
	__inline void Sort(){std::sort(begin(), end());}

	// 清除指定序号记录 
	__inline virtual void RemoveAt(int nIndex)
	{ 
		if ( nIndex>=0 && nIndex<(int)size() )
		{
			erase(begin()+nIndex); 
		}
	}
};

/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementTest: protected CArrBase<CXMLElement*> 元素自测试数组 
/////////////////////////////////////////////////////////////////////////////////////////////
struct __declspec(dllexport) CArrElementTest: protected CArrBase<CXMLElement*>
{
public:
	CArrElementTest();
	virtual ~CArrElementTest();
public:
	// 添加一个测试实体 
	template<class T>
	void Add()
	{
		T* pItem = new T;
		push_back(pItem);
	}
	// 清除全部 
	virtual void clear();
	// 进行自测试 
	virtual void TestAll();
};

/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementBase: public CHHElement, public CArrBase<T>  元素数组操作封装 
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
struct __declspec(dllexport) CArrElementBase: public CHHElement, public CArrBase<T>
{
	typedef const CArrBase<T>* _CArrBasePtr;
public:
	// 重载等号/不等号 
	bool operator == (const CArrElementBase&p1 )const { return *((_CArrBasePtr)this)==*((_CArrBasePtr)(&p1));}
	bool operator != (const CArrElementBase&p1 )const { return !(*this==p1); }
protected:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode)
	{
		try
		{
			// 解析取每个元素
			T tmp;
			MSXML::IXMLDOMNodeListPtr pNodeList = pNode->selectNodes(tmp.GetRootNodeIn());
			const int nCount = pNodeList->Getlength();
			if ( nCount < 1 )
				return true;

			// 循环创建每个元素信息
			for (int i=0; i<nCount; ++i)
			{
				// 取得节点信息
				T mInfo;
				if(!mInfo.LoadXML(pNodeList->Getitem(i)))
					 continue;
				push_back(mInfo);
			}
		}
		catch(...)
		{
			return false;
		}
		return true;
	}
	// 将成员值,保存为XML格式 
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const
	{
		const int nCount = size();
		for (int i=0; i<nCount; ++i)
		{
			// 一条信息
			const T& mItem = at(i);
			try
			{
				// 创建一个节点
				MSXML::IXMLDOMNodePtr pNew = pNode->GetownerDocument()->createElement(mItem.GetRootNodeIn());
				if(!pNode->appendChild(pNew))
					 continue;

				// 保存节点信息
				if(!mItem.SaveXML(pNew))
					return false;
			}
			catch(...)
			{
				continue;
			}
		}
		return true;
	}
};

//桩位信息
class __declspec(dllexport) CPointInfo : public CHHElement
{
public:
	CPointInfo(){}
	~CPointInfo(){}

public:
	CString m_strCoord;
	CString m_strName;
protected:
	static LPCTSTR node_Point;//节点
	static LPCTSTR glb_strCoord;
	static LPCTSTR glb_strName;

public:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

class __declspec(dllexport) CPlacemark : public CHHElement
{
public:
	CPlacemark(){}
	~CPlacemark(){}
public:
	CPointInfo m_Point;
	CString m_strName;
protected:
	static LPCTSTR node_Placemark;//节点
	static LPCTSTR glb_strName;
public:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};


class __declspec(dllexport)	CHHDocument : CHHElement
{
public:
	CHHDocument();
	virtual~CHHDocument();

public:
	CPlacemark m_Placemark;
protected:
	static LPCTSTR node_Document;//节点
protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};

public:
	//读取XML格式的字符串
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	//保存成xml格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

class __declspec(dllexport)	CKmlXmlns : public  CHHElement
{
public:
	CKmlXmlns();
	virtual~CKmlXmlns(){}

public:
	CString m_strXmlns;
	CHHDocument m_Document;
protected:
	static LPCTSTR node_Kml;//节点

	static LPCTSTR glb_strXmlns;
protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};

public:
	//读取XML格式的字符串
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	//保存成xml格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

//坐标转换参数
class __declspec(dllexport)	CCoordTrans : public  CHHElement
{
public:
	CCoordTrans();
	virtual~CCoordTrans(){}

public:
	CString m_strName;
	CString m_strCur;
	CString m_strTar;
	double m_dDX;
	double m_dDY;
	double m_dDZ;
	double m_dRX;
	double m_dRY;
	double m_dRZ;
	double m_dK;
protected:
	static LPCTSTR node_root;//节点
	static LPCTSTR glb_strName;
	static LPCTSTR glb_strCur;
	static LPCTSTR glb_strTar;
	static LPCTSTR glb_strDX;
	static LPCTSTR glb_strDY;
	static LPCTSTR glb_strDZ;
	static LPCTSTR glb_strRX;
	static LPCTSTR glb_strRY;
	static LPCTSTR glb_strRZ;
	static LPCTSTR glb_strK;
protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};

public:
	//读取XML格式的字符串
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	//保存成xml格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};
struct __declspec(dllexport)CCoordTransArr: public CArrElementBase<CCoordTrans>
{
public:
	CCoordTransArr();
	virtual ~CCoordTransArr();
protected:
	static LPCTSTR node_root;//!< 根节点
protected:
	// 取得根节点名
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};
	// [需要node_root节点]
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);

	// 将成员值,保存为XML格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;
public:
	// 取得根结点
	static LPCTSTR GetSelfRoot();
};

//多段线图层
class __declspec(dllexport)	CPolyLineLayer : public  CHHElement
{
public:
	CPolyLineLayer();
	virtual~CPolyLineLayer(){}

public:
	CString m_strLayerName;
protected:
	static LPCTSTR node_root;//节点

	static LPCTSTR glb_strLayerName;
protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};

public:
	//读取XML格式的字符串
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	//保存成xml格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

PrjStruct.cpp

#include "StdAfx.h"
#include "PrjStruct.h"
#include "XMLExt.h"
#import <MSXML.DLL> named_guids

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpFileName
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CXMLElement::SaveXMLFile( LPCTSTR lpFileName ) const
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false; 

		MSXML::IXMLDOMProcessingInstructionPtr pi = pXmlDoc->createProcessingInstruction(_T("xml"), (LPCTSTR)m_strverencoding);
		_variant_t vNullVal;
		vNullVal.vt = VT_NULL;
		pXmlDoc->insertBefore(pi, vNullVal);

		MSXML::IXMLDOMNodePtr pRoot = pXmlDoc->createElement(GetRootNode());
		if(!pXmlDoc->appendChild(pRoot))
			return false;

		// 向节点中写信息
		if(!SaveNodeXML(pRoot))
			return false;

		// 取得XML信息
		pXmlDoc->save(lpFileName);
	}
	catch(...)
	{
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 读取XML文件
//! @param LPCTSTR lpFileName XML文件名称
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CXMLElement::LoadXMLFile( LPCTSTR lpFileName )
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false; 

		// 取得XML信息
		if(!pXmlDoc->load(lpFileName))
			return false;
		return LoadNodeXML(pXmlDoc->GetdocumentElement());
	}
	catch(...)
	{
		return false;
	}
	return true;
}

void CXMLElement::SetVersionEncoding(LPCTSTR lpverencod)
{
	if (lpverencod != NULL && lpverencod[0] != _T('\0'))
		m_strverencoding = lpverencod;
}



/////////////////////////////////////////////////////////////////////////////////////////////
// struct CHHElement: public CXMLElement 对基类的次级封装,目的统一完成某几个函数 
/////////////////////////////////////////////////////////////////////////////////////////////
CHHElement::CHHElement()
{
}
CHHElement::~CHHElement()
{
}
// 读取XML格式的字符串,给成员赋值
bool CHHElement::LoadXML(IN LPCTSTR lpXMLStr)
{
	try
	{
		// 载入字符串
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false;
		if(!pXmlDoc->loadXML(lpXMLStr));
			return false;

		if(!LoadNodeXML(pXmlDoc->GetdocumentElement()))
			return false;
	}
	catch(...)
	{
		return false;
	}
	return true;
}
// 将成员值,保存为XML格式 
bool CHHElement::SaveXML(CString* strXML)const
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK )
			return false;
		MSXML::IXMLDOMNodePtr pRoot = pXmlDoc->createElement(GetRootNode());
		if(!pXmlDoc->appendChild(pRoot))
			return false;

		// 向节点中写信息
		if(!SaveNodeXML(pRoot))
			return false;

		// 取得XML信息
		*strXML = (LPCTSTR)pXmlDoc->Getxml();
	}
	catch(...)
	{
		return false;
	}
	return true;
}


/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementTest: protected CArrBase<CXMLElement*> 元素自测试数组 
/////////////////////////////////////////////////////////////////////////////////////////////
CArrElementTest::CArrElementTest()
{
}
CArrElementTest::~CArrElementTest()
{
	clear();
}
void CArrElementTest::clear()
{
	const int nCount = size();
	for (int i=0; i<nCount; ++i)
	{
		delete at(i);
	}
	clear();

}
// 进行自测试 
void CArrElementTest::TestAll()
{
	const int nCount = size();
	for (int i=0; i<nCount; ++i)
	{
		if(!at(i)->SelfTest())
			return;
	}
}


//////////////////////////////桩位信息/////////////////////////
LPCTSTR CHHDocument::node_Document = _T("Document");
CHHDocument::CHHDocument()
{
}

CHHDocument::~CHHDocument()
{
}

LPCTSTR CHHDocument::GetSelfRoot()
{
	return node_Document;
}

bool CHHDocument::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	return true;
}

bool CHHDocument::SaveNodeXML(MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		
		pNodePtr.SetToSubPtr(CPlacemark::GetSelfRoot(), true);
		return m_Placemark.SaveNodeXML(pNodePtr.GetNodePtr());
	}
	catch(...)
	{
		return false;
	}
	return true;
}

LPCTSTR CPointInfo::node_Point		= _T("LineString"	);
LPCTSTR CPointInfo::glb_strCoord	= _T("coordinates"	);
LPCTSTR CPointInfo::glb_strName		= _T("zhuangs"	);
LPCTSTR CPointInfo::GetSelfRoot()
{
	return node_Point;
}

bool CPointInfo::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

bool CPointInfo::SaveNodeXML(MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.SetNodeVar(glb_strName,m_strName);
		pNodePtr.SetNodeVar(glb_strCoord,m_strCoord);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

LPCTSTR CKmlXmlns::node_Kml			= _T("kml"	);
LPCTSTR CKmlXmlns::glb_strXmlns		= _T("xmlns");
CKmlXmlns::CKmlXmlns()
{
	m_strXmlns = _T("http://www.opengis.net/kml/2.2");
}
bool CKmlXmlns::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	return true;
}

bool CKmlXmlns::SaveNodeXML( MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.SetAttribute(glb_strXmlns,		 m_strXmlns);
		
		pNodePtr.SetToSubPtr(CHHDocument::GetSelfRoot(), true);
		return m_Document.SaveNodeXML(pNodePtr.GetNodePtr());
	}
	catch(...)
	{
		return false;
	}

	return true;
}

LPCTSTR CKmlXmlns::GetSelfRoot()
{
	return node_Kml;
}

LPCTSTR CPlacemark::node_Placemark	= _T("Placemark");
LPCTSTR CPlacemark::glb_strName		= _T("name");
bool CPlacemark::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	return true;
}

bool CPlacemark::SaveNodeXML( MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.SetNodeVar(glb_strName,m_strName );
		pNodePtr.SetToSubPtr(CPointInfo::GetSelfRoot(), true);
		return m_Point.SaveNodeXML(pNodePtr.GetNodePtr());
	}
	catch(...)
	{
		return false;
	}

	return true;
}

LPCTSTR CPlacemark::GetSelfRoot()
{
	return node_Placemark;
}

////////////////////////////////////////坐标转换参数/////////////////
LPCTSTR CCoordTransArr::node_root = _T("CoordTranss");// 根节点
CCoordTransArr::CCoordTransArr()
{

}

CCoordTransArr::~CCoordTransArr()
{
}

// 读取XML格式的字符串,给成员赋值
bool CCoordTransArr::LoadNodeXML(MSXML::IXMLDOMNodePtr pNode)
{
	try
	{
		if ( !__super::LoadNodeXML(pNode) )
			return false;
	}
	catch(...)
	{
		return false;
	}

	return true;
}

// 将成员值,保存为XML格式
bool CCoordTransArr::SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const
{
	try
	{
		if ( !__super::SaveNodeXML(pNode) )
			return false;
	}
	catch(...)
	{
		return false;
	}
	return true;
}
LPCTSTR CCoordTransArr::GetSelfRoot()
{
	return node_root;
}

LPCTSTR CCoordTrans::node_root		= _T("CoordTrans");
LPCTSTR CCoordTrans::glb_strName	= _T("Name"		 );
LPCTSTR CCoordTrans::glb_strCur		= _T("CurCoord"  );
LPCTSTR CCoordTrans::glb_strTar		= _T("TarCoord"  );
LPCTSTR CCoordTrans::glb_strDX		= _T("DX"		 );
LPCTSTR CCoordTrans::glb_strDY		= _T("DY"		 );
LPCTSTR CCoordTrans::glb_strDZ		= _T("DZ"		 );
LPCTSTR CCoordTrans::glb_strRX		= _T("RX"		 );
LPCTSTR CCoordTrans::glb_strRY		= _T("RY"		 );
LPCTSTR CCoordTrans::glb_strRZ		= _T("RZ"		 );
LPCTSTR CCoordTrans::glb_strK		= _T("K"		 );
CCoordTrans::CCoordTrans()
{
}
bool CCoordTrans::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.GetAttribute(glb_strName,m_strName);
		pNodePtr.GetAttribute(glb_strCur,m_strCur);
		pNodePtr.GetAttribute(glb_strTar,m_strTar);
		pNodePtr.GetAttribute(glb_strDX,m_dDX);
		pNodePtr.GetAttribute(glb_strDY,m_dDY);
		pNodePtr.GetAttribute(glb_strDZ,m_dDZ);
		pNodePtr.GetAttribute(glb_strRX,m_dRX);
		pNodePtr.GetAttribute(glb_strRY,m_dRY);
		pNodePtr.GetAttribute(glb_strRZ,m_dRZ);
		pNodePtr.GetAttribute(glb_strK,m_dK);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

bool CCoordTrans::SaveNodeXML( MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CString strTemp;
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.SetAttribute(glb_strName,m_strName);
		pNodePtr.SetAttribute(glb_strCur,m_strCur);
		pNodePtr.SetAttribute(glb_strTar,m_strTar);
		strTemp.Format(_T("%.20f"),m_dDX);
		pNodePtr.SetAttribute(glb_strDX,strTemp);
		strTemp.Format(_T("%.20f"),m_dDY);
		pNodePtr.SetAttribute(glb_strDY,strTemp);
		strTemp.Format(_T("%.20f"),m_dDZ);
		pNodePtr.SetAttribute(glb_strDZ,strTemp);
		strTemp.Format(_T("%.20f"),m_dRX);
		pNodePtr.SetAttribute(glb_strRX,strTemp);
		strTemp.Format(_T("%.20f"),m_dRY);
		pNodePtr.SetAttribute(glb_strRY,strTemp);
		strTemp.Format(_T("%.20f"),m_dRZ);
		pNodePtr.SetAttribute(glb_strRZ,strTemp);
		strTemp.Format(_T("%.20f"),m_dK);
		pNodePtr.SetAttribute(glb_strK,strTemp);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

LPCTSTR CCoordTrans::GetSelfRoot()
{
	return node_root;
}

/////////////////////////////////////多段线图层/////////////////////////////
LPCTSTR CPolyLineLayer::node_root			= _T("Layer");
LPCTSTR CPolyLineLayer::glb_strLayerName	= _T("Name"	);
CPolyLineLayer::CPolyLineLayer()
{
}

bool CPolyLineLayer::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.GetNodeVar(glb_strLayerName,m_strLayerName);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

bool CPolyLineLayer::SaveNodeXML( MSXML::IXMLDOMNodePtr pNode ) const
{
	return true;
}

LPCTSTR CPolyLineLayer::GetSelfRoot()
{
	return node_root;
}

坐标列表添加了右键菜单

CoordEditDlg.h

#pragma once
#include "Resource.h"
#include "afxwin.h"

// CCoordEditDlg 对话框
class CCoordEditDlg : public CDialog
{
	DECLARE_DYNAMIC(CCoordEditDlg)

public:
	CCoordEditDlg(CString& strName,CString& strXCoord, CString& strYCoord,CString& strLong, CString& strLat,CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CCoordEditDlg();

// 对话框数据
	enum { IDD = IDD_DLG_COORDEDIT };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	DECLARE_MESSAGE_MAP()
	virtual BOOL OnInitDialog();
	afx_msg void OnBnClickedOk();//确定
public:
	void GetData(CString& strName,CString& strXCoord, CString& strYCoord,CString& strLong, CString& strLat);
private:
	CEdit m_editName;
	CString m_strName;//名称
	CEdit m_editXCoord;
	CString m_strXCoord;//东坐标
	CEdit m_editYCoord;
	CString m_strYCoord;//北坐标
	CEdit m_editLong;
	CString m_strLong;//经度
	CEdit m_editLat;
	CString m_strLat;//纬度
};

CoordEditDlg.cpp

// CoordEditDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "CoordEditDlg.h"
#include "afxdialogex.h"

// CCoordEditDlg 对话框
IMPLEMENT_DYNAMIC(CCoordEditDlg, CDialog)
	CCoordEditDlg::CCoordEditDlg(CString& strName,CString& strXCoord, CString& strYCoord,CString& strLong, CString& strLat,CWnd* pParent /*=NULL*/)
	: CDialog(CCoordEditDlg::IDD, pParent)
	,m_strName(strName)
	,m_strXCoord(strXCoord)
	,m_strYCoord(strYCoord)
	,m_strLong(strLong)
	,m_strLat(strLat)
{
}

CCoordEditDlg::~CCoordEditDlg()
{
}

void CCoordEditDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDITNAME, m_editName);
	DDX_Control(pDX, IDC_EDITLONG, m_editLong);
	DDX_Control(pDX, IDC_EDITLAT, m_editLat);
	DDX_Control(pDX, IDC_EDIT_XCOORD, m_editXCoord);
	DDX_Control(pDX, IDC_EDIT_YCOORD, m_editYCoord);
}


BEGIN_MESSAGE_MAP(CCoordEditDlg, CDialog)
	ON_BN_CLICKED(IDOK, &CCoordEditDlg::OnBnClickedOk)
END_MESSAGE_MAP()

void CCoordEditDlg::OnBnClickedOk()
{
	m_editName.GetWindowText(m_strName);
	m_editXCoord.GetWindowText(m_strXCoord);
	m_editYCoord.GetWindowText(m_strYCoord);
	m_editLong.GetWindowText(m_strLong);
	m_editLat.GetWindowText(m_strLat);

	if (m_strName.IsEmpty() || m_strLong.IsEmpty() || m_strLat.IsEmpty() || m_strXCoord.IsEmpty() || m_strYCoord.IsEmpty())
	{
		MessageBox(_T("请将信息填写完整!"), _T("提示框"), MB_OK | MB_ICONHAND ); 
		return;
	}

	__super::OnOK();
}

BOOL CCoordEditDlg::OnInitDialog()
{
	__super::OnInitDialog();

	m_editName.ReplaceSel(m_strName);
	m_editXCoord.ReplaceSel(m_strXCoord);
	m_editYCoord.ReplaceSel(m_strYCoord);
	m_editLong.ReplaceSel(m_strLong);
	m_editLat.ReplaceSel(m_strLat);

	return TRUE;
}

void CCoordEditDlg::GetData( CString& strName,CString& strXCoord, CString& strYCoord,CString& strLong, CString& strLat )
{
	strName = m_strName;
	strXCoord = m_strXCoord;
	strYCoord = m_strYCoord;
	strLong = m_strLong;
	strLat = m_strLat;
}

导出Excel其中用到了Excel相关的类

ExcelReaderLibXl.h

#pragma once
#include <vector>
#include <string>

//! 读取excel中的数据 
struct CLibXlInfo;
class _declspec(dllexport) CExcelReaderLibXl
{
public:
	CExcelReaderLibXl(void);
	virtual ~CExcelReaderLibXl(void);

public:
	bool Open(CString& strXlsFile);
	bool Close();
	bool Save();//保存

public:
	long GetSheetCount();
	long GetRows(long lSheetIndex);
	long GetCols(long lSheetIndex);

	bool ReadRowTexts(long lSheetIndex , long lRow, std::vector<CString>& arrValues);
	//写入数据
	bool WirteCellText(long lSheetIndex , long lRow, long lCol, CString strValue);

private:
	CLibXlInfo* m_pBookInfo;	
};

ExcelReaderLibXl.cpp

#include "StdAfx.h"
#include "ExcelReaderLibXl.h"
#include "libxl-3.7.2.0\libxl.h"

struct CLibXlInfo
{
	CLibXlInfo	()
	: m_pBook(NULL)
	{
	}
	
	libxl::Book* m_pBook;
	CString m_strFileName;
};

CExcelReaderLibXl::CExcelReaderLibXl(void)
: m_pBookInfo(new CLibXlInfo)
{
}

CExcelReaderLibXl::~CExcelReaderLibXl(void)
{
	Close();
	delete m_pBookInfo;
}

bool CExcelReaderLibXl::Open(CString& strXlsFile)
{
	if (!Close())
		return false;
	
	CString strExt = strXlsFile;
	int nPos = strExt.ReverseFind(_T('.'));
	strExt = strExt.Right(strExt.GetLength() - nPos - 1);
	strExt.MakeUpper();

	m_pBookInfo->m_pBook = NULL;
	if (strExt == _T("XLS"))
		m_pBookInfo->m_pBook = xlCreateBook();
	else if (strExt == _T("XLSX"))
		m_pBookInfo->m_pBook = xlCreateXMLBook();

	if (NULL == m_pBookInfo->m_pBook)
		return false;

	//解锁
	m_pBookInfo->m_pBook->setKey(_T("Halil Kural"), _T("windows-2723210a07c4e90162b26966a8jcdboe"));

	if (!m_pBookInfo->m_pBook->load(strXlsFile))
	{
		Close();
		return false;
	}
	m_pBookInfo->m_strFileName = strXlsFile;

	return true;
}

//获取页数
long CExcelReaderLibXl::GetSheetCount()
{
	if (NULL == m_pBookInfo->m_pBook)
		return -1;

	return m_pBookInfo->m_pBook->sheetCount();
}

long CExcelReaderLibXl::GetRows(long lSheetIndex)
{
	if (NULL == m_pBookInfo->m_pBook)
		return -1;

	if (lSheetIndex < 0 || lSheetIndex >= m_pBookInfo->m_pBook->sheetCount())
		return -1;

	libxl::Sheet* pSheet = m_pBookInfo->m_pBook->getSheet(lSheetIndex);
	if (NULL == pSheet)
		return -1;

	return (pSheet->lastRow() - pSheet->firstRow() + 1);
}

long CExcelReaderLibXl::GetCols(long lSheetIndex)
{
	if (NULL == m_pBookInfo->m_pBook)
		return -1;

	if (lSheetIndex < 0 || lSheetIndex >= m_pBookInfo->m_pBook->sheetCount())
		return -1;

	libxl::Sheet* pSheet = m_pBookInfo->m_pBook->getSheet(lSheetIndex);
	if (NULL == pSheet)
		return -1;

	return (pSheet->lastCol() - pSheet->firstCol() + 1);
}

//读取一行数据 
bool CExcelReaderLibXl::ReadRowTexts(long lSheetIndex , long lRow, std::vector<CString>& arrValues)
{
	arrValues.clear();

	if (NULL == m_pBookInfo->m_pBook)
		return false;

	if (lSheetIndex < 0 || lSheetIndex >= m_pBookInfo->m_pBook->sheetCount())
		return false;

	libxl::Sheet* pSheet = m_pBookInfo->m_pBook->getSheet(lSheetIndex);
	if (NULL == pSheet)
		return false;

	long lRowNum = pSheet->lastRow() - pSheet->firstRow() + 1;
	long lColNum = pSheet->lastCol() - pSheet->firstCol() + 1;
	if (lRowNum < lRow)
		return false;

	CString strValue;
	//行列从0开始 
	for (long lColIndex = 0; lColIndex < lColNum; ++lColIndex)
	{
		strValue.Empty();
		libxl::CellType curCellType = pSheet->cellType(lRow, lColIndex);
		if (curCellType == libxl::CellType::CELLTYPE_NUMBER)
		{
			strValue.Format(_T("%f"), pSheet->readNum(lRow, lColIndex));
			strValue.TrimRight(_T("0"));
			strValue.TrimRight(_T("."));
		}
		else
		{
			strValue = pSheet->readStr(lRow, lColIndex);
		}

		arrValues.push_back(strValue);
	}

	return true;
}

bool CExcelReaderLibXl::Close()
{
	if (NULL == m_pBookInfo->m_pBook)
		return true;

	m_pBookInfo->m_pBook->release();
	m_pBookInfo->m_pBook = NULL;

	return true;
}

bool CExcelReaderLibXl::WirteCellText( long lSheetIndex , long lRow, long lCol, CString strValue )
{
	libxl::Sheet* pSheet = m_pBookInfo->m_pBook->getSheet(0);
	if (NULL == pSheet)
		return false;

	libxl::Font* pFont = m_pBookInfo->m_pBook->addFont();
	if (NULL == pFont)
		return false;
	pFont->setName(_T("宋体"));
	pFont->setSize(10);
	pFont->setColor(libxl::Color::COLOR_BLACK);
	
	libxl::Format* pFormat = m_pBookInfo->m_pBook->addFormat();
	if (NULL == pFormat)
		return false;
	pFormat->setFont(pFont);
	pFormat->setAlignH(libxl::AlignH::ALIGNH_LEFT);	
	pFormat->setPatternForegroundColor(libxl::Color::COLOR_NONE);
	
	if (!pSheet->writeStr(lRow,lCol, strValue,pFormat))
		return false;

	return true;
}

bool CExcelReaderLibXl::Save()
{
	return m_pBookInfo->m_pBook->save(m_pBookInfo->m_strFileName);
}

猜你喜欢

转载自my.oschina.net/u/2930533/blog/1573584
今日推荐