If you overlay a location-specific Silverlight
canvas
on a
Live Map (or is it
Virtual Earth?, you'll probably want to 'synchronise' the canvas with the underlying map as it is panned/zoomed.
Although it might seem a tough task, with the help of the
Virtual Earth 5 SDK it's relatively easy.
Firstly, check out
the end result - a Silverlight canvas/animation that zooms and pans with the Live Map underneath it.
To accomplish the effect, I needed to:
0. Load the map and Silverlight controlsmap = new VEMap('myMap');
map.LoadMap(
new VELatLong(-33.865052673579655, 151.22375965118408),
16, VEMapStyle.Hybrid);
//...
Sys.Silverlight.createObject( "xaml/Domain.Xaml", ...
Remembering to set
isWindowless:'true'
and the position of the elements so they float together.
1. Add Scale and Translate Transforms to the canvaslt;Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"
x:Name="canvasScale" />
<TranslateTransform X="0" Y="0"
x:Name="canvasTranslate" Name="canvasTranslate" />
</TransformGroup>
</Canvas.RenderTransform>
(this was the only change required to the Xaml). You will use the x:Names later to make it easy to transform the
canvas
.
2. Determine the lat-long of the canvasSo that you can always position it accurately, regardless of how the map has been panned or zoomed. In this case, the top-left of the
canvas
should be is at 33.858210507117995, 151.2127733230591, and the map center when loaded is -33.865052673579655, 151.22375965118408.
3. Support panningSimply shift the map and canvas by the same pixel delta, eg. simply call the
Pan
function on the
map
object, and modify the named TranslateTransform on the
canvas
.
function MoveNorth()
{
map.Pan(0, -100);
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
//canvasT.X = canvasT.X - 100;
canvasT.Y = canvasT.Y + 100;
}
4. Support zoomingOther than a little bit of hardcoding, the zoom javascript is pretty simple
function ZoomIn()
{
map.ZoomIn();
var zoom = map.GetZoomLevel();
media_scale(zoom);
return false;
}
function media_scale(zoomLevel)
{
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
var canvasS = sl8.content.findName("canvasScale");
var canvasLatLong = new VELatLong(-33.858210507117995, 151.2127733230591);
var canvasPixel = map.LatLongToPixel(canvasLatLong);
canvasT.X = canvasPixel.x;
canvasT.Y = canvasPixel.y;
if (zoomLevel == 17)
{
canvasS.ScaleX = 2;
canvasS.ScaleY = 2;
}
else if (zoomLevel == 16)
{
canvasS.ScaleX = 1;
canvasS.ScaleY = 1;
}
else if (zoomLevel == 15)
{
canvasS.ScaleX = 0.5;
canvasS.ScaleY = 0.5;
}
else if (zoomLevel == 14)
{
canvasS.ScaleX = 0.25;
canvasS.ScaleY = 0.25;
}
else if (zoomLevel == 13)
{
canvasS.ScaleX = 0.125;
canvasS.ScaleY = 0.125;
}
else if (zoomLevel == 12)
{
canvasS.ScaleX = 0.0625;
canvasS.ScaleY = 0.0625;
}
// haven't supported tinier zoom levels - might need to just hide content?
}
As long as your
canvas
and map loaded 'in sync', the panning should work without trouble, and if the top-left lat-long of your
canvas
is set, zooming should work too. Note that the scale-factors will depend on what 'resolution' your original Xaml was drawn in - I was tracing a map at zoom level 16 (as you can see).
There's a lot more you could add to this - including animating the zoom and supporting 'drag' for the canvas and map...