| Perfil de JohannesHannes's Virtual Earth B...BlogListasSkyDrive | Ayuda |
Hannes's Virtual Earth Blog |
|||||
|
20 noviembre Bing Maps Silverlight Control & PhotosynthLast week we launched a new wave of Bing Maps. My esteemed colleague Chris Pendleton has blogged about some of the changes here, here, here and here. One of the main announcements has been the launch of the Bing Maps Silverlight Control v1. You will find the interactive SDK here, the full reference on MSDN here and the download here. This control has been available as a Community Technology Preview (CTP) for quite a while but those of you who have been waiting for a fully supported version before getting involved may not be too familiar with it yet. If you did work with the CTP please be aware that it is time-bombed and will stop working by the end of the year; so please consider updating your application soon. If you have been working with the Bing Maps AJAX Control before you may actually be missing a few things that came in handy if you wanted to display additional information like for a example a Photosynth collection. This was quite simple in the AJAX control since you could simply generate an iFrame in Photosynth and just add it to a VEShape-object using the VEShape.SetDescription-method. You can look at a sample here and download the source here). Since pushpins in the Silverlight control don’t have an info-box like the ones in the AJAX-control the approach here is quite different but it still works very well. The major obstacle appear to be that we cannot directly integrate HTML-code into our Silverlight application. The solution is actually to use the HTML Bridge in order to lay a HTML DIV-element on top of the Silverlight control and arrange it appropriately. Of course you can write everything from the scratch but the guys from divelements have created a Silverlight-Control HtmlHost for us that you can download for free and use to add and control HTML content directly from your Silverlight application. Let’s have a crack at it. For this walkthrough we will need
First we create a new Silverlight application and add references to our Bing Maps Silverlight Control In the MainPage.xaml we add a reference to our Bing Maps Silverlight control… xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
…and the the map itself with a pushpin at the location where we our Photosynth collection is. We also attach an event to the pushpin that fires when we click on it. <m:Map CredentialsProvider="YOUR BING MAPS KEY" Mode="AerialWithLabels" Center="32.362980181127874,-64.71483707427978" ZoomLevel="17"> <m:Pushpin Name="pinMartelloTower" Location="32.362980181127874,-64.71483707427978" MouseLeftButtonDown="pinMartelloTower_MouseLeftButtonDown"/> </m:Map>
If you had done something like this with the CTP before you will notice a few differences:
In my sample here I chose to bring up the Photosynth collection as part of a ChildWindow. A ChildWindow is a Silverlight control that comes with the Silverlight Toolkit. So let’s add a ChildWindow as new object to our Silverlight-project. I call it Photosynth. The trouble with a ChildWindow and HTML-DIV-elements on top is that the ChildWindow has an animation and explodes when you open it. If you would just add the HTML-DIV-element when the ChildWindow opens it would appear in the bottom-right quadrant of the screen. In order to avoid this we can simply remove the animation by changing the template in Expression Blend. In Visual Studio just right-click on the ChildWindow and select “Open in Expression Blend” from the context menu. In Expression Blend right-click on the ChildWindow-object and select “Edit Template” => “Edit a Copy”. Now we switch to code-view and remove the whole VisualStateManager that handles the StoryBoards for opening and closing the window. By default this would start around line 119: While we’re at it we can optionally make a few more changes to adjust the design: Now we can leave Expression Blend and go back to Visual Studio. In order to add the HtmlHost from divelements right-click on the Toolbox, select “Choose Items” from the context menu and add the Divelements.SilverlightTools.dll from the location where you extracted the download. Now drag&drop the control on your ChildWindow. This will automatically add the required namespace you only need to add a Name-property to the HtmlHost. Your XAML-should now look like this <controls:ChildWindow x:Class="SilverlightApplication2.Photosynth" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:my="clr-namespace:Divelements.SilverlightTools;assembly=Divelements.SilverlightTools" Width="400" Height="300" Title="Photosynth"> <controls:ChildWindow.Resources> … Finally we can start coding. The only code we need is actually in the MainPage.xaml.vb. When we initialize the page we also add a handler which resizes the ChildWindow whenever the size of the browser window changes. When we click on the pushpin we set the title for the ChildWindow as well as the source for the HtmlHost. In this case we just add the iFrame which we can copy directly from Photosynth… …and make to minor changes:
Imports System.Windows.Browser Partial Public Class MainPage Inherits UserControl Public myHeight As Integer Public myWidth As Integer Private WithEvents cwPhotosynth As New Photosynth Public Sub New() InitializeComponent() AddHandler LayoutRoot.SizeChanged, AddressOf Page_SizeChanged End Sub Private Sub Page_SizeChanged(ByVal sender As Object, ByVal e As SizeChangedEventArgs) myWidth = CInt(e.NewSize.Width) myHeight = CInt(e.NewSize.Height) cwPhotosynth.Width = e.NewSize.Width * 0.8 cwPhotosynth.Height = e.NewSize.Height * 0.8 End Sub Private Sub pinMartelloTower_MouseLeftButtonDown _ Well that’s already it: You can have a look at the sample here and download the source code here. Note: if you download the sample code you need to create a Bing Maps Key and enter it into the XAML in order to load the Bing Maps. Also note that the solution was build with Visual Studio 2010 Beta 2, however all methods work as well in Visual Studio 2008 SP1 13 noviembre Bing Maps at TechEd EuropeOn behalf of our friends from Borchert GeoInfo and the Bing Maps team I would like to thank everybody who visited us at the booth during the TechEd in Berlin or attended one of my sessions. Some of you asked for my presentations and the sample code. You will find everything here on my SkyDrive: Have a look at the Readme.pdf if you are unsure about what you need. 08 noviembre Bing Maps at TechEd EuropeTomorrow the TechEd Europe opens it’s gates in Berlin and Bing Maps will be represented as well. Chris Pendleton will come over from Redmond and join us for the week and I have the privilege of presenting 2 sessions on Bing Maps:
Here is a quick Bing Maps Collection with some MapCruncher layers that shows the venue and helps you find the Bing Maps booth and the locations for my sessions :-) You can also jump straight into a 3D-tour. I’m looking forward to see some of you in Berlin. 02 septiembre Bing Maps & SQL Server 2008 R2 Reporting ServicesSQL Server 2008 R2 is the next generation of the Microsoft SQL Server platform. The release is planned for the first half of calendar year 2010 but for those who can’t wait there is as always a community technology preview (CTP). The August CTP has lots of new features and from the mapping perspective the most interesting one is the integration of a maps in SQL Server Reporting Services. With just a few mouse-clicks you can generate thematic maps from spatial data stored as GEOMTRY or GEOGRAPHY data types in SQL Server 2008 or from ESRI SHP-files and you can use Bing Maps roads, aerial or hybrid images as background data. If you are as nosy as me, you can download the CTP here. Check it out it’s really incredible simple.
21 agosto 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:
|
Carpetas públicas
|
||||
|
|