Click here to Skip to main content
Click here to Skip to main content

Virtual Earth Media Center Add-in

, 5 Jan 2006
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Sean McLeod
Web Developer
South Africa South Africa
Software developer.

Comments and Discussions

 
GeneralFix for modern virtual earth Pinmemberrwagnon31-Dec-09 13:29 
QuestionCan this work with Extenders (Xbox 360)?? PinmemberATSdave30-Apr-06 4:24 
AnswerRe: Can this work with Extenders (Xbox 360)?? PinmemberSean McLeod30-Apr-06 5:21 
GeneralRe: Can this work with Extenders (Xbox 360)?? PinmemberATSdave23-May-06 8:11 
Generalmce 2004 Pinmembercecret20-Apr-06 20:28 
GeneralOperational Problem Pinmemberkborg25-Mar-06 15:27 
GeneralRe: Operational Problem PinmemberSean McLeod29-Mar-06 7:36 
GeneralRe: Operational Problem PinmemberSean McLeod10-Apr-06 20:01 
GeneralGreat App Pinmemberaleest15-Mar-06 12:10 
GeneralRe: Great App PinmemberSean McLeod15-Mar-06 19:37 
GeneralRe: Great App Pinmemberaleest16-Mar-06 2:48 
GeneralGreat App Pinmemberaleest15-Mar-06 9:25 
GeneralWhere is the download PinmemberMatt G10-Nov-05 16:47 
GeneralRe: Where is the download PinmemberSean McLeod10-Nov-05 18:12 
GeneralHain Very Nice PinmemberThatsAlok9-Nov-05 18:18 
GeneralSample implementation Pinmemberbevpet9-Nov-05 16:10 
GeneralRe: Sample implementation PinmemberSean McLeod9-Nov-05 19:34 
GeneralRe: Sample implementation PinmemberSean McLeod10-Nov-05 18:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 6 Jan 2006
Article Copyright 2005 by Sean McLeod
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid