| Johannes's profileHannes's Virtual Earth B...BlogListsSkyDrive | Help |
|
August 21 Bing Maps & WikipediaIf you have been using the “Explore Collections” feature in the consumer facing implementation of Bing Maps before you may have wondered if it is possible to get this feature into your own Bing Maps implementation as well. Indeed that is possible and there is a quite simple approach. In the following walkthrough we will get specifically Wikipedia content into our Bing Maps. Let’s start with a closer look how the consumer side does it: If we go to Bing Maps and search for a location like “Tower of London” we’ll find that we can explore collections for this location. These collections are basically a whole lot of community content that was created in Bing Maps collections, is available as GeoRSS, KML, KMZ or GPX on the internet and was found by the crawlers or is integrated from Wikipedia and Photosynth. We can filter this content, apply different sort criteria such as distance and then we could subscribe to an RSS-feed with the results. A closer look at the RSS-feed will show that it is in fact a GeoRSS-feed and we know of course that we can import GeoRSS-feeds into Bing Maps using the VEMap.ImportShapeLayerData-method. What we really want is however not a static feed, we want to update the results when we pan or zoom the map so let’s have a closer look at the URL of the feed: So in fact we are calling a web service that generates the GeoRSS-feed dynamically and the parameter bbox contains the bounding box with the South-West and North-East corner of the area for which we want to retrieve the data. Well that is simple enough to implement but there is one more thing to consider: If we call a GeoRSS-feed that is in a different domain we get an annoying security warning from our browser: To avoid this security warning we can set up a proxy as described by Mike McDougall here. Our HTML- and JavaScript code could look like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script> <script type="text/javascript"> var map = null; //VEShapeLayer var slGeoRSS = new VEShapeLayer(); function GetMap() { map = new VEMap('myMap'); map.LoadMap(new VELatLong(51.508145,-0.07626), 17, 'h', false); } function AddShape(control) { if (document.getElementById(control).checked == false) { //Delete all Shapes slGeoRSS.DeleteAllShapes(); //Detach Map-Events map.DetachEvent("onendpan", LoadData); map.DetachEvent("onendzoom", LoadData); } else { //Attach Map-Events map.AttachEvent("onendpan", LoadData); map.AttachEvent("onendzoom", LoadData); LoadData(); } } function LoadData() { map.DeleteAllShapes(); //Retrieve the boundaries of the mapview var nePixel = new VEPixel(600, 0); //North-East corner of the map view var swPixel = new VEPixel(0, 400); //South West corner of the map view var neLatLon = map.PixelToLatLong(nePixel); var neLat = neLatLon.Latitude; var neLon = neLatLon.Longitude; var swLatLon = map.PixelToLatLong(swPixel); var swLat = swLatLon.Latitude; var swLon = swLatLon.Longitude; //Build URL to call the server var url = "./GeoRSS-Proxy.ashx?source=http://www.bing.com/maps/GeoCommunity.asjx?"; url += "action=retrieverss&mkt=en-gb&ss=&bbox="; url += swLon + ","; url += swLat + ","; url += neLon + ","; url += neLat; url += "&startindex=0&order=distance&tag=Wikipedia"; var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, url, slGeoRSS); map.ImportShapeLayerData(veLayerSpec, onGeoRSSLoad, false); } function onGeoRSSLoad(a, b) { var numShapes = slGeoRSS.GetShapeCount(); var numPoints = 0; for (var i = 0; i < numShapes; ++i) { var s = slGeoRSS.GetShapeByIndex(i); s.SetCustomIcon("IMG/wikipedia.gif"); } } </script> </head> <body onload="GetMap();"> <div id='myMap' style="position:absolute; top:0px; left:0px; width:600px; height:400px;"></div><br /> <div id='divCtrl' style="position:absolute; top:400px; left:0px; width:600px;" > <input id="cbGeoRSS" type="checkbox" onclick="AddShape('cbGeoRSS')" /><a>Wikipedia</a><br /> </div> </body> </html> And here is the proxy implemented as a Generic WebHandler <%@ WebHandler Language="VB" Class="GeoRSS_Proxy" %> Imports System Imports System.Web Imports System.Net Imports System.IO Public Class GeoRSS_Proxy : Implements IHttpHandler Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest Dim myUrl As String = "" myUrl = context.Request.QueryString(0) For i = 1 To context.Request.QueryString.Count - 1 myUrl = myUrl + "&" + context.Request.QueryString.AllKeys(i) + "=" + context.Request.QueryString(i) Next 'Dim source As String = context.Request.QueryString("source") context.Response.ContentType = "text/xml" context.Response.ContentEncoding = System.Text.Encoding.UTF8 Dim request As HttpWebRequest = DirectCast(HttpWebRequest.Create(myUrl), HttpWebRequest) Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse) Dim stream As StreamReader = New StreamReader(response.GetResponseStream(), Encoding.ASCII) context.Response.Write(stream.ReadToEnd()) End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class The sample code is available here:
TrackbacksThe trackback URL for this entry is: http://johanneskebeck.spaces.live.com/blog/cns!42E1F70205EC8A96!10073.trak Weblogs that reference this entry
|
|
|