Subscribe Now: Feed Icon

Tuesday, July 12, 2011

Silverlight: Adding Google Streets View

While in drafting stage this post was originally called “ArcGIS Silverlight API: Adding Google Streets” but the only thing ArcGIS Silverlight API adds to the mix is the extraction of the coordinates from the map. For a regular Silverlight application just pass the coordinates from another source. For a version with Google Map API V3 see part 2.

My team leader asked me to try and add Google Street View to our map (that uses ArcGIS Silverlight API). The idea that he wanted me to look at was simple: when the user right-clicks on the map a new window will open with Google Street View. There was just a minor problem with this – Israel doesn’t have a Google Street View yet and our development environment is using the map of Israel .

But it was minor because I just downloaded ESRI’s Interactive Samples and worked on those. I decided to work on the simplest of the samples – Mapping –> ArcGIS Tiled Layer:


(for a live demo of the sample click here)

The code is in ArcGISSilverlightSDK\Map\Map.xaml and just contains:

  1. <UserControl x:Class="ArcGISSilverlightSDK.Map"
  2.     xmlns=""
  3.     xmlns:x=""
  4.     xmlns:esri="">
  5.     <Grid x:Name="LayoutRoot" >
  7.                     <esri:Map x:Name="MyMap">
  8.             <esri:ArcGISTiledMapServiceLayer ID="MyLayer"
  9.                 Url="" />
  10.         </esri:Map>
  12.     </Grid>
  13. </UserControl>

End result:


(that after clicking on London)

Most of the code here uses a sample I found here (it’s not in English, without explanations, but it’s mostly code so I managed).


Changes to the html/aspx file:

  1. <body>
  2.     <div id="DllShepherd_GoogleStreetViewContainer" style="position:absolute;z-index:10;bottom:0px;right:0px; height: 325px; width: 300px;background-color:#888888;display:none;">
  3.         <input type="button" style="position:relative;z-index:1000;height: 25px; width: 60px;left:180px;top:5px"
  4.         value="Close" onclick="document.getElementById('DllShepherd_GoogleStreetViewContainer').style.display='none';"/>
  5.         <div id="DllShepherd_GoogleStreetviewObject" style="position:relative;height: 290px; width: 290px;left:5px;top:5px"></div>
  6.     </div>
  7.     <form id="form2" runat="server" style="height:100%">
  8.     <div id="silverlightControlHost">
  9.         <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
  10.           <param name="source" value="ClientBin/DllShepherd.SilverlightGoogleMaps.xap"/>
  11.           <param name="onError" value="onSilverlightError" />
  12.           <param name="background" value="white" />
  13.           <param name="minRuntimeVersion" value="4.0.50826.0" />
  14.           <param name="autoUpgrade" value="true" />
  15.                 <param name="windowless" value="true" />
  16.                      <asp:Literal ID="ParamInitParams" runat= "server"></asp:Literal>
  17.           <a href="" style="text-decoration:none">
  18.               <img src="" alt="Get Microsoft Silverlight" style="border-style:none"/>
  19.           </a>
  20.         </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
  21.     </form>
  22. </body>
  23. </html>

(the sample used JavaScript to dynamically create multiply Google Street View containers, I only need one)

Added the GoogleStreeViewContainer and the most important part is this change to the Silverlight object:

  1. <param name="windowless" value="true" />

Without it the Silverlight object will always be on top (took me a few hours since the original sample was with the Silverlight asp control).


  1. <script src=";v=2&amp;key=YourGoogleApiKey" type="text/javascript"></script>
  2. <script src="" type="text/javascript"></script>
  3. <script type="text/javascript">
  4.     $(document).ready(function () {
  5.         pan = new GStreetviewPanorama(document.getElementById("DllShepherd_GoogleStreetviewObject"));
  6.         GEvent.addListener(pan, "error", StreetViewError);
  7.     });
  9.     var pan;
  11.     //Edited original sample (simplified)
  12.     function streetView(lat, lon) {
  14.         var latlng = new GLatLng(lat, lon);
  15.         var svp = new GStreetviewClient();
  16.         svp.getNearestPanoramaLatLng(latlng,
  17.              function (newPoint) {
  18.                  if (newPoint == null) {
  19.                      //Street View Not Available For This Location (alerts just annoy me)
  20.                      return;
  21.                  }
  22.                  document.getElementById("DllShepherd_GoogleStreetViewContainer").style.display = 'block';
  23.                  panoramaOptions = { latlng: newPoint };
  24.                  var myPov = { yaw: 180, pitch: 0 };
  25.                  pan.setLocationAndPOV(latlng, myPov);
  27.              });
  28.     }
  30.     //Taken from sample
  31.     function StreetViewError(errorCode) {
  32.         if (errorCode == 603) {
  33.             alert("Error: Flash doesn't appear to be supported by your browser");
  34.             return;
  35.         }
  36.         if (errorCode == 600) {
  37.             alert("Street View Not Available For This Location");
  38.             return;
  39.         }
  40.     }
  41. </script>

Added some JavaScript that adds the flash object to the Div tag GoogleStreeViewObject.

Be sure to change the Google Map API Key (YourGoogleApiKey) in:

  1. <script src=";v=2&amp;key=YourGoogleApiKey"

Without the API key the only place this site will work will be in localhost. The key is domain specific but the FAQ provides a way to concatenate several API keys.

You can get a key from Google Map API V2 site. Before registering be sure to read this FAQ first, will help you in choosing the best base site so that all the sub domains will be valid.


From the Silverlight application calling the JavaScript function StreetView:

  1. private void MyMap_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
  2. {
  3.     var p = e.MapPoint;
  4.     HtmlPage.Window.Invoke("streetView", p.Y, p.X);
  5. }

(in a general Silverlight application just pass the coordinate here)

Since it’s a simple sample I just changed the map’s url and added a code behind mouse click event. The reason I changed the map is that Google Street View expects a spatial reference of Geographic WGS84 (see my other post Geographic Coordinates Systems) which the original map didn’t have (in a real application you will either use this coordinate or will have to convert the coordinates).

  1. <esri:Map x:Name="MyMap" MouseClick="MyMap_MouseClick">            
  2.     <esri:ArcGISTiledMapServiceLayer ID="MyLayer"
  3.         Url="" />
  4. </esri:Map>


And that’s it.

Code sample can be found in my CodePlex Project, or directly here.


Edit: Added a part on the Google Map API v2 Key.

Edit (13/09/2011): Fixed Firefox bug in JavaScript

Continued in part 2.



Geocoding & StreetView Google per ESRI API Silverlight – not in English but it’s mostly code…

ESRI’s Interactive Samples


Keywords: ESRI, Silverlight, Map, Google Street View