Recently I took my week end to found out what Virtual earth can do, as I have such an experience using MapInfo MapX (now MapXtreme) for couples of my old projects, for some reason I figure it out that might be interesting if I can combine VE and Silverlight.
In my sample here, I'll show you how we can easily create lines in Virtual Earth and silverlight application will following the lines, just like a route.
Click here to see how it run.
(*) Note If you are using IE8 beta, you should click Toggle with IE 7 Emulation mode.
If you interesting about virtual earth just go to http://dev.live.com/virtualearth/sdk/ and you'll find interactive sample that live.com provide to learn it fast.
In this sample the I'm requesting VE to load map of Jakarta and show Monas at center of the map, the code is quite simple using javascript :
- provide the location latitude and longitude as center of the map using VELatLong
- how many zoom that you preferred ?
- gave a type of map you wanted , a for 'aerial' , r for 'road'
function GetMap()
{
map = new VEMap('myMap');
map.LoadMap(new VELatLong(-6.17605430, 106.82762146), 15 ,'a' ,false);
}
and the result below
Stacking Silverlight with Virtual Earth, and Create Silverlight Transparently
Cause silverlight will run on the top of VE , we have to make silverlight component position on top VE component.
<div id='myMap' style="position:relative; width:640px; height:480px">
</div>
<!-- Silverlight Component -->
<div id="silverlightControlHost">
<object id="silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="640px" height="480px"
style="position: absolute; z-index:100; top:0px; left: 0px;">
<param name="background" value="Transparent" />
<param name="windowless" value="True" />
In order to make the silverlight looks transparently, some properties we should changed is background and windowless
- Set background value to Transparent
- Set windowless value to True
In the silverlight XAML make sure usercontrol properties background set to transparent.
Draw Lines On Virtual Earth
We can using VEShape class to drawing shape onto map, currently VE only support three type of Shape, they are : Polygon, Polyline and pushpin.
In here because I like to draw using the mouse, I need to attached mouse event. These function below is tell the map that I'm register on OnmouseDown and OnMouseUp Event on VE, that shall be pointed to my MousehandlerDown and MouseHandlerUp function,
map.AttachEvent("onmousedown",MouseHandlerDown);
map.AttachEvent("onmouseup",MouseHandlerUp);
When the mouseeventdown occurs I setup a couple things they are :
- Get The Position X, Y
- Convert to LatLong
- And Save Position Current Point
// Where We Are
var x = e.mapX;
var y = e.mapY;
// Convert TO VEPixel Class
pixel = new VEPixel(x, y);
// Convert To LatLong
LL = map.PixelToLatLong(pixel);
// Save To Array Collection
collLL.push(LL);
// Is This First Time Click ?
iClick +=1;
// Tell Map We Handle This
return true;
After that on mouseeventUp I called drawlines function to draw the lines.
// Convert To LatLong
var ll1 =convertToLL(val1);
var ll2 =convertToLL(val2);
// Create Polyline Object
var shape = new VEShape(VEShapeType.Polyline, [ ll1, ll2 ]);
// Set Line Color To Red
var mycolor = new VEColor(255, 0, 0, 0.8);
shape.SetLineColor(mycolor);
shape.SetFillColor(new VEColor(0,100,150,0.5));
// Size Of The Width (max 5)
shape.SetLineWidth(3);
// Tell VE that I do not need Icon
shape.HideIcon();
// Add SHape to Map
map.AddShape(shape);
In code above you see that VE provide us rich class and function to manipulate map instanly.
Speaking HTML and Silverlight Managed Code
In order to communicate with silverlight from HTML, I modify App.xaml.cs on mysilvelight application
private void Application_Startup(object sender,StartupEventArgs e)
{
// Load the main control
this.RootVisual = new Page();
HtmlDocument doc = HtmlPage.Document;
HtmlPage.RegisterScriptableObject("mysilver", RootVisual);
}
What actually happen, I'm telling HtmlPage class to register page class representing by rootvisual object as mysilver in HTML page.
In page class I also set "[ScriptableMember()]" attributes so they can safely call by my javascript from HTML. ScriptableMember attributes is part of System.Windows.Browser namespace.
[ScriptableMember()]
public void
AddPoint(double x, double y)
{
_playpts.Add(new Point(x, y));
}
AddPoint function above was called by mouseeventUp event VE from HTML, and saved on _playpts generic List of point.
Play with Animation
In Page.xaml, I added storyboard under usercontrol.resources which basically will play the animation instantly.
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames x:Name="dakX" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" BeginTime="00:00:00">
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames x:Name="dakY" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" BeginTime="00:00:00">
</DoubleAnimationUsingKeyFrames>
</Storyboard>
On sample above, the target name and property is also setup, especially for TargetProperty value, I've define that X and Y will be mark as target. As position will move dynamically, there is a function will generate KeyFrames during runtime, so rectangle object will following keyframes based mousedown event on HTML where the map reside.
private void GenerateKeyFrames()
{
for (int i = 0; i < _playpts.Count -1 ; i++)
{
SplineDoubleKeyFrame newsdkfX = new SplineDoubleKeyFrame();
// Set KeyTime
newsdkfX.SetValue(SplineDoubleKeyFrame.KeyTimeProperty , string.Format("00:00:0{0}",i+1));
// Set Value X Move
newsdkfX.SetValue(SplineDoubleKeyFrame.ValueProperty, _playpts[i + 1].X - _playpts[0].X);
dakX.KeyFrames.Add(newsdkfX);
SplineDoubleKeyFrame newsdkfY = new SplineDoubleKeyFrame();
// Set KeyTime
newsdkfY.SetValue(SplineDoubleKeyFrame.KeyTimeProperty,string.Format("00:00:0{0}", i+1));
// Set Value Y Move
newsdkfY.SetValue(SplineDoubleKeyFrame.ValueProperty, _playpts[i + 1].Y - _playpts[0].Y);
dakY.KeyFrames.Add(newsdkfY);
}
}
After Storyboard acomplished completed of storyboard event will fire to hide the Silvelight host application on HTML page.
HtmlPage.Document.GetElementById("SilverlightHostControl").SetStyleAttribute("visibility", "hidden");
Creating such an application using both VirtualEarth and Silverlight is challenge for me, I'll look more deep to see how their collaboration could create interesting and powerful application.
Regards