Mapguide Location

 

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 running as public service, just like Google Maps or Bing Maps.

當你要告訴您的朋友您最喜歡的餐館在哪裏的時候,你會怎麼做?告訴他們地址?是的,很好,但怎麼樣在地圖上指出來呢?在這一主題中,我們將討論如何實現基於 MapGuide Web GIS 應用的地圖共享功能,這是作爲公共服務來運行,就像谷歌。

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:

在這個主題中我更喜歡使用 Fusion Viewer Fusion 是一個 Web 地圖應用開發框架。它允許 Web 設計和開發人員容易並快速地構建豐富的地圖應用。在 Fusion 的模塊化體系結構中使用“小窗件”以提供界面接口功能;使用符合標準的 HTML CSS 允許開發者具有添加,刪除或修改的功能。我們需要創建網頁並在 MapGuide Studio 中編輯靈活網絡佈局同時將它添加到任務窗格:

 

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.

MapGuide Fusion Viewer 提供了許多“小窗件”, 這些“小窗件”使用 JavaScript 實現。我們可以利用 Fusion Viewer API 獲取當前地圖的中心座標及比例,然後通過這些參數傳遞到 MapGuide Web 應用程序主頁面。

< 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.

現在,讓我們產生主頁面。爲了避免 MapGuide 的身份驗證登錄對話框,我們創建一個 MapGuide 的連接並生成會話字符串,然後將它傳遞給瀏覽者的路徑。

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.

Web 應用程序的主頁,我們將嘗試從網址獲取視圖位置參數。如果這些參數在所附的網址裏,它可能是來自朋友的網址,地圖將跳到指定的視圖位置,否則地圖應程序加載初始視圖位置。

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:

現在,我們將討論以上頁面被加載時如何使查看地圖跳轉到指定的視圖位置。在 Autodesk MapGuide Studio 中,我們可以使用網絡佈局編輯器編輯靈活網頁佈局。默認的 “地圖初始視圖” 設置爲“使用地圖的初始視圖”;你還可以指定爲以下值:

 

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 <Initial View> section marked as bold.

當以上設置保存時該應用程序的 XML 定義改變如下,你可以通過 Maestro 方便地獲取該 XML ,請注意標記爲粗體部分的 <Initial View>

< 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 <Initial View> 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:

好了,正如我們所知道的原理,讓我們用代碼來實現。我們將爲網絡佈局添加 <Initial View> 節點。但還有另一件事情我們必須關注,我們並沒有改變在庫倉儲中網頁的佈局,因爲它會影響所有用戶。爲了不混淆其他的用戶,我們需要創建一個臨時的基於當前會話的網絡佈局。代碼如下:

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!

下面是測試結果,縮放你的地圖到你感興趣並希望共享的地方,按“ Generate Current View URL ”按鈕,一個像 http://serverName/SharePosition/default.aspx?x=-87.699801035788&y=43.751721697876&scale=3200.000005286838 將會生成。你可以複製該 URL 網址並通過 Email 或即時通訊工具發送給朋友。當他們打開此網址,地圖就會跳到跟你一樣的視圖位置。試一下吧!

 

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

同時也歡迎您通過 http://www.newmgdn.com 討論 MapGuide 中的有關問題。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章