MapGuide开发中使用Fusion Viewer及通过程序开关图层
现在MapGuide的开发已经逐渐进入了Fusion时代。 Fusion viewer(灵活网页布局Flexible Weblayout)是基于OpenLayers技术的,界面比传统的Ajax Viewer(基本网页布局 Basic Weblayout)更灵活,它基于HTML Div标签+CSS技术,因而可以有更丰富的界面表现力。MapGuide Fusion Viewer提供了丰富的内置功能,每个功能都有widget来提供。和Ajax Viewer一样,你也可以加入你自己的自定义功能,这篇文章介绍一下如果使用Fusion viewer以及在Fusion viewer中如何实现常见的功能--编程来开关图层。
首先看一下如何使用Fusion viewer。 MapGuide提供了5个Fusion模版,这些模版可以到C:\Program Files\Autodesk\Autodesk Infrastructure Web Server Extension 2012\www\fusion\templates\mapguide下面找到,你可以按照其中的模版来构造你自己的首页,也可以通过<iframe>把某个模版嵌入到你的首页里。但这里我们来介绍一种简单的办法,直接通过redirect方法来打开fusion模版。如果你还不了解MapGuide使用Ajax Viewer的开发,你可以看一下以前的文章,比如:
http://www.cnblogs.com/junqilian/category/207017.html
MapGuide应用开发系列(11)----创建自己的第一个MapGuide应用程序
Autodesk MapGuide Enterprise 2012开发技术入门培训视频录像下载
Visual studio里新建见一个asp.net页面,后台代码如下:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using OSGeo.MapGuide; public partial class FusionIndex : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string webLayout = @"Library://Exercise/Layouts/Flex.ApplicationDefinition"; UtilityClass util = new UtilityClass(); util.InitializeWebTier(Request); util.ConnectToServer(); MgSite site = util.GetSiteConnection().GetSite(); string sessionId = site.CreateSession(); Session["MySession"] = sessionId; Response.Redirect("http://localhost/mapserver2012/fusion/templates/mapguide/aqua/index.html?ApplicationDefinition=" + webLayout + "&session=" + sessionId); } }
Utility 类中上面用户的方法如下:
// initialize the web tier public void InitializeWebTier(HttpRequest Request) { string realPath = Request.ServerVariables["APPL_PHYSICAL_PATH"]; String configPath = realPath + "webconfig.ini"; MapGuideApi.MgInitializeWebTier(configPath); } // connect to server public void ConnectToServer(String sessionID) { MgUserInformation userInfo = new MgUserInformation(sessionID); siteConnection = new MgSiteConnection(); siteConnection.Open(userInfo); } public void ConnectToServer() { MgUserInformation userInfo = new MgUserInformation("Administrator", "admin"); siteConnection = new MgSiteConnection(); siteConnection.Open(userInfo); }
通过这样简单的代码就可以启动Fusion.
下面要扩展Fusion的功能,我们需要添加一个切换图层可见性的功能,这个功能可以添加到工具条、右键菜单、任务栏或者你想要添加的其他适当位置,下面以添加到地图右键菜单为例。点击下图中间的New… 按钮新建一个“Invoke URL”的component,指向一个自定义页面ToggleLayer.aspx,然后把这个命令添加到左边的地图右键菜单里。
下面在我们的web 工程里添加一个页面—toggleLayer.aspx. 我们将在这个页面的后台代码中调用MapGuide WebExtension API来控制某个图层的可见性。 为了让通过后台代码做的更改能够体现在浏览器里面,我们需要对地图进行刷新,包括对图层Legend窗口进行刷新。于是在这个页面的body onload事件中调用Fusion Viewer API进行地图刷新。对图例进行刷新最直观的方法就是找到这个图例widget,然后调用他的update()方法。可是貌似不起作用。于是我们通过调用地图widget的reloadMap()方法来实现。
这个页面同样也适用于与basic weblayout,在Basic weblayout中浏览器API来刷新的方法是parent.parent.Refresh(),假设我们是把这个页面放到了task pane里面的。
详细代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ToggleLayer.aspx.cs" Inherits="ToggleLayer" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript"> var isFusion = true; function RefreshMap() { if (isFusion) { Fusion = window.top.Fusion; // does not work //var legend = Fusion.getWidgetById("Legend"); // legend.renderer.update(); //reload the Map to refresh legend Fusion.getWidgetById('Map').reloadMap(); } else { // for basic web layout, // if using basic weblayout, referenceing to MapGuideViewerApi.js should be removed parent.parent.Refresh(); } } </script> </head> <body onload="javascript:RefreshMap()"> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
下面来实现后台代码,为了使页面能反复执行来实现图层可见性的切换,我们需要清除cache,否则由于缓存机制造成后台.net代码不在执行而达不到我们的效果,所以必须用Response.CacheControl = "no-cache"指定不缓存。 还有一点需要注意是,在Fusion中的MapName不能在像Basic Weblayout中那样硬编码的方式指定,因为Fusion viewer为了防止地图重名为原有地图名后加了一个随机字符串,我们需要通过mapName = Request["MapName"].ToString(); 的方式来获得真正的地图名。
下面是完整代码:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using OSGeo.MapGuide; public partial class ToggleLayer : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // *IMPORTANT*, clear the cache Response.CacheControl = "no-cache"; string sessionId = Request["Session"].ToString(); string mapName = Request["MapName"].ToString(); try { UtilityClass utility = new UtilityClass(); utility.InitializeWebTier(Request); utility.ConnectToServer(sessionId); MgSiteConnection siteConnection = utility.GetSiteConnection(); if (siteConnection == null) { Response.Write("fail to get site connection, exit"); return; } MgResourceService resService = (MgResourceService)siteConnection.CreateService(MgServiceType.ResourceService); MgLayerBase tmpLayer = null; //Please type in the code between the comments MgMap map = new MgMap(); map.Open(resService, mapName); tmpLayer = utility.getLayerByName(map, "Districts"); tmpLayer.SetVisible(!tmpLayer.IsVisible()); tmpLayer.ForceRefresh(); map.Save(resService); //////////////////////////////////////////////////// if (tmpLayer.IsVisible()) Response.Write("<p><b> the Districts layer is turned on </b></p>"); else Response.Write("<p><b> the Districts layer is turned off </b></p>"); } catch (MgException ex) { Response.Write(ex.Message); Response.Write(ex.GetDetails()); } } }
好了,下面运行我们的web 应用程序, 你应该能够开关districts图层,并且使图例也跟着同步刷新。来试一下吧。