📄 gpspointdlg.cpp
字号:
// GpsPointDlg.cpp : implementation file
//
#include "stdafx.h"
#include "GpsPoint.h"
#include "GpsPointDlg.h"
#include <mmsystem.h>
#include "SysSetup.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CCriticalSection m_SoundLock; //读取和写入语音字符串锁
CCriticalSection m_ThreadLock; //语音线程,完整读音锁
//语音线程函数
UINT SoundThread(LPVOID pParam){
CString strTmp;
CString strSoundNum;
int *idx=(int*)pParam;
m_SoundLock.Lock();
strSoundNum.Format("%d",*idx);
m_SoundLock.Unlock();
m_ThreadLock.Lock();
for(int i=0;i<strSoundNum.GetLength();i++){
strTmp=strSoundNum.Mid(i,1);
sndPlaySound("waves\\" + strTmp + ".wav",SND_SYNC);
}
m_ThreadLock.Unlock();
return 0;
}
extern CGpsPointApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CGpsPointDlg dialog
CGpsPointDlg::CGpsPointDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGpsPointDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CGpsPointDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGpsPointDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGpsPointDlg)
DDX_Control(pDX, IDC_STATIC_MSG, m_Msg);
DDX_Control(pDX, IDC_CHECK_SOUND, m_BtnSound);
DDX_Control(pDX, IDC_STATIC_ICON, m_Icon);
DDX_Control(pDX, IDC_CHECK_LOG, m_BtnSave);
DDX_Control(pDX, IDC_CHECK_FILE, m_ReadFile);
DDX_Control(pDX, IDC_LIST_POINT, m_ListPoint);
DDX_Control(pDX, IDC_COMBO_TIME, m_Time);
DDX_Control(pDX, IDC_STATIC_POINT, m_SP);
DDX_Control(pDX, IDC_BUTTON_POINT, m_BtnPoint);
DDX_Control(pDX, IDC_BUTTON_SETUP, m_BtnSetup);
DDX_Control(pDX, IDC_BUTTON_START_END, m_BtnSatrtEnd);
DDX_Control(pDX, IDC_MSCOMM, m_MsComm);
DDX_Control(pDX, IDC_COMMDLG, m_Dlg);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGpsPointDlg, CDialog)
//{{AFX_MSG_MAP(CGpsPointDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_START_END, OnButtonStartEnd)
ON_BN_CLICKED(IDC_BUTTON_SETUP, OnButtonSetup)
ON_BN_CLICKED(IDC_BUTTON_POINT, OnButtonPoint)
ON_BN_CLICKED(IDC_BUTTON_DRAW, OnButtonDraw)
ON_WM_TIMER()
ON_CBN_SELCHANGE(IDC_COMBO_TIME, OnSelchangeComboTime)
ON_BN_CLICKED(IDC_CHECK_LOG, OnCheckLog)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_CHECK_SOUND, OnCheckSound)
ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGpsPointDlg message handlers
BOOL CGpsPointDlg::OnInitDialog()
{
CDialog::OnInitDialog();
PAI=3.1415926535898;
// 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
//配置文件的路径
strFile=CCommFun::GetAppPath("setup.ini");
strFile1=CCommFun::GetAppPath("point.ini");
strFile2=CCommFun::GetAppPath("log\\log.ini");
dLate0=0;
dLong0=0;
lTime0=0;
m_bSetPoint=FALSE;
m_bDraw=FALSE;
//定时器时间选择下拉框
CString strTmp;
for(int i=100;i<=5000;i+=100){
strTmp.Format("%d",i);
m_Time.InsertString((i/100)-1,strTmp);
}
m_iTimer=CCommFun::Getini("GPS设置","读取文件定时器周期",1000,strFile);
m_Time.SetCurSel(m_iTimer/100-1);
//是否需要保存
m_bSavePoint=CCommFun::Getini("GPS设置","记录轨迹",0,strFile);
m_BtnSave.SetCheck(m_bSavePoint);
//是报语音
m_bSound=CCommFun::Getini("GPS设置","报语音",0,strFile);
m_BtnSound.SetCheck(m_bSound);
//数字声音字符串
iSoundNum=-1;
//多线程句柄
hthread=NULL;
return TRUE; // return TRUE unless you set the focus to a control
}
// 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 CGpsPointDlg::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();
}
//画图
//CDC* pdc=this->GetDC();
//pdc->Ellipse(100,100,300,300);
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CGpsPointDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CGpsPointDlg::OnButtonStartEnd()
{
CString strTmp;
m_BtnSatrtEnd.GetWindowText(strTmp);
if(strTmp.Compare("采集")==0){
if(m_ReadFile.GetCheck()){//采集文件
//加载文件模拟GPS数据
//选择文件
m_Dlg.SetFileName("");
m_Dlg.ShowOpen();
strGpsFile=m_Dlg.GetFileName();
if(strGpsFile.Compare("")==0){
return;
}
//初始化
lastLL.dLate=0;
lastLL.dLong=0;
lastLL.lJiao=0;
lastLL.sDM="";
iCount=1;
this->SetTimer(1,m_iTimer,NULL);
}else{
//打开串口
m_MsComm.SetCommPort(CCommFun::Getini("系统设置","串口号",1,strFile));
strTmp=CCommFun::Getini("系统设置","波特率","4800",strFile);
strTmp+=",N,8,1";
m_MsComm.SetSettings(strTmp);
m_MsComm.SetPortOpen(TRUE);
if(!m_MsComm.GetPortOpen()){
return;
}else{
//清除接收缓存
m_MsComm.SetInBufferCount(0);
}
}
//取得设置的参数
m_BreakMeter=CCommFun::Getini("GPS设置","1秒允许的突变米数",10,strFile);
m_BreakTime=CCommFun::Getini("GPS设置","允许突变的秒数",3,strFile);
m_ErrorMrter=CCommFun::Getini("GPS设置","定位一个点的误差范围(米)",2,strFile);;
m_strAppTitle=CCommFun::Getini("系统设置","发送消息程序标题","",strFile);
m_CutTime=CCommFun::Getini("GPS设置","线段切圆的两点时间间隔",1,strFile);
m_Point=CCommFun::Getini("GPS设置","定点判定",1,strFile);
m_CutRound=CCommFun::Getini("GPS设置","穿圆判定",1,strFile);
m_Fangxiang=CCommFun::Getini("GPS设置","方向判定",1,strFile);
m_CutCount=CCommFun::Getini("GPS设置","线段切圆分段数",100,strFile);
m_Jiao=CCommFun::Getini("GPS设置","方向角允许误差",20,strFile);
m_bSound=CCommFun::Getini("GPS设置","报语音",0,strFile);
m_Code=CCommFun::Getini("GPS设置","返回定位点代码值",1,strFile);
m_Dis=CCommFun::Getini("GPS设置","返回与标准点的距离",1,strFile);
m_Error=CCommFun::Getini("GPS设置","返回定点误差范围",1,strFile);
//初始化
dLate0=0;
dLong0=0;
lTime0=0;
m_BtnSatrtEnd.SetWindowText("停止");
m_BtnSetup.EnableWindow(FALSE);
m_ReadFile.EnableWindow(FALSE);
m_Time.EnableWindow(FALSE);
m_BtnSave.EnableWindow(FALSE);
//加载点
LoadPoint();
//记录加一
if(m_bSavePoint){
int iCount=CCommFun::Getini(CCommFun::GetSysDateString(),"数量",0,strFile2)+1;
CCommFun::Writeini(CCommFun::GetSysDateString(),"数量",iCount,strFile2);
}
//清空记录先
while(m_ListPoint.GetCount()>0)
m_ListPoint.DeleteString(0);
for(int i=0;i<7;i++){
GpsDataCount[i]=0;
}
//设置图标
SetShowIcon(IDI_GPS_NONE);
}else{//关闭采集
m_bSound=FALSE;
iSoundNum=-1;
if(m_ReadFile.GetCheck()){//采集文件
this->KillTimer(1);
}else{
//关闭串口
m_MsComm.SetPortOpen(FALSE);
}
//关闭语音线程
if(hthread){
if(!(hthread->m_bAutoDelete)){
TerminateThread(hthread->m_hThread,0);
CloseHandle(hthread->m_hThread);
delete hthread;
hthread=NULL;
}
}
m_BtnSatrtEnd.SetWindowText("采集");
m_BtnSetup.EnableWindow(TRUE);
m_ReadFile.EnableWindow(TRUE);
m_Time.EnableWindow(TRUE);
m_BtnSave.EnableWindow(TRUE);
//初始化
dLate0=0;
dLong0=0;
lTime0=0;
//保存统计信息
if(m_bSavePoint){
this->GetWindowText(strTmp);
SavePointStat(strTmp);
}
//图标显示
m_Icon.SetIcon(theApp.LoadIcon(IDI_GPS_HAHA));
}
}
BEGIN_EVENTSINK_MAP(CGpsPointDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CGpsPointDlg)
ON_EVENT(CGpsPointDlg, IDC_MSCOMM, 1 /* OnComm */, OnOnCommMscomm, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
//捕获串口数据
void CGpsPointDlg::OnOnCommMscomm()
{
static CString strData="";
CString strTmp;
VARIANT vData;
short iEvent=m_MsComm.GetCommEvent();
switch(iEvent){
case 1://comEvSend 在传输缓冲区中有比 Sthreshold 数少的字符。
break;
case 2://comEvReceive 收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
vData=m_MsComm.GetInput();
strData+=CString(vData.bstrVal);
//判断GPS结尾
strTmp='\r';
strTmp+='\n';
if(strData.Right(2).Compare(strTmp)==0){
//分析GPS数据
DoGps(strData);
//释放
strData="";
}
break;
case 3://comEvCTS Clear To Send 线的状态发生变化。
break;
case 4://comEvDSR Data Set Ready 线的状态发生变化。该事件只在 DST 从 1 变到 0 时才发生。
break;
case 5://comEvCD Carrier Detect 线的状态发生变化。
break;
case 6://comEvRing 检测到振铃信号。一些 UART(通用异步接收— 传输)可能不支持该事件。
break;
case 7://comEvEOF 收到文件结束(ASCII 字符为 26)字符。
break;
}
}
//处理GPS数据
void CGpsPointDlg::DoGps(CString GPS)
{
int idxT,idxW;
CString strTmp;
CString strW;//GPS结尾
CString strT;//GPS头
strW='\r';
strW+='\n';
strT="$";
//使用的数据
CString GPGGA="";
CString GPVTG="";
//切分数据
for(int i=0;i<GPS.GetLength();i++){
//$...............\R\N;"
idxT=GPS.Find(strT);
idxW=GPS.Find(strW);
if(idxW>idxT){
strTmp=GPS.Mid(idxT,idxW-idxT+1);
//数据分类
if(strTmp.Left(6).Compare("$GPGGA")==0){//GPGGA数据
if(CGps::CheckGps(strTmp).Compare("")!=0){
//暂存等待速度方向数据
GPGGA=strTmp;
//正确的GPS数据计数
GpsDataCount[2]++;
}else{
//验证失败GPS数据计数
GpsDataCount[1]++;
//图标显示
SetShowIcon(IDI_GPS_ERROR);
}
//GPS数据计数
GpsDataCount[0]++;
}else if(strTmp.Left(6).Compare("$GPVTG")==0){//GPVTG数据
if(CGps::CheckGps(strTmp).Compare("")!=0){
//速度方向数据
GPVTG=strTmp;
}
}else{
SetShowIcon(IDI_GPS_NONE);
}
GPS.Delete(0,idxW+1);
}else{
GPS.Delete(0,idxW+1);
}
//处理GPGGA,GPVTG数据
if(GPGGA.Compare("")!=0){//有合格数据
if(m_Fangxiang){//判断方向
if(GPVTG.Compare("")!=0){//必须有方向数据
DoGPSData(GPGGA,GPVTG);
}
}else{
DoGPSData(GPGGA,GPVTG);
//清空,下一循环继续采集
GPGGA="";
GPVTG="";
}
}
}
}
//处理GPGGA数据
void CGpsPointDlg::DoGPSData(CString GPGGA, CString GPVTG)
{
double dLate;
double dLong; //当前取得的经纬度坐标
long lJiao; //方向角
double dV; //速度
long lRlt1; //返回结果
long lRlt2;
lRlt1=CGps::FilterLatLong(GPGGA,&dLate,&dLong);
lRlt2=CGps::FilterFV(GPVTG,&lJiao,&dV);
if(lRlt1==0){//正确的GPGGA数据
if(m_Fangxiang){//需要方向
if(lRlt2==0){
//处理经纬度数据
DoLateLong(dLate,dLong,0,lJiao,dV);
}
}else{
//处理经纬度数据
DoLateLong(dLate,dLong,0,lJiao,dV);
}
//卫星数足够的GPS数据计数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -