This is the fifth article I have written on a technique to add high performance shape rendering to the Virtual Earth map control. Every article has been an evolution introducing new technologies, extending the functionality and optimising the algorithm. Although dated if you are interested in the history of the concept please read the previous articles:
- Clustering a million points on Virtual Earth using AJAX and .Net
- Clustering Virtual Earth with MS AJAX and C#
- Clustering Virtual Earth Version 5
- Clustering Virtual Earth 6. Performance, throttling and PNG icons
Today we look at implementing the logic into the newly released Virtual Earth ASP.NET control. This control is perfect for server centric operations and, as you will see, works exceptionally well with the server side clustering.
Pins (VEShape.Pushpin) rendered on Virtual Earth are <div> elements with attached events. Your browser can only render so many of these quickly and before it slows down the whole experience. I tend to see this as about 200 pins, but it clearly depends upon your computer’s performance and browser of choice. Where pins overlap, although this may give an appropriate visualisation, the elements themselves become impossible to select individually. Throughout my articles I propose that you do not render overlapping pins at all. additionally you only render what is currently visible for the current map view. This simple combination will allow all elements to be selectable and typically reduces the number of pins to an acceptable level.
Visually we can style this clusters in many different ways. A cluster icon may look like a bunch of pins or it may change size and opacity to reflect the quantity it represents. This rendering of the attending MVP’s to the Microsoft summit in April shows one such example of giving accurate density of thousands of pins while only needing to render a few:
The algorithm I designed is far from perfect but does something that a simple grid algorithm cannot, it always represents an actual location. The algorithm loops through visible locations, takes an actual location and merges any overlapping pins into that cluster. By ordering the locations it does this with as few compares as possible. A simple grid algorithm is faster but snaps actual locations to a grid, the result looks very artificial. More advanced clustering concepts have known locations, such as major cities, and snap pins to these. Unfortunately at this stage there is no simple data source within Virtual Earth for this.
Introduction to the VE ASP.NET control
I highly recommend you have a look at these eight videos that cover the installation and basic concepts of the ASP.NET control:
In our first example we will connect up our simple database of Australian Postcodes using the Clustering algorithm to the VE ASP.NET control. Along the way I explain some of the finer points of the code.
As always the full source code can be downloaded from here.
Clustering Enhanced Roll Overs (EROs)
Its not much good to just have the pins on the map if you can’t see the data under them. In this second example we enhance our clustered pins to show an ERO. It would be against our performance focused to code to pass all the data needed for the pins tot he client. Instead we store only the bounds the cluster represents. This is our unique key that lets us retrieve the actual data on demand.
Again the full source code can be downloaded from here.
I hope you enjoy these videos and get a sense of just how powerful and easy to use the VE ASP.NET control really is.
Connecting to a Database
To make this example really simple to download and execute I use an XML file. In practice you will most commonly replace this with a database. I highly recommend using LINQ to query the database for points with the bounds. You should not need to cache any data (although for ultra high performance you will but I’ll cover this in the future). If you would like to see an example of this please let me know.
Hey can I do this in VB.NET?
Of coarse you can! This is an awesome tool to convert C# code into VB.NET: