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">
<title>Send to friends</title>
<script language="javascript" type="text/javascript">
var serverUrl = "http://ServerName/SharePosition/default.aspx";
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()
var gotoUrl = serverUrl + "?x=" + centerX + "&y=" + centerY + "&scale=" + scale;
document.getElementById("url").innerHTML = gotoUrl;
<form id="form1" runat="server">
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)
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.
<CenterX>-87.730254250934</CenterX>
<CenterY>43.744459064634</CenterY>
<Scale>22324609.319122165</Scale>
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:
MgUserInformation userInfo = new MgUserInformation(sessionId);
siteConnection = new MgSiteConnection();
siteConnection.Open(userInfo);
MgResourceIdentifier layoutResId = new MgResourceIdentifier(webLayoutTemplate);
MgByteReader reader = resSvc.GetResourceContent(layoutResId);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] buf = new byte[8 * 1024];
read = reader.Read(buf, buf.Length);
string layoutXml = GetStringFromMemoryStream(ms);
XmlDocument doc = new XmlDocument();
// 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);
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");
initialViewNode.AppendChild(centerXNode);
initialViewNode.AppendChild(centerYNode);
initialViewNode.AppendChild(scaleNode);
MgByteSource byteSource = ByteSourceFromXMLDoc(doc);
string sessionLayoutName = layoutResId.GetName();
MgResourceIdentifier sessionLayoutResId = new MgResourceIdentifier(sessionLayout);
resSvc.SetResource(sessionLayoutResId, byteSource.GetReader(), null);
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 |