📄 mapobjects开发技术 (vc++).htm
字号:
Variable”对话框,在成员变量名称栏输入“m_map”,下面两栏保持不变,即Category为Control,Variable
Type为CMoMap。做完这些工作后,回到ClassView中观察CMmapView类,将发现增加了一个类型为CMoMap的m_map对象,利用它就可以操作地图了。
<BR><BR>2.3
使用Map对象增加图层<BR>这时编译程序,应该不会出错,但在运行时,发现除了在表单视图中增加了一个空白的代表地图控件的小图标外,应用程序与刚生成时的情况并没有什么太大的区别。为了增加图层数据,首先要把地图控件的尺寸放大到与表单视图一样大,然后把图层数据加入到地图对象中。
<BR><BR>第一步、找到CMmapView的OnInitialUpdate()方法,作如下操作:<BR>(1)如果原来有“ResizeParentToFit();”语句,注释掉或删除它;<BR>(2)在返回语句之前增加如下语句:<BR><BR>//
将显示尺寸调整到整个客户区<BR>CRect
client;<BR>GetClientRect(&client);<BR>int
cx=client.Width();<BR>int
cy=client.Height();<BR>m_map.SetWindowPos(0, 0, 0, cx, cy,
SWP_NOZORDER);
<BR><BR>第二步、找到CChildFrame,重载其OnClientCreate()方法,该方法将在创建表单客户区时被调用,在其返回语句之前增加语句:“MDIMaximine();”。
<BR><BR>完成上面两步后,再次编译程序并运行,在原来表单客户区应该出现一个空白的地图,接下来往这个空白图上增加图层。为了简单起见,我们假设图层数据放在C:\data目录下,图层格式为Shape文件,其文件名为test.shp。
<BR><BR>第三步、在CMmapView中创建一个增加shape文件的方法AddShpLayer(),其实现为:<BR>增加SHP图层,返回图层内部名称,为空表示不成功。<BR>CString
CMmapView::AddShpLayer(const CString & path, COLORREF
color, short symbolSize, short
symbolStyle)<BR>{<BR><BR>CMoDataConnection conn;<BR>if
(!conn.CreateDispatch(TEXT("MapObjects2.DataConnection")))
return "";<BR>conn.SetDatabase(GetFileDirectory(path));<BR>if
(!conn.Connect()) return ""; <BR><BR>// Add layer specified by
path<BR>CMoLayers layers=m_map.GetLayers();<BR>CMoMapLayer
layer;<BR>if
(!layer.CreateDispatch(TEXT("MapObjects2.MapLayer"))) return
"";<BR><BR>CString LayerName =
GetFileTitle(path);<BR>CMoGeoDataset
geoDataset=conn.FindGeoDataset(LayerName);<BR>if(!geoDataset)
return "";
<BR><BR>layer.SetGeoDataset(geoDataset);<BR>CMoSymbol
layerSymbol(layer.GetSymbol()); <BR><BR>if (color != -1)
layerSymbol.SetColor(color); // Set color if
specified<BR><BR>layerSymbol.SetSize(symbolSize);<BR>layerSymbol.SetStyle(symbolStyle);<BR>layers.Add(layer);<BR>return(layer.GetName());<BR><BR>}
<BR><BR>为了使这段代码能够被顺利编译,还要在mmapview.cpp的文件开始处增加如下include语句:<BR>#include
"modataconnection.h"<BR>#include "molayers.h"<BR>#include
"momaplayer.h"<BR>#include "mogeodataset.h"<BR>#include
"mosymbol.h"
<BR><BR>另外,在CMmapView中增加几个辅助函数,用于分析图层文件路径中的文件名、目录名:<BR>CString
CMmapView::GetFileDirectory(const CString&
path)<BR>{<BR><BR>int pos = path.ReverseFind('\\');<BR>if (pos
>= 0) return path.Left(pos);<BR>return "";<BR><BR>}
<BR><BR>CString CMmapView::GetFileTitle(const CString&
path)<BR>{<BR><BR>CString strResult =
GetFileName(path);<BR>int pos =
strResult.ReverseFind('.');<BR>if (pos >= 0) return
strResult.Left(pos);<BR>return strResult;<BR><BR>}
<BR><BR>CString CMmapView::GetFileName(const CString&
path)<BR>{<BR><BR>int pos = path.ReverseFind('\\');<BR>if (pos
>= 0) return path.Right(path.GetLength() - pos -
1);<BR>return path;<BR><BR>}
<BR><BR>第四步,回到CMmapView的OnInitialUpdate(),在其返回之前加上如下语句:<BR>AddShpLayer("c:\\data\\test.shp",
RGB(125,125,125), 0, 0);
<BR><BR>再次编译后运行(运行前确保C:\data\test.shp图层文件存在,即至少包括c:\data\test.dbf、c:\data\test.shp、c:\data\test.shx三个文件),应该能够观察到test图层被加入到了地图中。
<BR><BR>2.4
使用map对象操作地图<BR>接下来我们完成对地图的放大缩小操作,当点击鼠标左键时,地图放大1倍,当点击鼠标左键时,地图回到全图显示。
<BR><BR>第一步,使用类向导(Class
Wizzard)在CMmapView中增加一个地图消息响应函数。即选中CMmapView中的IDC_MAP1,在Message列表框中双击MouseDown,将生成一个<BR>OnMouseDownMap1()消息函数。
<BR><BR>第二步,在OnMouseDownMap1()中加入如下语句:<BR>if(Button==1)<BR>{<BR><BR>CMoRectangle
rect=m_map.GetExtent();<BR>rect.ScaleRectangle(0.5);<BR>m_map.SetExtent(rect);<BR><BR>}<BR>else
if(Button==2)<BR>{<BR><BR>CMoRectangle
rect=m_map.GetFullExtent();<BR>m_map.SetExtent(rect);<BR><BR>}
<BR><BR>为了使用CMoRectangle,还需要在mmapview.cpp的开始部分加一个include语句,即:<BR>#include
"morectangle.h"
<BR><BR>按下鼠标左键时,在消息响应函数中的Button参数记录按下的是哪个键,1表示左键,2表示右键。编译后运行,分别点击鼠标左右键,应该观察到地图放大和缩回到全图的效果。
<BR><BR>2.5
使用Recordset对象检索数据<BR>接下来我们想找到图层中的第一个要素,即其FeatureId为1(在MapObjects要素图层中,FeatureId是其固有的字段,用于记录每个要素在图层中的序号),找到这个要素后,把它放在视图窗口的中央显示,这就类似于一个条件定位的功能。
<BR><BR>第一步,在IDR_MMAPTYPE菜单中增加一个“定位”菜单项至“查看”菜单下,设其ID号为ID_FEATURE_LOCATE。
<BR><BR>第二步,使用类向导(Class
Wizzard)产生该菜单项在CMmapView中的消息响应函数,即与COMMAND和UPDATA_COMMAND_UI两个消息对应的OnFeatureLocate()和OnUpdateFeatureLocate(),在OnUpdateFeatureLocate()的实现中增加下行语句,使该菜单总是处于激活状态:<BR>pCmdUI->Enable();
<BR><BR>第三步,在OnFeatureLocate()中增加如下语句:<BR><BR> <BR><BR>void
CMmapView::OnFeatureLocate() <BR>{ <BR>CMoLayers
layers=m_map.GetLayers(); <BR>CMoMapLayer
layer=layers.Item(COleVariant(TEXT("test"))); <BR>if(layer)
<BR>{ <BR>CMoRecordset
recs=layer.SearchExpression(_T("FeatureId = 1"));
<BR>recs.MoveFirst(); <BR>if(!recs.GetEof())
<BR>{<BR><BR>CMoFields fields=recs.GetFields(); <BR>CMoField
shapeField=fields.Item(COleVariant(TEXT("Shape")));
<BR><BR>if(shapeField) <BR>{ <BR>switch(shapeField.GetType())
<BR>{ <BR>case 21: <BR>{ <BR>CMoPoint
point=shapeField.GetValue().pdispVal; <BR>if(point)
m_map.CenterAt(point.GetX(), point.GetY()); <BR>} <BR>break;
<BR>case 22: <BR>{ <BR>CMoLine
line=shapeField.GetValue().pdispVal; <BR>if(line) <BR>{
<BR>CMoRectangle rect=line.GetExtent();
<BR>rect.ScaleRectangle(1.5); <BR>m_map.SetExtent(rect); <BR>}
<BR>} <BR>break; <BR>case 23: <BR>{ <BR>CMoPolygon
polygon=shapeField.GetValue().pdispVal; <BR>if(polygon) <BR>{
<BR>CMoRectangle rect=polygon.GetExtent();
<BR>rect.ScaleRectangle(1.5); <BR>m_map.SetExtent(rect); <BR>}
<BR><BR>} <BR>break; <BR>} <BR>} <BR>} <BR>} <BR>}
<BR><BR>在这里使用到了记录集、字段、点、线、面等对象,因此在文件头部还要增加如下include文件:<BR>#include
"morecordset.h"<BR>#include "mofields.h"<BR>#include
"mofield.h"<BR>#include "mopoint.h"<BR>#include
"moline.h"<BR>#include "mopolygon.h"
<BR><BR>在switch/case语句中的21表示要素的几何类型为点,22表示线,23表示面。编译后运行,并选择“定位”菜单,程序将找到test图层中的第一个要素,并把它放在窗口的中央显示出来。如果加入的图层数据是点层,我们建议把其symbolSize设为10,以便观察到点位。即把OnInitialUpdate()中的AddShpLayer方法调用换作:<BR>AddShpLayer("c:\\data\test.shp",
RGB(255,0,0), 10, 0);
<BR><BR>从这个例子中我们看到了如何通过图层(Layer)执行一个SQL查询语句,获得记录集后如何对其进行检索,并提取出具体字段内容。对于图形图层,“Shape”字段也是固定存在的,其中存放了该要素的图形几何部分,通过使用字段的GetType()方法可以获得该图层是点层、线层或面层,并作出相应的定位处理。字段的GetValue()方法返回的是一个VARIANT类型值,其中封装了各种各样的数据类型,在Shape字段中,它封装的是一个图形要素,可以通过pdispVal取得它的真正内容,并根据图层类型转换为相应的图形要素,作为计算地图显示范围的依据。
</SPAN></P></TD></TR>
<TR>
<TD
style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px"
height=4> </TD></TR>
<TR>
<TD
style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px"
height=4>
<DIV align=left>(作者联系方式: )</DIV></TD></TR>
<TR>
<TD
style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px"
height=4>
<DIV align=left><A href="http://www.gissky.net/bbs/"
target=_blank><FONT
color=#ff0000>欢迎进入GIS论坛讨论区进行相关讨论,论坛社区欢迎您的到来...</FONT></A></DIV></TD></TR></TBODY></TABLE></TD>
<TD class=mframe-m-right height=145></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=1 width="100%" border=0>
<TBODY>
<TR>
<TD height=4></TD></TR>
<TR>
<TD height=2></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD class=mframe-b-left height=2></TD>
<TD class=mframe-b-mid height=2> </TD>
<TD class=mframe-b-right
height=2></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=777 align=center border=0>
<TBODY>
<TR>
<TD align=left height=2> </TD></TR>
<TBODY></TBODY></TABLE>
<TABLE class=twidth cellSpacing=0 cellPadding=0 align=center>
<TBODY>
<TR style="LINE-HEIGHT: 130%" align=middle height=60>
<TD height=2>
<DIV align=center>
<P><BR>GIS空间站|地理信息系统空间站 版权所有:王华斌<BR><FONT
face="Arial, Helvetica, sans-serif">Copyright © 2001 - 2005<B> GISSky<FONT
color=#cc0000>.Net</FONT></B></FONT>(引用本站资料,请注明站名和网址)
<BR></P></DIV></TD></TR></TBODY></TABLE></DIV></TD></CENTER></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -