“Sharing Position with Friends” in MGE based Web GIS Application

What will you do when you want to tell your friends where your favorite restaurant is? Tell them the address? Yes, good, but how about to point it out on map? In this topic, we will discuss how to implement sharing position functionality in MapGuide based Web GIS application, which is supposed to run as public service, just like Google Maps or Bing Maps.

Firstly we find the restaurant on the map, and generate the link of current view, the link can be send to friends by email or IM tools, and of cause we can also embed the map into any page. Secondly, when we receive such a link and open it in browser, it should zoom to the specified view port automatically.

I prefer to use Fusion viewer in this topic. Fusion is a web mapping application development framework. It allows web designers and developers to build rich mapping applications quickly and easily. Using "widgets" that provide the interface functionality within Fusion's modular architecture; developers are able to add, remove, or modify functionality using standard-compliant HTML and CSS. We need to create webpage and edit the flexible web layout in MapGuide Studio to add it to Task Pane:

MapGuide Fusion Viewer provides many widgets, which implemented using JavaScript. We can get the center of map and current scale by Fusion Viewer API, and then pass these parameters to home page of MapGuide web application.

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Send to friends</title>

<script language="javascript" type="text/javascript">

// <!CDATA[

var mapWidgetId = 'Map';

var serverUrl = "http://ServerName/SharePosition/default.aspx";

function Generate_onclick() {

var Fusion = window.top.Fusion;

var mapWidget = Fusion.getWidgetById(mapWidgetId);

 

//Get the parameters of current view

var centerX = mapWidget.getCurrentCenter().x;

var centerY = mapWidget.getCurrentCenter().y;

var scale = mapWidget.getScale()

 

//Generate the URL

var gotoUrl = serverUrl + "?x=" + centerX + "&y=" + centerY + "&scale=" + scale;

 

document.getElementById("url").innerHTML = gotoUrl;

}

// ]]>

</script>

</head>

<body>

<form id="form1" runat="server">

<div>

<input id="Generate" type="button" value="Generate Current View URL" onclick="return Generate_onclick()" /><br />

<div id="url"></div>

</div>

</form>

</body>

</html>

 

Now, let's make the home page. To avoid MapGuide authentication login dialogue, we create a MapGuide connection and generate the session string, then pass it to the viewer path.

In the web application home page, we will try to get view port parameters from the URL. If such parameters are attached in URL, it maybe a URL received from friends, the map should jump the specified view port; otherwise map should load the initial view port.

protected void Page_Load(object sender, EventArgs e)

{

// default flexible weblayout

string webLayout = @"Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition";

string viewerPathSchema = @"http://ServerName/mapguide2010/fusion/templates/mapguide/slate/index.html?ApplicationDefinition={1}&SESSION={0}";

 

string defaultUser = "Administrator";

string defaultPassword = "admin";

 

Utility utility = new Utility();

utility.InitializeWebTier(Request);

 

MgUserInformation userInfo = new MgUserInformation(defaultUser, defaultPassword);

MgSiteConnection siteConnection = new MgSiteConnection();

siteConnection.Open(userInfo);

MgSite site = siteConnection.GetSite();

string sessionId = site.CreateSession();

 

//store in session for further use

Session["sessionId"] = sessionId;

 

if (Request["X"] != null && Request["Y"] != null && Request["scale"] != null)

{

string centerX = Request["X"].ToString();

string centerY = Request["Y"].ToString();

string scale = Request["scale"].ToString();

 

//Generate the new weblayout resource identifier

webLayout = utility.ChangeInitialViewInWebLayout(webLayout, sessionId, centerX, centerY, scale);

}

 

string viewerPath = string.Format(viewerPathSchema, sessionId, Server.UrlEncode(webLayout));

Response.Redirect(viewerPath);

}

 

Now, we will discuss how to make the map jump to specified view port when it is loaded. In Autodesk MapGuide Studio, we can edit the flexible web layout using web layout editor. The default setting for "Initial view of map" is "use map's initial view"; it also can be specified value as below:

The application definition xml would be changed as below when it is saved, you can get the xml by Maestro conveniently, please pay attention to the <InitialView> section marked as bold.

