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,然后把这个命令添加到左边的地图右键菜单里。

image

 

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


Related Posts Plugin for WordPress, Blogger...