Thursday, 23 August 2007

"Moon"light - Silverlight and moontiles

Turns out the lat-long algorithm works on the moon too!

The Apollo landing co-ordinates on were mapped in the Silverlight TileClient straight from JSON...
var landings = eval('['
+' {"Name":"Apollo11","Y":0.67, "X":23.49}'
+',{"Name":"Apollo12","Y":-3.20, "X":-23.38}'
+',{"Name":"Apollo14","Y":-3.67, "X":-17.47}'
+',{"Name":"Apollo15","Y":26.10, "X":3.65}'
+',{"Name":"Apollo16","Y":-8.99, "X":15.52}'
+',{"Name":"Apollo17","Y":20.16, "X":30.77}'

Here are the points, mapped with yesterday's Javascript function CoordinateFromLongLat() and overlaid on the 'real' 
The JSON is injected into the Silverlight Canvas using CreateFromXaml() method,

var plugin = document.getElementById("SilverlightControl");// landings is the JSON arrayvar coord = CoordinateFromLongLat(landings[0], world);var xaml = flagXaml (landings[0].Name, coord.X, coord.Y);var xamlC = plugin.content.createFromXaml(xaml); canvas.children.add(xamlC);

Where the Silverlight plugin was instantiated like this:

Silverlight.createObjectEx({ source: 'TileClient.xaml', parentElement: document.getElementById("SilverlightControlHost"), id:'SilverlightControl', 

I mention that because most of the samples discussing CreateFromSilverlight() expect the call to come from an event handler, where the sender argument has the getHost() method available.

UPDATE 28/8: the Silverlight-moontile client now zooms in and out (but no panning yet...)

Wednesday, 22 August 2007

Lat/Long to pixel conversion (for Silverlight, in Javascript)

Greg Schechter's Silverlight 1.1 VirtualEarth Viewer is a very cool sample (ot: as is tafiti Silverlight search interface, which I just came across today).

However the VirtualEarth Viewer is written for Silverlight 1.1, and I want to be able to display & animate maps in Silverlight 1.0. Hence the work on a custom TileClient for Silverlight - the most recent sample of which uses a few lines of Greg's codes (converted from C# to Javascript) to dynamically translate screen coordinates to latitude/longitude values (and vice versa)

See it in action here, and check out the ported code below.

/* Original Author
License */
function RadiansToDegrees (rad)
return (rad / Math.PI * 180.0);
function DegreesToRadians (deg)
return (deg * Math.PI / 180.0);
/* SLVirtualEarthViewer */
// Extent maps to +-180 for Longitude and +-85 for Latitude
function LongLatFromCoordinate (coordinate, worldRect)
var x = ((coordinate.X - worldRect.Left) * 360.0 / worldRect.Width) - 180.0;
var y = RadiansToDegrees (2 * Math.atan(Math.exp(Math.PI * (1.0 - 2.0 * (coordinate.Y - worldRect.Top) / worldRect.Height))) - Math.PI * 0.5);
var point = eval('({"X":'+x+', "Y":'+y+'})');
return point;
function CoordinateFromLongLat (longLat, worldRect)
var coordinate = eval('({"X":0, "Y":0})');
coordinate.X = worldRect.Left + (longLat.X + 180.0) * worldRect.Width / 360.0;
coordinate.Y = worldRect.Top + (worldRect.Width * 0.5) * (1 - (Math.log(Math.tan(DegreesToRadians(longLat.Y) * 0.5 + Math.PI * 0.25))) / Math.PI);
return coordinate;

And to use it...

var world = eval('({"Left":0, "Top":0, "Width":512, "Height":512})');
/* wired up to Silverlight event */
function onMouseMove (sender, mouseEventArgs)
var currX = mouseEventArgs.getPosition(null).x;
var currY = mouseEventArgs.getPosition(null).y;
var coo = eval('({"Y":'+currY+', "X":'+currX+'})');

var ll= LongLatFromCoordinate(coo, world);
document.getElementById('output').innerHTML = 'Lat/long: ' + ll.X + ', ' + ll.Y;

var coord = CoordinateFromLongLat(ll, world);
document.getElementById('output').innerHTML += '

Screen: ' + coord.X + ', ' + coord.Y;

Now to hook this up with a conversion to Virtual Earth image tile 'quadkey' values...

p.s. if you are interested in a slightly different version of the lat/long-coordinate conversion, download the sample code for Roll Your Own Tile Server and examine the XToLongitudeAtZoom() and YToLatitudeAtZoom() javascript functions. It's also a very cool sample.

Monday, 20 August 2007

Silverlight map 'saga' continues

After posting about my Silverlight/Virtual Earth overlay on RaceReplay and my plans for a Silverlight VirtualEarth viewer on codeplex, I got a friendly message from Microsoft about using the Virtual Earth tile servers "outside of the terms of service".

I figured it would be 'more responsible' to ensure that the Tile Client at least supported the Virtual Earth logo & copyright details, so I spent a bit of time working on displaying the correct copyright notice in Silverlight - the goal being that the Silverlight client would be indistinguishable from the "real thing".

Turns out Greg Shechter from Microsoft has come up with a similar concept (it's pretty obvious, after all) - a Virtual Earth Viewer (but using Silverlight 1.1, not 1.0)... (screenshot below)

It's a pretty cool sample - but even he didn't bother with the copyright; and it seems like a double-standard for MS to 'ask' me about accessing the tile images directly while at the same time releasing demo/samples that do exactly the same thing! Particularly since Greg's stuff actually works whereas my posts consist of a 4-tile proof-of-concept and a pile of ideas...

Thursday, 16 August 2007

Try doing THIS with javascript-driven maps

OK, I'm still working on getting the tile-grid 'working' beyond a simple 2x2 fixed quadkey BUT that doesn't mean we can't play around with the display capabilities of a Silverlight-hosted map control.

No, there's no business application per-se for randomly animating, zooming and translating the map tiles like this, but it looks cool (view larger image)

[OT] BTW, apparently there are some element names that "just don't work", this being one of them: <Storyboard x:Name="TimelineTranslate" RepeatBehavior="1x">. Had me confused for a minute when a SILVERLIGHT ERROR "TimelineTranslate has no properties" was thrown - but a simple name change and the animation worked.

Wednesday, 15 August 2007

Virtual Earth custom tile client (in Silverlight)

While works "acceptably" overlaying Silverlight and Virtual Earth to visualize animated/map data, it would be even better (smoother, easier to synchronize) if there was a Virtual Earth client in Silverlight, rather like this Flash map client for Yahoo Maps.

So, using tips from these instructions on
rolling your own tile server here is a first attempt at a Silverlight Virtual Earth Tile Client. I could post the source code - but as with all Silverlight 1.0 stuff, it's right there on the page!

The real question is - how much work to get from here to something that actually works?

Monday, 13 August 2007

Map-a-likes: where to map your running routes

Rundown of interactive mapping sites I've come across, primarily for mapping running (or other exercise) track data using either Google Earth or Microsoft Virtual Earth/Live Maps... (no, I haven't seen one using Yahoo Maps yet). Some require you to draw/trace the route, others allow upload of GPX, KML or other GPS-format data.

Includes MapMyRun, MapMyRide and MapMyTri. Uses Google Maps to draw routes, enter training data and search for others. Imports Gpx and from gmap-pedometer. Exports to Kmz. 5 star favourite.

The original (as far as I'm concerned) - if there was a site around before this one, I didn't find it.

Focussed on GPS data integration using Google Earth maps - since I don't have any toys, haven't really used it. Apparently has lots of 'analysis' features for your data & fitness.

Uses Microsoft Virtual Earth. Exports to Gpx and Kml.

Not so much a website, but a piece of software to manage maps (see NYC below)

ninemsn's rip-off site
Rip-off of my favourite site (above) at - slow maps and pretty basic functionality.
In German, but you get the idea...
Great URL but seems relatively new (ie. very few runs in the database)... uses Google Maps.

and for watching only

Tour de France map - the BBC always does great stuff on the web.

New York City Marathon
NYC marathon simlator requires Java, and provided by Sportsim (who have open-sourced their software as CompareTracks - see above).

...and "sorta" related
RunPix doesn't have an interactive map, but does do 'race statistics visualization', including a static map of where you were on the course when the leaders finished.

Thursday, 9 August 2007

RaceReplay 'RC1' (now with Silverlight & Virtual Earth) release 3 is now live:The Designer will be mortified that I've munged the beautiful work he did by adding those dodgy arrows, but I'm sure you'll agree it's a big improvement!

Tuesday, 7 August 2007

When non-runners strike...

This is what happens when a "non-runner" publishes a race map on the web... That's a big jump off the Cahill Expressway onto Macquarie Street, guys.

Who would do such a thing? It's ninemsn's new "mapmyfitness" site, with a blatant ripoff (even the name!) of a better established, better written US-based site

Too bad the ninemsn site is slow as a wet-week - I "think"' they've missed the point about JSON being light-weight
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
or, if you preferred:
{"Title":"Edit Layer"
Okay okay, I'm being harsh - maybe it's generated output from astoria - but the maps are slow to navigate. I wonder how the sponsor "Kellogg's Special K" feels about it - maybe they should go back to ninemsn to get it sped up (and maybe the map resized?)

Road view - big jump!Satellite view - big jump!

It's certainly no "RaceReplay" :)

Wednesday, 1 August 2007

Silverlight 1.0 RC - bug fixed!

Yes, RC1 of Silverlight 1.0 has been released (in case you missed the announcements).

Thankfully the breaking changes haven't really affected the stuff I've been playing with - it's been a fairly painless change to swap in the updated Silverlight.js file and tweak the createSilverlight() function (Sys.* has been removed - shouldn't clash with ASP.NET AJAX now):
source: 'Scene.xaml',
parentElement: document.getElementById("SilverlightControlHost"),
onError:null, onLoad:null, onResize:null
What's even better is that it fixes the bug on this 400-element animation. The beta used to just 'freeze' about two-thirds of the way through the animation: all the dots stopped moving until the timeline 'finished', then they'd all disappear (jump straight to end). Now it works seemlessly - time to try it with more animated objects!