Right around the new year, I was playing with a simple app that placed pictures from 2006 travels onto a Virtual Earth map, and mentioned that I implemented the app using Script#. I've just published build 0.2.2.0 of script# which includes this functionality. I got a few emails and a comment asking for that, and I thought a dedicated blog post was called for in order to introduce it.
Here's a very quick overview of using the API. When you install the latest build, there is a new assembly that will be installed - ssve4.dll. You'll need to reference this assembly in your project; it contains metadata representing the v4 map control from Virtual Earth in the System.VirtualEarth namespace. The corresponding script file is ssve4.js. Right now this includes the v4 map control, as well as a handful of name mappings (from VEMap to Map, VELatLong to MapLocation and so on ... basically some friendlier type names corresponding to the names of the metadata classes in the assembly).
Basically, for my simple Hello World application, I want to load the map, center it around Seattle to start with, and a pushpin pointing at Seattle.
Here is the simple HTML I am going to use:
<style>
body {
margin: 10px !important;
background-color: black; color: white;
}
#mapFrame {
width: 400px; height: 400px;
padding: 4px;
background-color: white; color: black;
}
</style>
...
<div id="mapFrame">
<div id="mapContainer" style="position: relative; width: 100%; height: 100%">
<img src="Loading.gif" alt="" align="absmiddle" />
<span id="loadingLabel">Loading...</span>
</div>
</div>
<label id="locationLabel"></label>
I ran into some gotchas with Virtual Earth. I found I needed an inline style on the mapContainer <div>, otherwise weird things would happen in Firefox. Secondly Virtual Earth automatically sets margins of your document to 0px (ouch...), so if you care about them, you need to include the CSS style for <body> as shown above. Hopefully these will be fixed in a future release. Finally, the samples, don't show this, but I was successful putting some default content within the mapContainer <div> to serve as loading progress text, which is nice and simple mechanism to indicate activity. It simply goes away, once Virtual Earth has loaded, and starts displaying map image tiles.
OK, now to write some client code-behind for this page.
using System;
using System.DHTML;
using System.VirtualEarth;
public class MapApplication {
private Map _map;
private MapApplication() {
DOMElement mapContainer = Document.GetElementById("mapContainer");
_map = new Map(mapContainer.ID);
MapLocation seattleLocation = new MapLocation(47.6024592954631, -122.32727050781253);
_map.LoadMap(seattleLocation, /* zoomLevel */ 10);
MapPushpin seattlePushpin =
new MapPushpin("seattlePushpin", seattleLocation, null, "Seattle", "Downtown Seattle");
_map.AddPushpin(seattlePushpin);
}
public static void Main(Dictionary args) {
MapApplication app = new MapApplication();
}
}
Now say you want to track the center of the map and display the coordinates, as the user pans around or zooms in and out of the map. The map control provides an event called "onchangeview" that your app code can subscribe to.
_map.AttachEvent(MapEvent.onchangeview, OnMapChangeView);
Couple interesting things to note in this simple line of code. Script# automatically creates a delegate when you reference a member method such as OnMapChangeView. Secondly, in reality the script API takes in strings to identify events. However the Script# compiler allows you to program using named enums, which are converted to strings at runtime, so there is no overhead for enums, and at the same time, it helps ensure you don't run into typos that end up causing runtime errors. Anyway, to finish up the sample, here is the implementation of the event handler itself.
private void OnMapChangeView(MapEventArgs e) {
DOMElement locationLabel = Document.GetElementById("locationLabel");
locationLabel.InnerHTML = "The map is centered at " +
e.View.LatLong.Latitude + ", " + e.View.LatLong.Longitude;
}
The samples available with Script# include a new sample page, map.aspx which demonstrates this functionality. You can run the sample to see the generated JavaScript. There aren't any surprises or magic there... it is what you'd expect.
A bit more about ssve4.dll... basically this is an assembly with stub types and methods. They simply represent metadata for the existing map control APIs, without adding any additional layers of abstraction. They're there to allow you to program in C#, get intellisense, and let the compiler do its job. Your code gets compiled into JavaScript that works directly against the map control APIs. As a result, you should be able to follow the samples and reference documentation associated with the map control SDK, as well as any examples on using Virtual Earth on the Web. The one thing I changed was the names of the types - I used the "Map" prefix instead of the "VE" prefix, given the latter felt odd when the types were already in the System.VirtualEarth namespace.
Hopefully this was useful.
Posted on Tuesday, 1/9/2007 @ 11:59 PM
| #
Script#