Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Virtual Earth Media Center Add-in

0.00/5 (No votes)
5 Jan 2006 1  
Virtual Earth add-in for media center for browsing and viewing geocoded pictures.

Introduction

The 'My Pictures' feature of Microsoft Windows Media Center Edition is probably the most used feature in our household. We have tons of digital photos and have started scanning in most of our slides. Often while viewing a slide show with our friends, they ask from where these particular photos are taken. With a combination of geo-coded digital images and MSN's Virtual Earth web based map control, it is now possible to show them on a map right inside the media center.

A secondary use of Virtual Earth within media center is to use it as a digital atlas for browsing the world:

Implementation

The implementation consists of two main parts. The first is to create a Virtual Earth web page that works well within the media center, which mainly consists of handling the media center remote control keys and mapping them to the relevant Virtual Earth map control methods. The second part is the code to read the latitude and longitude coordinates from an image file.

Basic Virtual Earth page

The Virtual Earth functionality in a browser window is implemented by a client side JavaScript map control object. So in order to host a Virtual Earth map in your own web page all you need to do is add a reference to the JavaScript source file for the map control and then create an instance of the map control.

In the OnPageLoad event we create an instance of the map control object insert it into the body of the web page.

var params = new Object(); 
params.latitude = startLat; 
params.longitude = startLon; 
params.zoomlevel = startZoom; 
params.mapstyle = Msn.VE.MapStyle.Hybrid; 
params.showScaleBar = true; 
params.showDashboard = false; 

map = new Msn.VE.MapControl(document.body, params); 
map.Init();

In the OnRemoteEvent event handler for handling the key press from the media center remote control, I call the following map control methods:

  • ContinuousPan - animated panning option used when the user hits one of the arrow keys on the remote.
  • ZoomIn, ZoomOut - zooms the map in or out by one zoom level when the user hits the channel + or - keys on the remote.
  • SetMapStyle - toggles the map's style between aerial, road and hybrid when the user hits 1, 2 or 3 number keys on the remote.

For more details on using the Virtual Earth map control see the Via Virtual Earth website.

The user can also use the 7, 8 and 9 keys on the remote control to adjust the size of the pan operation. It's useful to have a large pan increment when you're trying to quickly navigate from one side of the globe to another side, and then to have a smaller increment once you've zoomed in on the area of interest and you want to make fine pan adjustments.

Since Virtual Earth was designed for use on regular monitors with the user sitting 2 feet away the text can often be difficult to read on a TV 10 feet away, especially if used on a CRT TV with interlaced flicker, so I've added a local zoom option. The user can toggle between three local zoom factors of 1, 1.2 and 1.5 which will zoom the web page making the text easier to read by using the 4, 5 and 6 keys on the remote control.

We now have a basic Virtual Earth experience that is usable in media center using the remote control while sitting 10 feet away in front of the TV. The final piece to implement is the code to read the latitude and longitude from a selected digital image and then pan the map control to the location the picture was taken with a pushpin displayed on the map.

function onRemoteEvent(keyChar)
{
    switch (keyChar)
    {
        case 38:    // Up button

            map.ContinuousPan(0, -panDelta, 20);
        break;
        case 40:    // Down button

            map.ContinuousPan(0, panDelta, 20);
        break;
        case 37:    // Left button

            map.ContinuousPan(-panDelta, 0, 20);
        break;
        case 39:    // Right button

            map.ContinuousPan(panDelta, 0, 20);
        break;
        case 33:    // Channel+

            map.ZoomIn();
        break;
        case 34:    // Channel-

            map.ZoomOut();
        break;
        case 49:    // 1 button

            map.SetMapStyle(Msn.VE.MapStyle.Aerial);
            window.external.MediaCenter.Dialog("Aerial", 
                                 "Map Style", 1, -1, false);
        break;
        case 50:    // 2 button

            map.SetMapStyle(Msn.VE.MapStyle.Road);
            window.external.MediaCenter.Dialog("Road", 
                                 "Map Style", 1, -1, false);
        break;
        case 51:    // 3 button

            map.SetMapStyle(Msn.VE.MapStyle.Hybrid);
            window.external.MediaCenter.Dialog("Hybrid", 
                                 "Map Style", 1, -1, false);
        break;
        case 52:    // 4 button

            document.body.style.zoom = 1.0;
            window.external.MediaCenter.Dialog("0%", 
                                 "Local Zoom", 1, -1, false);
        break;
        case 53:    // 5 button

            document.body.style.zoom = 1.2;
            window.external.MediaCenter.Dialog("20%", 
                                 "Local Zoom", 1, -1, false);
        break;
        case 54:    // 6 button

            document.body.style.zoom = 1.5;
            window.external.MediaCenter.Dialog("50%", 
                                 "Local Zoom", 1, -1, false);
        break;
        case 55:    // 7 button

            panDelta = 15;
            window.external.MediaCenter.Dialog("Large", 
                                 "Pan Amount", 1, -1, false);
        break;
        case 56:    // 8 button

            panDelta = 7;
            window.external.MediaCenter.Dialog("Medium", 
                                 "Pan Amount", 1, -1, false);
        break;
        case 57:    // 9 button

            panDelta = 3;
            window.external.MediaCenter.Dialog("Small", 
                                 "Pan Amount", 1, -1, false);
        break;
        case 166:    // Back button

            window.external.MediaCenter.CloseApplication();
        break;
    }

    return true;
}

