现在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图层,并且使图例也跟着同步刷新。来试一下吧。