基于MapXtreme的鹰眼功能
平台:Microsoft .Net Framework 1.1 (ASP.Net 1.1)
GIS组件:MapInfo MapXTreme 2004
语言:C#
要实现鹰眼功能有两个主要问题:用户在鹰眼窗口上点击的时候地图自动定位到相应的位置;当地图视图(包括缩放比例和中心)发生变化的时候,鹰眼窗口上的导航矩形框相应变化以指示用户当前所处的位置。
第一个问题可以通过客户端捕获用户在鹰眼窗口上点击的位置,发送到服务器,服务器端把该位置转换为地图坐标并更新地图的中心点来实现。为了便于保持地图或者页面上其它Web Control的状态,这个回发应该用HTTP POST来实现。
第二个问题复杂一些,需要在地图的视图改变的时候根据地图当前的边距生成一个矩形框,然后把这个矩形框放到一个临时图层里面并添加到鹰眼窗口上。因为地图视图改变事件难以捕获,可以在MapControl的PreRender事件里来实现这个功能,这样在每次页面生成的时候都生成一次导航矩形框。
首先在.aspx文件上添加两个MapInfo.Web.UI.WebControls.MapControl。一个叫mcEagle,小一些做为鹰眼窗口。一个叫mcMain,用来显示主地图。
<MapInfoWebUIWebControls:MapControl id="mcEagle" style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px" runat="server"
WorkspaceFileName="WebForm1mcEagle.mws" Height="150px" Width="200px" BorderStyle="Solid" BorderWidth="1px" MapAlias="Map11"
UseDesigntimeWorkspace="True" Format="Gif"></MapInfoWebUIWebControls:MapControl>
<mapinfowebuiwebcontrols:MapControl id="mcMain" style="Z-INDEX: 102; LEFT: 8px; POSITION: absolute; TOP: 168px" runat="server"
WorkspaceFileName="WebForm1mcMain.mws" Height="600px" Width="800px" BorderStyle="Solid" BorderWidth="1px" MapAlias="Map12"
DisplayCoordSys="经度/纬度" UseDesigntimeWorkspace="True" Format="Gif" Zoom="3000"></mapinfowebuiwebcontrols:MapControl>
再放置一个隐藏的input来保存用户点击鹰眼窗口的位置:
<INPUT id="iPoint" type="hidden" runat="server" NAME="iPoint">
在页面的Page_Load事件里写以下代码:
mcEagle.Attributes.Add("onclick","Form1.iPoint.value=event.offsetX + '|' + event.offsetY;Form1.submit()");
if(iPoint.Value != "")
{
string []point;
int screenX = -1;
int screenY = -1;
point = iPoint.Value.Split('|');
try
{
screenX = Convert.ToInt32(point[0]);
screenY = Convert.ToInt32(point[1]);
}
catch(Exception)
{
}
if ( screenX >= 0 && screenY >= 0 )
{
System.Drawing.Point pntClick = new System.Drawing.Point(screenX,screenY);
DPoint pntCenter = new DPoint(0,0);
mcEagle.Map.DisplayTransform.FromDisplay(pntClick, out pntCenter);
mcMain.Map.Center = pntCenter;
}
iPoint.Value = "";
}
为mcMain的PreRender事件添加事件处理方法
private void mcMain_PreRender(object sender, System.EventArgs e)
{
if(mcMain.Map.Layers.Count == 0) return;
//创建样式
MapInfo.Geometry.Rectangle rectangle = new MapInfo.Geometry.Rectangle(mcEagle.Map.GetDisplayCoordSys(),mcMain.Map.Bounds);
MapInfo.Styles.AreaStyle aStyle = new AreaStyle();
aStyle.Border = StockStyles.RedLineStyle();
aStyle.Interior = new SimpleInterior(0);
CompositeStyle cStyle = new MapInfo.Styles.CompositeStyle(aStyle);
//创建内存临时表
TableInfoMemTable tableInfo = new TableInfoMemTable("EagleEyeTemp");
tableInfo.Temporary = true;
Column column;
column = new GeometryColumn(mcEagle.Map.GetDisplayCoordSys());
column.Alias = "MI_Geometry";
column.DataType = MIDbType.FeatureGeometry;
tableInfo.Columns.Add(column);
column = new Column();
column.Alias = "MI_Style";
column.DataType = MIDbType.Style;
tableInfo.Columns.Add(column);
MapInfo.Data.Table map_table;
MIConnection conn = new MIConnection();
conn.Open();
MICommand cmd = conn.CreateCommand();
if(MapInfo.Engine.Session.Current.Catalog["EagleEyeTemp"] == null)
{
map_table = MapInfo.Engine.Session.Current.Catalog.CreateTable(tableInfo);
cmd.Parameters.Add("geometry",MIDbType.FeatureGeometry);
cmd.Parameters.Add("style",MIDbType.Style);
cmd.CommandText = "Insert Into EagleEyeTemp (MI_Geometry,MI_Style) values (geometry,style)";
cmd.Prepare();
cmd.Parameters[0].Value = rectangle;
cmd.Parameters[1].Value = cStyle;
int nchanged = cmd.ExecuteNonQuery();
}
else
{
map_table = MapInfo.Engine.Session.Current.Catalog["EagleEyeTemp"];
cmd.Parameters.Add("geometry",MIDbType.FeatureGeometry);
cmd.CommandText = "Update EagleEyeTemp Set MI_Geometry = geometry";
cmd.Prepare();
cmd.Parameters[0].Value = rectangle;
int nchanged = cmd.ExecuteNonQuery();
}
//创建临时图层
MapInfo.Mapping.FeatureLayer temp_layer = new FeatureLayer(map_table,"EagleEyeTemp");
for(int i = 0;i < mcEagle.Map.Layers.Count;i++)
{
if(mcEagle.Map.Layers[i].Alias == "EagleEyeTemp")
{
mcEagle.Map.Layers.Remove("EagleEyeTemp");
break;
}
}
mcEagle.Map.Layers.Add(temp_layer);
}