Johannes Kebeck's Blog
09-26-2007, 07:50 AM
<p>In the <a href="http://johanneskebeck.spaces.live.com/blog/cns!42E1F70205EC8A96!1752.entry">first part</a> we have been looking at some general resources to get started with your Virtual Earth development and in the <a href="http://johanneskebeck.spaces.live.com/blog/cns!42E1F70205EC8A96!1792.entry">second part</a> we created an AJAX-enabled ASP.NET web site which will host our various samples. We also added the first type of content - the individual VEShape - which was in this case a pushpin with a traffic cam-image in the infobox. Now we are going a step further and will*import a number of various information into a VEShapeLayer. There are 2 ways how to do this: <ul> <li>Import from a Live Search Maps Collection and <li>Import from an GeoRSS-feed</ul> <p><strong>Live Search Maps Collections</strong> <p><a href="http://maps.live.com/?mkt=en-us">Live Search Maps</a> is the consumer facing implementation of Virtual Earth. It uses a variety of features from the Virtual Earth API and adds a number of further features which are specific to this implementation and may even be specific to a market. For example: traffic overlays are currently only available in the United States and so are the features 'Call for free' and 'Send to mobile' which are*accessible from*the results of a business search. One*very nice*feature is however available for all markets: the Collections. <table cellspacing=0 cellpadding=2 width=785 border=1> <tbody> <tr> <td valign=top width=783><em><u>Tip:</u> If you want to see these market-specific features*add the following URL-parameters: </em><a title="http://maps.live.com/?mkt=en-us" href="http://maps.live.com/?mkt=en-us"><em>http://maps.live.com/<strong>?mkt=en-us</strong></em></a></tbody></table> <p>You can add the results of your searches to a scratch pad and you can even add drawings of type point, polyline or polygon to this scratchpad. These annotations to the map can contain URLs to images or further information. To make the content of the scratch pad persistent you can sign-in with your Windows Live ID and store them in a collection. Such collections can be private or shared and you can make them optionally searchable - a great feature to enhance the user experience of Live Search Maps by adding local knowledge to the global community. Here I have have such a <a href="http://maps.live.com/?v=2&cid=42E1F70205EC8A96!837&encType=1">collection for the London Bus Tour</a>. <p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV0n7B0lTuzY3y-CChaqYfJmXSGdUjEGG5sf68o1n4vmNIQSprW_T5j-BHIdbmeLFedJoc25HyD-Wa1I87XdLPuN"><img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px" alt=07-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV3g6VqWHgFbGQoRLJR-2ZshCPpupfhHP-jr6VJzgovSNf6PVhS0O5gRVNtnCmQOtlp3USVa6OME6xpcDDg1 O-BV" border=0></a> <p>If*you want to share the collection you can use the menu of the scratch pad to do so. You can directly blog it, you can send the URL in an email or you can just copy it to the clipboard. What you get in any case is a tiny URL with a parameter for a Collection ID like shown*here:*<a title="http://maps.live.com/?v=2&cid=42E1F70205EC8A96!837&encType=1" href="http://maps.live.com/?v=2&cid=42E1F70205EC8A96!837&encType=1">http://maps.live.com/?v=2&cid=42E1F70205EC8A96!837&encType=1</a>. While this is extremely simple to use, you might also want to make use of these collections in your custom application with your personal*branding or corporate identity. The Virtual Earth API supports the import of such collections into a VEShapeLayer and we will extend our existing AJAX-enabled application from part 2 and walk through the steps which are required to do that and. <p>First we add a new a AccordionPane to our ASP.NET AJAX web site. Within this pane we have a HTML-control of type checkbox and we define an onclick event for the control which calls the JavaScript-function AaddGCLayer with a couple of parameters. We will discuss these parameters a little bit later.<pre><span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span> <span style="color:rgb(255,0,0)">ID</span><span style="color:rgb(0,0,255)">="paneCollection"</span> <span style="color:rgb(255,0,0)">runat</span><span style="color:rgb(0,0,255)">="server">
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">></span>Collection Layer<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbLondonBus"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbLondonBus',LondonBusLayer,VEDataType .VECollection,'42E1F70205EC8A96!837')"</span> <span style="color:rgb(0,0,255)">/></span>London Bus Tour<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/>
</span> <span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span><span style="color:rgb(0,0,255)">>
</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>Now let's look at the JavaScript part. In the global section we define a new VEShapeLayer in which we will import the collection<pre><span style="color:rgb(0,0,255)">var</span> LondonBusLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>
<p>The function AddGCLayer will import the Live Search Maps collection into this layer. It is a very generic script which will allow us to import not only collections but also GeoRSS-feeds. The parameter we use to call this function are:
<ul>
<li>the name of the HTML-control which is being clicked. This is just used to determine later if the checkbox has been activated or de-activated.
<li>The name of the layer we want to import into
<li>the <a href="http://msdn2.microsoft.com/en-us/library/bb412442.aspx">VEDataType</a> of the data source we want to import into VEShapeLayer. It is a mandatory property for the <a href="http://msdn2.microsoft.com/en-us/library/bb429634.aspx">VEShapeSourceSpecification</a>. Valid properties are VECollection and GeoRSS. The former is what we need here.
<li>The collection ID if it is a VECollection or the URL if it is a GeoRSS feed</ul>
<p>In the function we first check if the checkbox has been activated or deactivated. If it has been deactivated we remove all VEShapes from this particular layer. If it has been activated we add define the <a href="http://msdn2.microsoft.com/en-us/library/bb429634.aspx">VEShapeSourceSpecification</a>*with the parameters mentioned above and then import the data into the layer. <pre><span style="color:rgb(0,0,255)">function</span> AddGCLayer(control, layer, type, url)
{
<span style="color:rgb(0,0,255)">if</span> (document.getElementById(control).checked == <span style="color:rgb(0,0,255)">false</span>) {
layer.DeleteAllShapes();
}
<span style="color:rgb(0,0,255)">else</span> {
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, url, layer);
map.ImportShapeLayerData(layerSpec,onGCLoad);
}
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>You also see that we define a callback-function when we execute the method <a href="http://msdn2.microsoft.com/en-us/library/bb429606.aspx">ImportShapeLayerData</a>. This*is an optional parameter and allows us e.g. to modify the data once we imported*them. In our example I want to use this function to replace the default icons with a numbered pushpin. To do that we first <a href="http://msdn2.microsoft.com/en-us/library/bb429622.aspx">determine the number of VEShape-objects in our VEShapeLayer</a>. Then we <a href="http://msdn2.microsoft.com/en-us/library/bb412540.aspx">loop through all the VEShape-objects</a> and <a href="http://msdn2.microsoft.com/en-us/library/bb412425.aspx">set a custom icon</a>. Our icons are not just defined by an image but also by a text-field which we will populate with*a number.<pre><span style="color:rgb(0,0,255)">function</span> onGCLoad()
{
<span style="color:rgb(0,0,255)">var</span> numShapes = currentLayer.GetShapeCount();
<span style="color:rgb(0,0,255)">for</span>(<span style="color:rgb(0,0,255)">var</span> i=0; i < numShapes; ++i)
{
<span style="color:rgb(0,0,255)">var</span> s = currentLayer.GetShapeByIndex(i);
s.SetCustomIcon(<span style="color:rgb(163,21,21)">"<div style='position:absolute; top:0px; left:0px;'><img src='poi_search.gif' /></div><div style='position:absolute; top:0px; left:0px; width:25px; text-align: center; color: #ffffff'>"</span> + (i+1) + <span style="color:rgb(163,21,21)">"</div>"</span>);
}
} </pre>
<p>
<table cellspacing=0 cellpadding=2 width=786 border=1>
<tbody>
<tr>
<td valign=top width=784><em><u>Tip:</u> If you want to debug your JavaScript in Visual Studio and your default browser is the Internet Explorer you may want to uncheck 'Disable script debugging (Internet Explorer)' in the advanced tabulator of the Internet Explorer options dialog. Now you can set breakpoints in your JavaScript and debug the code in the same*fashion as you do with .NET-managed code.<br><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV3U0vKSU-hIbQgpZOGNtuEbptTdyY6JwqMT81Zu8S7jZ68el941ABIlXqEU 4RkRiWfPcWzh0GaEySt6ut1FonsN"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=10-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV1n_NHBfMtNNi2nEk7XDqC2amAUoPtzShggC8F xBgzGIAroZNYNIa6QjSgx3e-QIV6wqJj8IhrCHnMvjAjJ2_Gq" border=0></a> </em></tbody></table>
<p>All right, that's it we can now see our Live Search Maps Collection in our custom Virtual Earth application.
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV3Db69VNYrXuBUIuhKXpzZrEynZhgumXdeUyAn fY6sa4Wcma6jOp2oCaVBuEG664tLRHG-BVDymnwcQN9Gc_K0t"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=09-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV309Dd5pKxFBs3rwmmZu78vlCdGiMniKMXJrWa B0j2hME9Jo7YFofXbp4V1RTTL1p-AhBURUzp3b-Zvk-_BNzl_" border=0></a>
<p><strong>GeoRSS-deeds</strong>
<p>Since the methods to add a GeoRSS-feed are exactly the same as the ones which are being used to add a Live Search Maps collection we will add such a sample in this part as well.
<p>GeoRSS is an extension to the well known Real Simple Syndications (RSS). It adds tags for the location information but unfortunately a unique standard has not yet*been established. Virtual Earth support the <a href="http://georss.org/simple">simple specification</a> according to GeoRSS.org as well as the <a href="http://georss.org/gml">GML-specification</a> as suggested by the Open Geospatial Consortium (OGC). Both of them support points, polylines and polygons. Let's have a look at such a feed. You see below that there is actually just one tag more than in a typical RSS-feed.<pre><span style="color:rgb(0,0,255)"><?</span><span style="color:rgb(163,21,21)">xml</span><span style="color:rgb(0,0,255)"> </span><span style="color:rgb(255,0,0)">version</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">1.0</span>"<span style="color:rgb(0,0,255)">?>
<</span><span style="color:rgb(163,21,21)">rss</span><span style="color:rgb(0,0,255)"> </span><span style="color:rgb(255,0,0)">version</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">2.0</span>"<span style="color:rgb(0,0,255)">
</span><span style="color:rgb(255,0,0)">xmlns:georss</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">http://www.georss.org/georss</span>"<span style="color:rgb(0,0,255)">
</span><span style="color:rgb(255,0,0)">xmlns:gml</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">http://www.opengis.net/gml</span>"<span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">channel</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Point<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">link</span><span style="color:rgb(0,0,255)">></</span><span style="color:rgb(163,21,21)">link</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:point</span><span style="color:rgb(0,0,255)">></span>51.449139537118 -1.0529091954231<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:point</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Line<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:line</span><span style="color:rgb(0,0,255)">></span>51.46138386849 -0.9245842695236 ... 51.4492130864 -1.0533142089843<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:line</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Polygon<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:polygon</span><span style="color:rgb(0,0,255)">></span>51.46221441192 -0.9249061346054 ... 51.46221441192 -0.9249061346054<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:polygon</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
</span><span style="color:rgb(0,0,255)"> </</span><span style="color:rgb(163,21,21)">channel</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">rss</span><span style="color:rgb(0,0,255)">></span></pre><a href="http://11011.net/software/vspaste"></a>
<p>The items in such a GeoRSS-feed are described within XML-tags so it is pretty simple to create your own parser if your source data is available e.g. in your existing MapPoint-files or in a database. In a later part we will have a look at how to create these GeoRSS-feeds directly from SQL Server 2008 (the one with the spatial engine). However, if you*want to reuse your existing spatial-data it is more complex and you would probably look at tools like <a href="http://www.safe.com/">Safe FME</a>. Safe FME can read more than 200 spatial formats and*has a huge number of useful transformers e.g. to generalize the*geometries*(node-thinning) or to convert coordinate systems. Another tool which reads spatial data from GML, AutoDesk (*.dxf), ESRI (*.shp) and MapInfo (*.mif) as well as KML-files is the <a href="http://www.brightisolutions.com/">GeoFeeder from BRIGHTisolutions</a>. It doesn't have the rich functionality of Safe FME but depending on your requirements it*might be a*cost-efficient solution. <br><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV1bkdTZKXmI0p6CnI1039eB3bDDXfm73Pebs31 W5YkaRfQ8R17kPqqhYzbV2wrhEbyraiC0CjRnR6u7LTJ19KDI"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=11-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV3S2rtd5UlU-cBEaFs1ZHBGobhSs8zL0DjW3HeT-QLpZFdVJpnvWO5rLprdMETTZoy9wsEBovHhLHUFYxq4sAqO" border=0></a>
<p>Now let's take the GeoRSS-feed as given and implement an example in our sample web site. First we add another AccordionPane to our web site. You see that we call the same JavaScript-function as before but there are 2 differences in the parameters:
<ul>
<li>We use VEDataType.GeoRSS instead of VEDataType.VECollection and
<li>We point the URL to our GeoRSS-feed rather than to a collection id</ul><pre><span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span> <span style="color:rgb(255,0,0)">ID</span><span style="color:rgb(0,0,255)">="paneGeoRSSLayer"</span> <span style="color:rgb(255,0,0)">runat</span><span style="color:rgb(0,0,255)">="server">
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">></span>GeoRSS Layer<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbLCZ"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbLCZ',LCZLayer,VEDataType.GeoRSS,'Geo RSS/LondonCongestionZone.xml')"</span> <span style="color:rgb(0,0,255)">/></span>London Congestion Zone<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/>
</span> <span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span><span style="color:rgb(0,0,255)">></span></pre><a href="http://11011.net/software/vspaste"><a href="http://11011.net/software/vspaste"></a>
<p>As mentioned before the JavaScript part is exactly the same we are just declare one more layer in our global section<pre><span style="color:rgb(0,0,255)">var</span> LCZLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>
<p>This is already it. We have our first GeoRSS-feed in*our sample*application
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV14JbJFBTiapuJn8C8W8CsAps__6eJkfCLsFYh JGH6PHGHqJ4oe_T3YhX4FKNxtKq6bPM0Jv-BWpjgsQG5TPefx"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=12-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV2jEKuSA0at9FU9N-AVUVZhM1t5WQgJg267UepNafMTVNdvVgXR7t6bu7ELfagCqGZd X_42BrVZdvQO_Ourx2oV" border=0></a>
<p>Virtual Earth has unfortunately one limitation in the usage of GeoRSS-feeds: the GeoRSS-feed has to be on the same domain as your Virtual Earth application. Well that is usually not a problem if you just use your own data but if you want to leverage all the great information which are on the web available*as GeoRSS-feeds it can be quite disappointing. There is however a nice workaround which has been published by Mike McDougall from <a href="http://www.brightisolutions.com/">BRIFGTisolution</a> on <a href="http://www.viawindowslive.com/Articles/VirtualEarth/AccessingRemoteGeoRSS.aspx">Via Windows Live</a>. It basically uses a generic Web Handler as a proxy to execute an HTTPWebRequest to the GeoRSS-feed in the external domain. We will implement this workaround within a try ... catch clause to overlay an GeoRSS-from Flickr.
<p>In the content part of our AccordionPane we add another HTML-control of type checkbox which uses the URL to the Flickr-feed as parameter<pre><span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbFlickr"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbFlickr',FlickrLayer,VEDataType.GeoRS S,'http://api.flickr.com/services/feeds/geo/?tags=ufo&lang=en-us&format=rss_200')"</span> <span style="color:rgb(0,0,255)">/></span>Flickr<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/></span></pre><a href="http://11011.net/software/vspaste"></a>
<p>In the global part of our JavaScript we define another layer<pre><span style="color:rgb(0,0,255)">var</span> FlickrLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>And then we*extend our existing JavaScript AddGCLayer*with the try ... catch clause so that we redirect to our WebHandler if we hit the error "Permission denied".<pre><span style="color:rgb(0,0,255)">function</span> AddGCLayer(control, layer, type, url)
{
<span style="color:rgb(0,0,255)">if</span> (document.getElementById(control).checked == <span style="color:rgb(0,0,255)">false</span>) {
layer.DeleteAllShapes();
}
<span style="color:rgb(0,0,255)">else</span> {
<span style="color:rgb(0,0,255)">try
</span> {
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, url, layer);
map.ImportShapeLayerData(layerSpec,onGCLoad);
}
<span style="color:rgb(0,0,255)">catch</span>(err)
{
<span style="color:rgb(0,0,255)">if</span> (err.message=<span style="color:rgb(163,21,21)">"Permission denied"</span>)
{
<span style="color:rgb(0,0,255)">var</span> proxyPath = <span style="color:rgb(163,21,21)">"GeoRSSProxy.ashx?source="</span> + url;
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, proxyPath, layer);
map.ImportShapeLayerData(layerSpec, onGCLoad);
}
}
}
}
</pre><a href="http://11011.net/software/vspaste"></a>
<p>Now that this redirection is prepared we need to add of course our WebHandler. We call it GeoRSSProxy, imports the following namespaces:
<ul>
<li>Imports System.IO
<li>Imports System.Net</ul>
<p>...and replace the default-code in 'Public Sub ProcessRequest' with the code below<pre><span style="color:rgb(0,0,255)">Dim</span> source <span style="color:rgb(0,0,255)">As</span> <span style="color:rgb(0,0,255)">String</span> = context.Request.QueryString(<span style="color:rgb(163,21,21)">"source"</span>)
context.Response.ContentType = <span style="color:rgb(163,21,21)">"text/xml"
</span>context.Response.ContentEncoding = System.Text.Encoding.UTF8
<span style="color:rgb(0,0,255)">Dim</span> request <span style="color:rgb(0,0,255)">As</span> HttpWebRequest = <span style="color:rgb(0,0,255)">DirectCast</span>(HttpWebRequest.Create(source), HttpWebRequest)
<span style="color:rgb(0,0,255)">Dim</span> response <span style="color:rgb(0,0,255)">As</span> HttpWebResponse = <span style="color:rgb(0,0,255)">DirectCast</span>(request.GetResponse(), HttpWebResponse)
<span style="color:rgb(0,0,255)">Dim</span> stream <span style="color:rgb(0,0,255)">As</span> StreamReader = <span style="color:rgb(0,0,255)">New</span> StreamReader(response.GetResponseStream(), Encoding.ASCII)
context.Response.Write(stream.ReadToEnd())</pre><a href="http://11011.net/software/vspaste"></a>
<p>Here we go:
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV2WqtVZvuhblMRZnXeLl0PmH3eMYDDgpH4V-IG9hxSWlxO4PdTg-aLSfyOYqLYLx2wHC8Gj7_bTv0OHoQ7DGgGb"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=13-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV3URW7ugFQIXFibZiApaq4PEfh1sP6ZUY-dNGOOgo76YiAgAz6NS5XCD6983Hfd6sMl_QFmoraArIBm2O9im IJd" border=0></a>*
<p>You can preview and download the complete source code <a href="http://mappointemea.members.winisp.net/Collections/Default.aspx">here</a>.
<div style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px">Technorati Tags: <a href="http://technorati.com/tags/Virtual Earth" rel=tag>Virtual Earth</a>, <a href="http://technorati.com/tags/Live Search Maps" rel=tag>Live Search Maps</a>, <a href="http://technorati.com/tags/Collection" rel=tag>Collection</a>, <a href="http://technorati.com/tags/GeoRSS" rel=tag>GeoRSS</a>, <a href="http://technorati.com/tags/VEShapeLayer" rel=tag>VEShapeLayer</a></div></a><img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4819404664324524694&page=RSS%3a+How+to+bring+your+own+content+to+Virtu al+Earth+(Part+3)&referrer=" width="1px" height="1px" border="0" alt=""><img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&NA=1149&PI=88469&RF=&DI=3919&PS=85545&TP=johanneskebeck.spaces.live.com>1=JohannesKebeck">
Click here to view the article. (http://JohannesKebeck.spaces.live.com/Blog/cns!42E1F70205EC8A96!1817.entry)
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">></span>Collection Layer<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbLondonBus"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbLondonBus',LondonBusLayer,VEDataType .VECollection,'42E1F70205EC8A96!837')"</span> <span style="color:rgb(0,0,255)">/></span>London Bus Tour<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/>
</span> <span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span><span style="color:rgb(0,0,255)">>
</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>Now let's look at the JavaScript part. In the global section we define a new VEShapeLayer in which we will import the collection<pre><span style="color:rgb(0,0,255)">var</span> LondonBusLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>
<p>The function AddGCLayer will import the Live Search Maps collection into this layer. It is a very generic script which will allow us to import not only collections but also GeoRSS-feeds. The parameter we use to call this function are:
<ul>
<li>the name of the HTML-control which is being clicked. This is just used to determine later if the checkbox has been activated or de-activated.
<li>The name of the layer we want to import into
<li>the <a href="http://msdn2.microsoft.com/en-us/library/bb412442.aspx">VEDataType</a> of the data source we want to import into VEShapeLayer. It is a mandatory property for the <a href="http://msdn2.microsoft.com/en-us/library/bb429634.aspx">VEShapeSourceSpecification</a>. Valid properties are VECollection and GeoRSS. The former is what we need here.
<li>The collection ID if it is a VECollection or the URL if it is a GeoRSS feed</ul>
<p>In the function we first check if the checkbox has been activated or deactivated. If it has been deactivated we remove all VEShapes from this particular layer. If it has been activated we add define the <a href="http://msdn2.microsoft.com/en-us/library/bb429634.aspx">VEShapeSourceSpecification</a>*with the parameters mentioned above and then import the data into the layer. <pre><span style="color:rgb(0,0,255)">function</span> AddGCLayer(control, layer, type, url)
{
<span style="color:rgb(0,0,255)">if</span> (document.getElementById(control).checked == <span style="color:rgb(0,0,255)">false</span>) {
layer.DeleteAllShapes();
}
<span style="color:rgb(0,0,255)">else</span> {
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, url, layer);
map.ImportShapeLayerData(layerSpec,onGCLoad);
}
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>You also see that we define a callback-function when we execute the method <a href="http://msdn2.microsoft.com/en-us/library/bb429606.aspx">ImportShapeLayerData</a>. This*is an optional parameter and allows us e.g. to modify the data once we imported*them. In our example I want to use this function to replace the default icons with a numbered pushpin. To do that we first <a href="http://msdn2.microsoft.com/en-us/library/bb429622.aspx">determine the number of VEShape-objects in our VEShapeLayer</a>. Then we <a href="http://msdn2.microsoft.com/en-us/library/bb412540.aspx">loop through all the VEShape-objects</a> and <a href="http://msdn2.microsoft.com/en-us/library/bb412425.aspx">set a custom icon</a>. Our icons are not just defined by an image but also by a text-field which we will populate with*a number.<pre><span style="color:rgb(0,0,255)">function</span> onGCLoad()
{
<span style="color:rgb(0,0,255)">var</span> numShapes = currentLayer.GetShapeCount();
<span style="color:rgb(0,0,255)">for</span>(<span style="color:rgb(0,0,255)">var</span> i=0; i < numShapes; ++i)
{
<span style="color:rgb(0,0,255)">var</span> s = currentLayer.GetShapeByIndex(i);
s.SetCustomIcon(<span style="color:rgb(163,21,21)">"<div style='position:absolute; top:0px; left:0px;'><img src='poi_search.gif' /></div><div style='position:absolute; top:0px; left:0px; width:25px; text-align: center; color: #ffffff'>"</span> + (i+1) + <span style="color:rgb(163,21,21)">"</div>"</span>);
}
} </pre>
<p>
<table cellspacing=0 cellpadding=2 width=786 border=1>
<tbody>
<tr>
<td valign=top width=784><em><u>Tip:</u> If you want to debug your JavaScript in Visual Studio and your default browser is the Internet Explorer you may want to uncheck 'Disable script debugging (Internet Explorer)' in the advanced tabulator of the Internet Explorer options dialog. Now you can set breakpoints in your JavaScript and debug the code in the same*fashion as you do with .NET-managed code.<br><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV3U0vKSU-hIbQgpZOGNtuEbptTdyY6JwqMT81Zu8S7jZ68el941ABIlXqEU 4RkRiWfPcWzh0GaEySt6ut1FonsN"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=10-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV1n_NHBfMtNNi2nEk7XDqC2amAUoPtzShggC8F xBgzGIAroZNYNIa6QjSgx3e-QIV6wqJj8IhrCHnMvjAjJ2_Gq" border=0></a> </em></tbody></table>
<p>All right, that's it we can now see our Live Search Maps Collection in our custom Virtual Earth application.
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV3Db69VNYrXuBUIuhKXpzZrEynZhgumXdeUyAn fY6sa4Wcma6jOp2oCaVBuEG664tLRHG-BVDymnwcQN9Gc_K0t"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=09-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV309Dd5pKxFBs3rwmmZu78vlCdGiMniKMXJrWa B0j2hME9Jo7YFofXbp4V1RTTL1p-AhBURUzp3b-Zvk-_BNzl_" border=0></a>
<p><strong>GeoRSS-deeds</strong>
<p>Since the methods to add a GeoRSS-feed are exactly the same as the ones which are being used to add a Live Search Maps collection we will add such a sample in this part as well.
<p>GeoRSS is an extension to the well known Real Simple Syndications (RSS). It adds tags for the location information but unfortunately a unique standard has not yet*been established. Virtual Earth support the <a href="http://georss.org/simple">simple specification</a> according to GeoRSS.org as well as the <a href="http://georss.org/gml">GML-specification</a> as suggested by the Open Geospatial Consortium (OGC). Both of them support points, polylines and polygons. Let's have a look at such a feed. You see below that there is actually just one tag more than in a typical RSS-feed.<pre><span style="color:rgb(0,0,255)"><?</span><span style="color:rgb(163,21,21)">xml</span><span style="color:rgb(0,0,255)"> </span><span style="color:rgb(255,0,0)">version</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">1.0</span>"<span style="color:rgb(0,0,255)">?>
<</span><span style="color:rgb(163,21,21)">rss</span><span style="color:rgb(0,0,255)"> </span><span style="color:rgb(255,0,0)">version</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">2.0</span>"<span style="color:rgb(0,0,255)">
</span><span style="color:rgb(255,0,0)">xmlns:georss</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">http://www.georss.org/georss</span>"<span style="color:rgb(0,0,255)">
</span><span style="color:rgb(255,0,0)">xmlns:gml</span><span style="color:rgb(0,0,255)">=</span>"<span style="color:rgb(0,0,255)">http://www.opengis.net/gml</span>"<span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">channel</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Point<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">link</span><span style="color:rgb(0,0,255)">></</span><span style="color:rgb(163,21,21)">link</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:point</span><span style="color:rgb(0,0,255)">></span>51.449139537118 -1.0529091954231<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:point</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Line<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:line</span><span style="color:rgb(0,0,255)">></span>51.46138386849 -0.9245842695236 ... 51.4492130864 -1.0533142089843<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:line</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">></span>My Polygon<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">title</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">></span><span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">description</span><span style="color:rgb(0,0,255)">>
<</span><span style="color:rgb(163,21,21)">georss:polygon</span><span style="color:rgb(0,0,255)">></span>51.46221441192 -0.9249061346054 ... 51.46221441192 -0.9249061346054<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">georss:polygon</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">item</span><span style="color:rgb(0,0,255)">>
</span><span style="color:rgb(0,0,255)"> </</span><span style="color:rgb(163,21,21)">channel</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">rss</span><span style="color:rgb(0,0,255)">></span></pre><a href="http://11011.net/software/vspaste"></a>
<p>The items in such a GeoRSS-feed are described within XML-tags so it is pretty simple to create your own parser if your source data is available e.g. in your existing MapPoint-files or in a database. In a later part we will have a look at how to create these GeoRSS-feeds directly from SQL Server 2008 (the one with the spatial engine). However, if you*want to reuse your existing spatial-data it is more complex and you would probably look at tools like <a href="http://www.safe.com/">Safe FME</a>. Safe FME can read more than 200 spatial formats and*has a huge number of useful transformers e.g. to generalize the*geometries*(node-thinning) or to convert coordinate systems. Another tool which reads spatial data from GML, AutoDesk (*.dxf), ESRI (*.shp) and MapInfo (*.mif) as well as KML-files is the <a href="http://www.brightisolutions.com/">GeoFeeder from BRIGHTisolutions</a>. It doesn't have the rich functionality of Safe FME but depending on your requirements it*might be a*cost-efficient solution. <br><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV1bkdTZKXmI0p6CnI1039eB3bDDXfm73Pebs31 W5YkaRfQ8R17kPqqhYzbV2wrhEbyraiC0CjRnR6u7LTJ19KDI"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=11-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV3S2rtd5UlU-cBEaFs1ZHBGobhSs8zL0DjW3HeT-QLpZFdVJpnvWO5rLprdMETTZoy9wsEBovHhLHUFYxq4sAqO" border=0></a>
<p>Now let's take the GeoRSS-feed as given and implement an example in our sample web site. First we add another AccordionPane to our web site. You see that we call the same JavaScript-function as before but there are 2 differences in the parameters:
<ul>
<li>We use VEDataType.GeoRSS instead of VEDataType.VECollection and
<li>We point the URL to our GeoRSS-feed rather than to a collection id</ul><pre><span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span> <span style="color:rgb(255,0,0)">ID</span><span style="color:rgb(0,0,255)">="paneGeoRSSLayer"</span> <span style="color:rgb(255,0,0)">runat</span><span style="color:rgb(0,0,255)">="server">
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">></span>GeoRSS Layer<span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Header</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbLCZ"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbLCZ',LCZLayer,VEDataType.GeoRSS,'Geo RSS/LondonCongestionZone.xml')"</span> <span style="color:rgb(0,0,255)">/></span>London Congestion Zone<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/>
</span> <span style="color:rgb(0,0,255)"></</span><span style="color:rgb(163,21,21)">Content</span><span style="color:rgb(0,0,255)">>
</</span><span style="color:rgb(163,21,21)">ajaxToolkit</span><span style="color:rgb(0,0,255)">:</span><span style="color:rgb(163,21,21)">AccordionPane</span><span style="color:rgb(0,0,255)">></span></pre><a href="http://11011.net/software/vspaste"><a href="http://11011.net/software/vspaste"></a>
<p>As mentioned before the JavaScript part is exactly the same we are just declare one more layer in our global section<pre><span style="color:rgb(0,0,255)">var</span> LCZLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>
<p>This is already it. We have our first GeoRSS-feed in*our sample*application
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV14JbJFBTiapuJn8C8W8CsAps__6eJkfCLsFYh JGH6PHGHqJ4oe_T3YhX4FKNxtKq6bPM0Jv-BWpjgsQG5TPefx"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=12-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV2jEKuSA0at9FU9N-AVUVZhM1t5WQgJg267UepNafMTVNdvVgXR7t6bu7ELfagCqGZd X_42BrVZdvQO_Ourx2oV" border=0></a>
<p>Virtual Earth has unfortunately one limitation in the usage of GeoRSS-feeds: the GeoRSS-feed has to be on the same domain as your Virtual Earth application. Well that is usually not a problem if you just use your own data but if you want to leverage all the great information which are on the web available*as GeoRSS-feeds it can be quite disappointing. There is however a nice workaround which has been published by Mike McDougall from <a href="http://www.brightisolutions.com/">BRIFGTisolution</a> on <a href="http://www.viawindowslive.com/Articles/VirtualEarth/AccessingRemoteGeoRSS.aspx">Via Windows Live</a>. It basically uses a generic Web Handler as a proxy to execute an HTTPWebRequest to the GeoRSS-feed in the external domain. We will implement this workaround within a try ... catch clause to overlay an GeoRSS-from Flickr.
<p>In the content part of our AccordionPane we add another HTML-control of type checkbox which uses the URL to the Flickr-feed as parameter<pre><span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">input</span> <span style="color:rgb(255,0,0)">id</span><span style="color:rgb(0,0,255)">="cbFlickr"</span> <span style="color:rgb(255,0,0)">type</span><span style="color:rgb(0,0,255)">="checkbox"</span> <span style="color:rgb(255,0,0)">onclick</span><span style="color:rgb(0,0,255)">="AddGCLayer('cbFlickr',FlickrLayer,VEDataType.GeoRS S,'http://api.flickr.com/services/feeds/geo/?tags=ufo&lang=en-us&format=rss_200')"</span> <span style="color:rgb(0,0,255)">/></span>Flickr<span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">br</span> <span style="color:rgb(0,0,255)">/></span></pre><a href="http://11011.net/software/vspaste"></a>
<p>In the global part of our JavaScript we define another layer<pre><span style="color:rgb(0,0,255)">var</span> FlickrLayer = <span style="color:rgb(0,0,255)">new</span> VEShapeLayer();</pre><a href="http://11011.net/software/vspaste"></a>And then we*extend our existing JavaScript AddGCLayer*with the try ... catch clause so that we redirect to our WebHandler if we hit the error "Permission denied".<pre><span style="color:rgb(0,0,255)">function</span> AddGCLayer(control, layer, type, url)
{
<span style="color:rgb(0,0,255)">if</span> (document.getElementById(control).checked == <span style="color:rgb(0,0,255)">false</span>) {
layer.DeleteAllShapes();
}
<span style="color:rgb(0,0,255)">else</span> {
<span style="color:rgb(0,0,255)">try
</span> {
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, url, layer);
map.ImportShapeLayerData(layerSpec,onGCLoad);
}
<span style="color:rgb(0,0,255)">catch</span>(err)
{
<span style="color:rgb(0,0,255)">if</span> (err.message=<span style="color:rgb(163,21,21)">"Permission denied"</span>)
{
<span style="color:rgb(0,0,255)">var</span> proxyPath = <span style="color:rgb(163,21,21)">"GeoRSSProxy.ashx?source="</span> + url;
currentLayer = layer;
<span style="color:rgb(0,0,255)">var</span> layerSpec = <span style="color:rgb(0,0,255)">new</span> VEShapeSourceSpecification(type, proxyPath, layer);
map.ImportShapeLayerData(layerSpec, onGCLoad);
}
}
}
}
</pre><a href="http://11011.net/software/vspaste"></a>
<p>Now that this redirection is prepared we need to add of course our WebHandler. We call it GeoRSSProxy, imports the following namespaces:
<ul>
<li>Imports System.IO
<li>Imports System.Net</ul>
<p>...and replace the default-code in 'Public Sub ProcessRequest' with the code below<pre><span style="color:rgb(0,0,255)">Dim</span> source <span style="color:rgb(0,0,255)">As</span> <span style="color:rgb(0,0,255)">String</span> = context.Request.QueryString(<span style="color:rgb(163,21,21)">"source"</span>)
context.Response.ContentType = <span style="color:rgb(163,21,21)">"text/xml"
</span>context.Response.ContentEncoding = System.Text.Encoding.UTF8
<span style="color:rgb(0,0,255)">Dim</span> request <span style="color:rgb(0,0,255)">As</span> HttpWebRequest = <span style="color:rgb(0,0,255)">DirectCast</span>(HttpWebRequest.Create(source), HttpWebRequest)
<span style="color:rgb(0,0,255)">Dim</span> response <span style="color:rgb(0,0,255)">As</span> HttpWebResponse = <span style="color:rgb(0,0,255)">DirectCast</span>(request.GetResponse(), HttpWebResponse)
<span style="color:rgb(0,0,255)">Dim</span> stream <span style="color:rgb(0,0,255)">As</span> StreamReader = <span style="color:rgb(0,0,255)">New</span> StreamReader(response.GetResponseStream(), Encoding.ASCII)
context.Response.Write(stream.ReadToEnd())</pre><a href="http://11011.net/software/vspaste"></a>
<p>Here we go:
<p><a href="http://blu1.storage.msn.com/y1pgaVuGim1rV2WqtVZvuhblMRZnXeLl0PmH3eMYDDgpH4V-IG9hxSWlxO4PdTg-aLSfyOYqLYLx2wHC8Gj7_bTv0OHoQ7DGgGb"><img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" alt=13-small src="http://blu1.storage.msn.com/y1pgaVuGim1rV3URW7ugFQIXFibZiApaq4PEfh1sP6ZUY-dNGOOgo76YiAgAz6NS5XCD6983Hfd6sMl_QFmoraArIBm2O9im IJd" border=0></a>*
<p>You can preview and download the complete source code <a href="http://mappointemea.members.winisp.net/Collections/Default.aspx">here</a>.
<div style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px">Technorati Tags: <a href="http://technorati.com/tags/Virtual Earth" rel=tag>Virtual Earth</a>, <a href="http://technorati.com/tags/Live Search Maps" rel=tag>Live Search Maps</a>, <a href="http://technorati.com/tags/Collection" rel=tag>Collection</a>, <a href="http://technorati.com/tags/GeoRSS" rel=tag>GeoRSS</a>, <a href="http://technorati.com/tags/VEShapeLayer" rel=tag>VEShapeLayer</a></div></a><img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4819404664324524694&page=RSS%3a+How+to+bring+your+own+content+to+Virtu al+Earth+(Part+3)&referrer=" width="1px" height="1px" border="0" alt=""><img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&NA=1149&PI=88469&RF=&DI=3919&PS=85545&TP=johanneskebeck.spaces.live.com>1=JohannesKebeck">
Click here to view the article. (http://JohannesKebeck.spaces.live.com/Blog/cns!42E1F70205EC8A96!1817.entry)