调用Esupermap库函数对图层操作的总结
接到要用esupermap在一个pmf地图文件上画点和线的小任务,但完成这个任务加上周末的话差不多用了一个星期,回想起这一路上碰到的问题及自己怎么一个个把它们干掉的,心中的激动之情油然而生。不过,话说回来,都怪自己对这方面的编程一点都不熟悉,所以特意在此总结一下,以备不时之需:
1. 首先得有一个Pmf地图文件。
话说开始给我的是一个mapinfo导出的地图文件,要用supermap先转换成数据源和工作区间,然后再用esupermap转换成Pmf文件。顺便在此提一下,基本上supermap生成的数据源和工作区间只能由其对应的esupermap版本转换,但恶心的是超图很难弄到esupermap的认证文件,所以转换的时候得花点功夫。可以提供一个小建议,采用截图的方式获取要操作的地图,然后导入supermap(我用的是20xx版),再用esupermap1.0转换,这两个版本虽然不是对应的,但能够转换过来真是庆幸。
Copy师兄的一句话提醒自己:任务是死的,人是活的。真的,不是任务太难完成,是你脑袋不够灵活经验不够多,想不到可以解决的办法。
2. 新建一个evc工程,开始动手了!
首先我觉得是思路的问题,要怎么在一个图层上操作以实现画点,线及其它功能呢?师兄给的建议是:先打开一个地图,然后新建一个图层,再创建点数据集画点,最后创建线数据集画线。
思路清晰了,接下来就是实现了:
第一步: 在EVC 中生成一个WCE MFC AppWizard(Exe)单文档界面工程, 工程名任取, 在stdafx.h 中包含RSFC.h 头文件,该文件中所包含的头文件是对所有eSuperMap 类库的声明和根据编译的环境变量来确定所需的库。也可以根据需要来选择头文件。 如:#include "../SeRSFC/RSFC.h"
第二步:在App 类中加入成员变量CSePMF m_PMF,以便用于管理pmf 文件,对资源,地图数据的操作;类定义之后加入一句“extern CeSuperMapDeskproApp theApp;”这样可以在程序的其他地方调用theApp。
第三步:在视类中加入成员变量CSeMapWnd m_MapWnd,用于对打开的地图进行基本的操作,如放缩、漫游、旋转、刷新、全幅显示、选择对象、添加删除图层、设置图层的显示比例等等,所有一切与用户打交道的都必须涉及到它。
第四步:在视类中添加重载函数OnInitialUpdate(),在函数中添加上初始化代码 m_MapWnd.OnInitialUpdate( &theApp.m_PMF, this ),这样我们的视就跟管理文件的对象theApp.m_PMF 建立了关系。
第五步:在视类的OnDraw 函数中加入以下代码,以便能正确显示地图
CRect rcClient;
GetClientRect( &rcClient );
m_MapWnd.OnDraw( pDC, rcClient, rcClient );
第六步:将资源ID_FILE_OPEN 改为ID_MAP_OPEN,在视类中添加响应该菜单或工具条上相应按钮的函数OnMapOpen(),并添加相应的代码,其函数最后如下: CFileDialog dlgOpenFile ( true, _T("pmf"), NULL, OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,_T("PMF Files (*.pmf)|*.pmf") );
if( dlgOpenFile.DoModal() == IDOK )
{
if(theApp.m_PMF.IsOpen())
{
m_MapWnd.Close();
theApp.m_PMF.Close();
}
if( theApp.m_PMF.Open(dlgOpenFile.GetPathName()) )
{
CSeMapDef mapdef;
CSeMaps *pMaps = theApp.m_PMF.GetMaps();
CString strMapName = pMaps ->GetMapNameAt(0);
if(pMaps->GetMap(strMapName,mapdef))
{
if(m_MapWnd.OpenMap(mapdef))
{
m_MapWnd.Refresh();
return;
}
}
//如果没有默认地图,就算是图层也要打开一个
CSeDataSource *pDataSource = theApp.m_PMF.GetDefaultDataSource(); m_MapWnd.AddLayer(pDataSource->GetDatasetAt(0));
m_MapWnd.Refresh();
return ;
}
}
3. 在图层上画点和线
第一步:画点。
在菜单栏添加响应函数,点击时弹出对话框,用户输入一个地理坐标(坐标范围可以参照PMF Viewer中显示的地图及手持机屏幕大小来设定)。
将坐标传到一个自定义的CoursePoint结构体中,然后写入文件(其实大可以定义一个CArray的队列来存储,读取时遍历这个队列)。
接下来调用一个函数删除数据集和图层,以保证每次显示时只有一个图层: void CDrawCourseView::ClosePtLayer()
{
CSeDataSource *pDataSource = theApp.m_filePMF.GetDefaultDataSource();
pDataSource->DeleteDataset(_T("CoursePoint"));
m_MapWnd.RemoveLayer(_T("CoursePoint@DataSource"));
m_MapWnd.Refresh();
}
最后是关键了,显示添加的点。我是先读取文件获得添加的点的个数,然后创建点数据集和图层:
void CDrawCourseView::AddPointToLayer()
{
// TODO: Add your command handler code here
CSeDataSource *pDataSource = theApp.m_filePMF.GetDefaultDataSource();//得到默认的数据源
//创建前先删除数据集和图层
BOOL bDeletePointDataset = pDataSource->DeleteDataset(_T("CoursePoint")); BOOL bDeletePointLayer
m_MapWnd.RemoveLayer(_T("CoursePoint@DataSource"));
CSeDataset* pDataset0 = pDataSource->GetDatasetAt(0); //获取第一个数据集 CSeRect2D rcBounds = pDataset0->GetBounds();//得到数据集范围
//创建点数据集
m_pCoursePoints=
pDataSource->CreateDataset(_T("CoursePoint"),CSeDatasetInfo::Point,CSeDataset::HasStyle,rcBounds);
if(m_pCoursePoints!=NULL)
{
CSeLayer* pLayer = m_MapWnd.AddLayer(m_pCoursePoints,true);//添加到地图图层
//设置点的风格
long
nID=theApp.m_filePMF.GetResources()->m_SymbolLib.GetSymbolID(m_CosPtID);
pLayer->m_Style.m_nDimension=0;//设置风格的维数为0,即点
pLayer->m_Style.m_nSymbolStyle=nID;//设置符号类型 pLayer->m_Style.m_nSymbolSize=m_CosPtSize;//设置符号大小 pLayer->m_Style.m_nPenColor=m_CosPtClor;//设置颜色 =
}
}
接着在for循环里添加如下代码:
//地理坐标转换为地图坐标
CPoint point; point.x=(long)floor(Point.x*10000); point.y=(long)floor(Point.y*10000); //设置点的位置 CSeGeoPoint sePoint; sePoint.SetPoint(point.x,point.y); //将点加入记录集 CSeRecordset* pRecd=NULL;//记录集初始化为空 CSeDatasetVector* pCourseLines;//创建一个向量集用于查询
pCourseLines=(CSeDatasetVector*)
(m_MapWnd.GetLayer(_T("CoursePoint@DataSource")))->GetDataset();//查询图层数据集
if (pCourseLines)
pRecd=pCourseLines->QueryWithGeneral(_T(""));//一般查询,返回满足条件的几何对象的记录集
if (pRecd) { if (pRecd->AddNew(&sePoint)>=0) { se_VARIANT variant; variant.vt=VT_I4; variant.lVal=i+1;//点标识加1 CSeVariant varValue=CSeVariant(variant); pRecd->SetFieldValue(_T("SMUSERID"),varValue); pRecd->Update(); } pCourseLines->ReleaseRecordset( pRecd );//释放记录集
}
最后刷新地图,就可以成功显示点了。
第二步:画线。
首先对话框添加点的时候将坐标另存为一个队列
CArray<CSePoint2D ,CSePoint2D >arrPnts;
//转为地图坐标用于连线
CSePoint2D pt;
pt.x = (long)floor(point.x*10000);
pt.y = (long)floor(point.y*10000);
arrPnts.Add(pt);
接着删除线数据集和图层,创建线数据集和线图层,显示各点连成的线。
显示线的代码如下:
for (int i=0;i<arrPnts.GetSize();i++)
{
CSeRecordset* pRecordset=NULL;//记录集初始化为空 CSeDatasetVector* pDV;//创建一个向量集用于查询 pDV=(CSeDatasetVector*) (m_MapWnd.GetLayer(_T("Course@DataSource")))->GetDataset();//查询图层数据集
if (pDV)
pRecordset=pDV->QueryWithGeneral(_T(""));//一般查询,返回满足条件的几何对象的记录集
if (pRecordset) {
//设置航线 CSeGeoLine *pGeoLine = new CSeGeoLine; pGeoLine->Make(arrPnts.GetData(),(arrPnts.GetSize())); pRecordset->AddNew( pGeoLine ); pRecordset->Update(); delete pGeoLine;
pGeoLine = NULL; } pDV->ReleaseRecordset( pRecordset );//释放记录集
}
m_MapWnd.Refresh();//更新地图
第三步:添加地图放大,缩小,平移,显示跟踪点的功能
首先重载鼠标左键Down和Up函数,然后在菜单栏添加各个功能的响应函数。要注意的问题是显示跟踪点时也要用到OnLButtonDown()函数,所以要定义两个宏来避免功能之间的冲突。我是这样实现的:
#define QUERY_MODE_NONE 0
#define QUERY_TRAKING 1
//添加一个整型变量,记下当前的查询模式
long m_nQueryMode;
//设置用户动作状态为放大状态
m_MapWnd.SetAction( CSeDrawParameters::uaZoomIn );
m_nQueryMode = QUERY_MODE_NONE;
//设置用户动作状态为缩小状态
m_MapWnd.SetAction( CSeDrawParameters::uaZoomOut );
m_nQueryMode = QUERY_MODE_NONE;
//设置用户动作状态为平移状态
m_MapWnd.SetAction( CSeDrawParameters::uaPan );
m_nQueryMode = QUERY_MODE_NONE;
m_nQueryMode = QUERY_TRAKING;
m_MapWnd.SetAction( CSeDrawParameters::uaNull );
工作总结是集体或个人对一个时期内的工作情况进行的回顾或评价。通常说的工作总结,一般是指机关、企业、事业等单位的集体工作总结,不包括…
工作总结是集体或个人对一个时期内的工作情况进行的回顾或评价。通常说的工作总结,一般是指机关、企业、事业等单位的集体工作总结,不包括…
工作总结的作用与分类http://www.job1688.com/[加入收藏]工作总结是对过去某一时期或某项工作的情况(包括成绩、…
工作总结的作用与写法工作总结是集体或个人对一个时期内的工作情况进行的回顾或评价。通常说的工作总结,一般是指机关、企业、事业等单位的…
工作总结的4大作用1、推动工作前进工作总结既是对过去一个阶段工作的回顾与总结,也是总结成绩,认识缺点,吸取教训,提升认识与能力的过…
我们这次的活动主题为“传播健康文化知识,共享精彩人生”从主题透出的含义我们就可看出这次活动的目的。主要就是宣传健康的生活习惯,帮助…
经过两个星期的努力,终于完成了注射成型模具的设计。在上课的时候,老师大概和我们讲了一下模具设计的情况,刚开始对模具设计还一无所知。…
同志们:两天的培训就要结束了。这次培训是公司组建以来组织的第一次办公室综合性系统培训活动。这次培训可以说既是业务培训会,又是鼓舞士…
根据各部门经理的培训感想,汇总整理如下:一、部门经理的八大责任和使命:1.保证部门工作的正常运行2.企业工作计划的具体落实和实现3…
红根小学假期教师读书活动总结假期生活已经结束,老师们除了完成假期的学习任务外,都在积极参加教育局开展的教师读书活动,并且都根据学校…
1.概述函,即信函,或称书信。公函,即处理公务所用的书信。公函是党政机关、人民团体、企事业单位间商洽和联系工作时使用的一种文体。公…