EXIF GPS component

Most people are familiar with the EXIF data like shutter speed, aperture, camera model etc. that digital cameras store as part of the JPEG image. In addition to camera specific settings there are also standard properties for storing GPS data within the EXIF data for things like latitude, longitude, altitude etc.

There are a handful of cameras in the market today having a built-in GPS receiver which allows the camera to store the GPS coordinates whenever a picture is taken. However there are also a number of software programs that allow you to add the GPS coordinates and edit any of the EXIF data after the picture is taken. Most of them allow you to load a GPS track file that you've recorded from a separate GPS receiver and estimate the location of the photo by looking at the timestamp in the EXIF data and finding the nearest GPS track point based on the timestamps of the track points.

If you don't have an associated GPS track file you can always determine the latitude and longitude for a picture via other means and then manually enter the coordinates via an EXIF editor.

Take a look at this page on World Wide Media Exchange website which offers software that perform EXIF edits specifically for location data and lists a number of other software packages that offer similar features. One thing to watch out for is whether the EXIF editing program recompresses the image data while writing the EXIF property values. If it does and you're using a lossy image file format like JPEG then there will be some loss in image quality.

In order to read the EXIF latitude and longitude coordinates I make use of the Image class in GDI+ which has methods to read and write property values stored in the EXIF data. I wrote a simple COM component in C++ to read the latitude and longitude property values via the Image class. The ExifGPSExtractor component is then used on the web page and invoked by JavaScript to retrieve the position data and then pan and center the map to this location. A pushpin is also added to the map at picture's location:

double CExifGPS::GetCoordinate(Image* image, int tag, int reftag)
{
    double coordinate = 0.0;

    unsigned int size = 0;
    PropertyItem* propertyItem = NULL;

    size = image->GetPropertyItemSize(tag);
    if(size > 0)
    {
        propertyItem = (PropertyItem*)malloc(size);
        image->GetPropertyItem(tag, size, propertyItem);

        long* pVals = (long*)(propertyItem->value);

        // Degrees

        coordinate = pVals[0];
        coordinate /= pVals[1];

        // Minutes, either mm/1 or mmmm/100 for decimal minutes

        double minutes = pVals[2];
        minutes /= pVals[3];

        // Seconds, either ss/1 or ssss/100 for decimal seconds

        double seconds = pVals[4];
        seconds /= pVals[5];

        coordinate += minutes / 60.0 + seconds / (60.0 * 60.0);

        free(propertyItem);
    }

    return coordinate * GetReferenceFactor(image, reftag);
}
if(window.external.MediaCenter.MediaContext != null)
{
    if(window.external.MediaCenter.MediaContext.ContextName == "Picture")
    {
        gps.Load(
          window.external.MediaCenter.MediaContext.GetProperty("Name"));
        startLat = gps.Latitude;
        startLon = gps.Longitude;        
        
        if(startLat != 0.0 || startLon != 0.0)
            startZoom = 10;
        else
            window.external.MediaCenter.Dialog("No GPS coordinates found", 
                                                   "No GPS", 1, -1, false);
    }
}

if(startLat != 0.0 || startLon != 0.0)
{
    map.AddPushpin(0, startLat, startLon, 40, 40, "pushpin", "");
}

Using the Virtual Earth Media Center add-in

Download the program package zip file and unzip to a location of your choice, e.g. c:\Program Files\VirtualEarth. Then run Register.cmd which will register the COM component and register the Virtual Earth HTML add-in with media center.

To uninstall make sure you've closed Virtual Earth in media center and then run Unregister.cmd to unregister the COM component the Virtual Earth HTML add-in. Then delete the files.

To use the Virtual Earth add-in as a digital atlas go to 'More Programs' main menu option and select Virtual Earth.

To use the add-in in conjunction with geo-coded pictures navigate to 'My Pictures' main menu and then navigate down to your picture folders. While viewing the thumbnail pictures in a folder, you can select a single picture and then hit the 'i - More Info' remote key. This will bring up a context menu with a 'More�' menu option.

If you have opened a picture in full screen for viewing or if you are busy watching a slide show and want to get the location info for the current picture hit the 'i - More Info' remote key, then select 'Picture Details' from the context menu that appears. Once the picture details page is displayed hit the 'i - More Info' remote key again and select the 'More�' menu option.

A page with a list of available add-ins registered for handling pictures will then be displayed. Select 'Virtual Earth' from the list which will then launch the Virtual Earth web page with the map centered on the location of the picture and a pushpin showing the picture's location on the map.

To Do

I have a couple of additional features in the pipeline:

  • Option to display pushpins for all the photos stored in your media center and as you pan around and zoom the map, offer a slideshow option for all the photos in the current map view.
  • Place name search while using Virtual Earth as a digital atlas.
  • Oblique - "Bird's Eye View" support introduced with the version 2 Virtual Earth control.

Updates

  • HTML file updated to reference and use the new version 2 Virtual Earth control that Microsoft has released. Added a few minor changes to reference the new URL for the JavaScript control and some minor changes on how the control is initialized.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here