<MapGroup id="Sheboygan">

<InitialView>

<CenterX>-87.730254250934</CenterX>

<CenterY>43.744459064634</CenterY>

<Scale>22324609.319122165</Scale>

</InitialView>

<Map>

</Map>

<Extension />

</MapGroup>

OK, as we have known the mechanism, let's implement it in code. We will add the <InitialView> section for the web layout. But there is another thing we need to care about, we are not going to change the web layout stored in library repository, because it will affect all the users. In order not to confuse other users, we need to create a temporary web layout based the current session. Code goes as below:

public string ChangeInitialViewInWebLayout(string webLayoutTemplate, string sessionId, string centerX, string centerY, string scale)

{

if (siteConnection == null)

{

MgUserInformation userInfo = new MgUserInformation(sessionId);

siteConnection = new MgSiteConnection();

siteConnection.Open(userInfo);

}

 

MgResourceIdentifier layoutResId = new MgResourceIdentifier(webLayoutTemplate);

MgResourceService resSvc = siteConnection.CreateService(MgServiceType.ResourceService) as MgResourceService;

MgByteReader reader = resSvc.GetResourceContent(layoutResId);

 

System.IO.MemoryStream ms = new System.IO.MemoryStream();

byte[] buf = new byte[8 * 1024];

int read = 1;

while (read != 0)

{

read = reader.Read(buf, buf.Length);

ms.Write(buf, 0, read);

}

 

string layoutXml = GetStringFromMemoryStream(ms);

 

XmlDocument doc = new XmlDocument();

 

doc.LoadXml(layoutXml);

 

// if using custom view in web layout defintion, change the custom view port

if (doc.GetElementsByTagName("InitialView").Count > 0)

{

XmlNode nodeCenterX = doc.GetElementsByTagName("CenterX").Item(0);

nodeCenterX.InnerText = centerX;

XmlNode nodeCenterY = doc.GetElementsByTagName("CenterY").Item(0);

nodeCenterY.InnerText = centerY;

XmlNode scaleNode = doc.GetElementsByTagName("Scale").Item(0);

scaleNode.InnerText = scale;

}

else // using the map's initial view, we need to add a custom view port ourselves.

{

//Add <InitialView> tag for the web layout(application definition)

XmlNode initialViewNode = doc.CreateNode(XmlNodeType.Element, "InitialView", null);

XmlNode centerXNode = doc.CreateElement("CenterX");

centerXNode.InnerText = centerX;

XmlNode centerYNode = doc.CreateElement("CenterY");

centerYNode.InnerText = centerY;

XmlNode scaleNode = doc.CreateElement("Scale");

scaleNode.InnerText = scale;

 

initialViewNode.AppendChild(centerXNode);

initialViewNode.AppendChild(centerYNode);

initialViewNode.AppendChild(scaleNode);

 

//insert before the <Map> tag

doc.GetElementsByTagName("MapGroup")[0].InsertBefore(initialViewNode, doc.GetElementsByTagName("Map")[0]);

}

 

MgByteSource byteSource = ByteSourceFromXMLDoc(doc);

string sessionLayoutName = layoutResId.GetName();

string sessionLayout = "Session:" + sessionId + @"//" + sessionLayoutName + ".ApplicationDefinition";

MgResourceIdentifier sessionLayoutResId = new MgResourceIdentifier(sessionLayout);

 

resSvc.SetResource(sessionLayoutResId, byteSource.GetReader(), null);

 

return sessionLayout;

 

}

Here is the test result, zoom you map to something you are interested in and want to share, press the "Generate Current View URL", an URL like http://serverName/SharePosition/default.aspx?x=-87.699801035788&y=43.751721697876&scale=3200.000005286838 will be generated. You can copy the follow URL
and send it to friends by mail or IM tools. When they open the URL, the map will jump to the same view port as yours. Enjoy!J

 

You are also welcome to discuss MapGuide related issue at http://www.newmgdn.com .

 

Source code download here:

 

SharePosition.zip 7KB 0 2010/4/2 16:39:56 Download

 


Related Posts Plugin for WordPress, Blogger...