Sunday, December 27, 2009

Google Street View And Google Maps Interaction - Sample Showcase

Hi,

Recently, I wanted to learn more about the Google Street View API objects. So I decided to create a small application. While there, I thought it would be great to integrate a Google Map with a draggable marker for the two to interact together.

The Demo


So here it is, my small sample. It is 100% Google Maps API JavaScript with no jQuery involved. You would be surprised how many functions are available in the native Maps API that are duplicated by jQuery (assuming you're using jQuery only for Google Maps in your webpages). Maybe I'll create a blog post regarding this. Anyways, don't forget, the marker is draggable so you can navigate through the streets pretty quickly:

(All the code and the documentation are available below)




<div id="mapcanva" style="width:400px; height:250px;"></div>
<div id="streetcanva" style="width:400px; height:250px;"></div>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&hl=en&v=2&key=your-api-key&sensor=false"></script>
<script type="text/javascript">
    // Instead of handling events directly in the tags
    // attributes (ie. <body onload="...">), I prefer
    // listening to the events programmatically like:
    GEvent.addDomListener(window, 'load', Initialize);
    GEvent.addDomListener(window, 'unload', GUnload);
    
    var map;    // This will be our map instance
    var center; // This is a GLatLng representing the initial
                // position of the map
    var marker; // The one and only draggable marker
    var pano;   // The street view object

    // This function is called when the page has loaded.
    // see above, the GEvent.addDomListener(...) call.
    // What it does, it simply creates the map then creates
    // the street view.
    function Initialize() {
        InitializeMap();
        InitializeStreetView();
    }

    // This function is used to create the map.
    // It is called by Initialize() on the page load.
    function InitializeMap() {
        // Create a map instance
        map = new GMap2(document.getElementById('mapcanva'));
        // Create the center point the map will be initialized with
        center = new GLatLng(45.5, -73.5771);
        // Our draggable marker
        marker = new GMarker(center, { draggable: true });
        
        // Initialize the map
        map.setCenter(center, 15);
        map.setUIToDefault();
        map.addOverlay(marker);

        // Listen to the 'dragend' event of the marker.
        // Each time the user will drag the marker, the
        // function 'OnMarkerDragged' will be called receiving
        // the longitude and latitude of the marker's new
        // position
        GEvent.addListener(marker, 'dragend', OnMarkerDragged);
    }

    // This function is used to create the street view viewport.
    // It is called by Initialize() on the page load, after the map.
    function InitializeStreetView() {
        // This sets some options
        var options = { latlng: center, pov: { yaw: 180, pitch: 0} };
        pano = new GStreetviewPanorama(document.getElementById('streetcanva'), options);

        // Listen to the 'initialized' event of the street view.
        // This event occurs every time a new panorama is initialized
        // in the street view viewport.
        // 'OnStreetViewChanged' will be called and will receive a
        // 'GStreetviewLocation' object so we can have the location
        // of the current panorama.
        GEvent.addListener(pano, 'initialized', OnStreetViewChanged);
        
        // Error handling, in case the user don't have the flash player
        GEvent.addListener(pano, 'error', OnStreetViewError);
    }

    // This function is called when the marker has been dragged
    // (See InitializeMap())
    function OnMarkerDragged(loc) {
        // The map's marker have a new location, synchronize street view also
        pano.setLocationAndPOV(loc);
        // Re-center the map according to the marker's position
        map.panTo(loc);
    }

    // This function is called when the street view have changed
    // (See InitializeStreetView())
    function OnStreetViewChanged(loc) {
        // Update the marker's position according to the
        // street view position
        marker.setPoint(loc.latlng);
        // Re-center the map according to the marker's position
        map.panTo(loc.latlng);
    }

    // Error handling function, in case the user doesn't have the
    // flash player installed
    function OnStreetViewError(errCode) {
        if (errCode == 603) {
            alert('flash is required');
        }
    }
</script>

That's it, I hope you liked it. Don't forget to add a comment to showcase your own Street View application.

I'm putting time and effort on this blog and having you here is my reward. Make me feel better and better everyday by spreading the love with the buttons below! Also, don't hesitate to leave a comment. Thanks for reading!

Related Articles



See ya

8 comments:

Anonymous Avatar Anonymous said...

Nice Job Mike, an interesting challenge would be to have a marker which would indicate the POV as well. I have seen panoramic photo viewers with this feature, but I don't think a rotating marker in Google Maps. Thanks again for the well commented code.

James

Unknown said...

Hi, thanks for the comments...

What you can do for the marker to show the current POV is the following:

1) Create 8 arrows (icons) pointing in each 45 degrees around the circle.

2) Listen to an event that is triggered when the POV changes.

3) Take the current POV and determine the proper arrow to show with this formula: Round(POV / 45) = The arrow number.

Example: 275/45 = 6.11 = 6 (Image 6)

4) Call GMarker::setImage(url:String) to change the marker with the proper icon found previously.

You'll have to pay attention for the arrows to be pointing in the right directions but it shouldn't be that difficult.

I'll maybe try it sometimes :)

Thanks for reading!

Anonymous Avatar Anonymous said...

Hi Mike, I modified my map/pano to use your features. When it is done, I will send you a link.

Since I wrote my post above, I did a bit of reading on adding direction UI to the map marker. There are several solutions, change icon image, rotate image within CANVAS (HTML 5), and an interesting demo that looks like Radar. It is animated and would be a more accurate reflection of the view angle:

http://maps.forum.nu/gm_radar.html

There was also some demos on rotating the mini-map so the it had the same yaw as the Pano. Here is a demo, but it was broken?

http://cheeaun.github.com/streetview-fun/

It will be interesting when HTML 5 is more main stream...

James

Ajo said...

This was a really great example but i'm having a weird issue. I copied your example exactly but moved the javascript into a separate file and the referenced it in a static html file.

When you open the html file directly everything works fine, but when i serve it up from my local tomcat server the street view images dont change when you move the marker. (when u first load the page the streetview renders fine, its only problematic when u move the marker).

Note: i did not make any changes to your example.

Any ideas? is this something to do with cross site scripting?

Anonymous Avatar Anonymous said...

This is an extremely well done sample. I've been trying to do the same thing; however, when I run this on my machine it doesn't work (just like my code). I'm trying to step through using firebug but nothing is popping out.

To a newbie ... is there any reason why copying the above local, saving to an html file then opening in IE won't work? (By won't work I mean when I move the marker, SV is not updating).

Jess

Anonymous Avatar Anonymous said...

Sorry ... realized the problem.

I embarassingly was storing all my code in folder on my desktop. I tried to use that folder as virtual directory, got security errors so went to new folder in root C. Still didn't work if I opened up file without IIS, but now does if I go through localhost. Just weird that the maps and street view were working fine before and just the call to setLocationAndPov wouldn't work.

Jess

Unknown said...

Hi,

I just found out the problem...

You must run the sample from a Web Server (local or not).

I think google doesn't allow calls from local pages outside a web server.

I've been able to reproduce the problem. Try to install IIS (assuming windows) via "Add/Remove programs --> Windows Components".

Thanks for the comments, it's really appreciated.

Mike

Unknown said...

Hehe no biggy, I didn't knew it myself :)

©2009-2011 Mike Gleason jr Couturier All Rights Reserved