Interactive Mapping Blog

Mapping Solutions News

Archive for the ‘ASP.Net’ Category

5 ways to make your web mapping fly!

Monday, March 28th, 2011

map paper planeOver the past four years here at Earthware we have encountered a number of performance challenges when creating mapping applications on the web. We thought it might be helpful to bring together the 5 most common issues we’ve encountered, both when helping other developers or in some of our older mapping projects.

It’s unfair to call these mistakes, rather they are missed opportunities to make your mapping really fly. They are not exclusively focused on specific mapping API’s or web programming languages / frameworks so they should be applicable to the majority of web mapping applications with a little translation.

So in no particular order:

1. How accurate do you really need to be?

We often come across systems or code samples that both store, but more importantly transfer their position data (usually pairs of lat/lon) to very high levels of decimal places (often 13 or more decimal places). Did you know that 8 decimal places of accuracy is a real world value of 1.11 millimetre (at worst when on the equator). How many systems have you worked on that require you to map to 1.11 millimetre accuracy?

So assuming that for most of us meter accuracy is plenty enough we can reduce our values to only use 5 decimal places (1.11 metre accuracy). When transferring either points, or more importantly polygon data reducing your data from 13 to 5 decimal places is likely to decrease the amount of data you are transferring by at least half.

Typical speed improvement: 50%!

2. Load small, load often

Many mapping applications allow the user to drill into the detail of the data shown on the map. In the majority of cases the user does not require the full details of every single piece of data so why bother loading them all?

Typically in the mapping applications we encounter the initial view a user is presented with has a number of pushpins / polygons maybe with a text label and or an icon representing the ‘type’ of data shown (like a hotel, house, pipe etc). So the data we need to initially load for each point is a title, latitude, longitude, type and unique id. We don’t need to load all the description, photos, links or other data that will not be shown until the user clicks the icon/polygon.

At Earthware, the way we normally handle this is to have two services, one that returns the initial map data that matches our query, and one that returns the full details for a single selected entity. You can code your map so that it makes a call to the “full details” service when a user clicks a map entity and in our experience returning the data for a single entity is usually so quick the user doesn’t even notice the slight pause.

To see an example of this service architecture using asp.net and Bing Maps see http://bingmaps.codeplex.com/wikipage?title=Getting%20Started%20in%20Web%20Services&referringTitle=Home

Typical initial map load improvement: > 500%

3. Don’t repeat yourself

Often when helping developers improve their JavaScript map performance we come across an approach to loading the map data that we don’t recommend except in the most simplistic applications. That approach is to generate the JavaScript code on the web server that is used to create entities on the map and to pass this chunk of JavaScript back to the client and execute it there. For example, we see a service return the following JavaScript:

var pin = new Microsoft.Maps.Pushpin(52.011,-0.221, {text: '1'});
map.entities.push(pin);
pin = new Microsoft.Maps.Pushpin(53.011,-0.121, {text: '2'});
map.entities.push(pin);
pin = new Microsoft.Maps.Pushpin(51.011,-0.251, {text: '3'});
map.entities.push(pin);
pin = new Microsoft.Maps.Pushpin(50.011,-0.321, {text: '4'});
map.entities.push(pin);
pin = new Microsoft.Maps.Pushpin(54.011,-0.143, {text: '5'});
map.entities.push(pin);
pin = new Microsoft.Maps.Pushpin(55.011,-0.0123, {text: '6'});
map.entities.push(pin);

This approach seems to be popular with developers because it’s quick and simple to achieve. However, the downside is that you are constantly repeating the same long text phrases and transferring all these repeats to your user, thus slowing down their mapping experience to make it easier for you to code. This data could be sent in a simple data structure, like JSON, and with some simple code looped through and added to the map. The same data above in JSON would look like:

{points:{point:[{title:1,lat:52.021,lon:-0.211},
  {title:2,lat:53.011,lon:-0.121},
  {title:3,lat:51.011,lon:-0.251},
  {title:4,lat:50.011,lon:-0.321},
  {title:5,lat:54.011,lon:-0.143},
  {title:6,lat:55.011,lon:-0.0123}

]}}

To see an example of this data transfer architecture using Asp.net, JSON and Bing Maps see http://bingmaps.codeplex.com/wikipage?title=Getting%20Started%20in%20Web%20Services&referringTitle=Home

Typical map data load improvement: > 100%

4. Some data you just can’t load fast enough

As we have recently blogged the latest Bing Maps AJAX API is now even faster at showing pushpins on a map, but there is still a limit especially when you are working with older browsers. If your data consists of thousands of entities then it won’t take long before you either cannot transfer the data fast enough or the performance of your map is too slow.

So what can you do? Your users still need to be able to search all the data so you cannot just remove some. The most common solution to this problem is ‘clustering’ of map entities. This is where you group together nearby or overlapping entities and only show individual entities once the user has zoomed in. This can be achieved either using client side code (see http://rbrundritt.wordpress.com/2011/03/02/client-side-clustering-in-v7/) or on the server side before you transfer the data to the client (see http://www.viawindowslive.com/Articles/VirtualEarth/ClusteringVirtualEarthwithMSAJAXandC.aspx). The advantage of doing this on the server side is that you do not have to transfer the data for each individual entity but instead can just transfer the data required to show the ‘clustered’ entity.

There are other approaches to this problem including generating rasterised image tiles of your data and only showing interactive map elements once the user has zoomed in. This works just as well for pushpins as it does polygons. A good example of this ‘hybrid’ approach is the open source ajax map data connector project on codeplex: http://ajaxmapdataconnector.codeplex.com/

5. Transferring data as plain text is soooo slooowwwww

We have already discussed ways of optimising the data you send your clients (in 3.) above but that approach still ends up transmitting plain text data to your clients. There are much better binary formats you could transfer the data in that would massively reduce the size of your transfers.

The first and easiest of these is to use a compression format called Gzip that is seamlessly built into all modern web browsers and plugins (Flash and Silverlight). If on your web service you compress all your map data using Gzip your clients browser will be able to atomically decompress the data ready for you code to use without you having to change you client side code at all. Gzip compression is usually very simple to enable on your web service (see these links for apache, iis6 and iis7).

This approach doesn’t just apply to data transfer or mapping and (if you are not already) you should look at compressing other ‘static’ files like your JavaScript and css.

If you are using Silverlight to load data from WCF services then an even better solution is to use the built in binary http protocol.

There is usually a slight CPU cost to compressing the data but on a modern processor this is minimal and well worth the decrease in data transfer sizes.

Typical map data load improvement: > 50%

In Summary

Hopefully some or all of these issues might help you make a real, measurable difference to your applications performance and many of them are quick and simple to achieve. We would love to hear your real world performance improvements if you do use any of these tips so please feel free to share them in the comments section below.

Earthware help Rovster launch a new type of property website

Monday, October 26th, 2009

Earthware are delighted to have been invited by Gary McCausland (from BBC1’s “Axe the Agent” to do the web design, web development, interactive mapping and SEO (Search Engine Optimisation) for his new venture Rovster.

Rovster allows a property owner who wants to “sell my house privately” to sign up and advertise online with a free property listing.  Whether you have flats to rent, property to rent or you want to buy a property in … or sell my house in …. then Rovster is seeking to debunk the property market.

We are delighted that not only did Gary decide to integrate Earthware interactive property mapping but also to use our sister, The Technology Studio to do the web design and development.

We wish Gary every success with Rovster!

The Earthware team

Virtual Earth Control 100% height problem – Solved! Well almost

Friday, August 29th, 2008

Ok, so I was using the new asp.net Virtual Earth map control and looking to size it to have a 100% width and height. Like many of you out there I was experiencing the problem that I could only seem to apply the 100% width. As soon as I tried to apply the 100% height the control was not visible when the page loaded.

Well, we here at Earthware have continued to work at the problem and have managed to come up with a solution. If you put the map control within a div which is positioned absolute and has a height and width of 100% itself, then you should see it works as required. See below…

<div style="position:absolute;width:100%;height:100%;">
    <ve:Map ID="Map1" runat="server" Height="100%" Width="100%"
    ZoomLevel="4" onserverloadmap="Map1_ServerLoadMap"
    OnClientLoadMap="Map1_ClientLoadMap"
    OnClientResize="Map1_ClientLoadMap" />
</div>

However, as always things are not quite that simple!! From what we can see this works in Internet Explorer 7 and Firefox 3, but not in earlier versions of these browsers. We’ve therefore come up with a semi fix for this. If you set the height and width using the Map.Resize method in the code behind then this works on initial page load. We’ve used some javascript and hidden fields in the code in front to get the correct height and width, as below…

CODE IN FRONT:

<script type="text/javascript">
 function Map1_ClientLoadMap(sender, e)
 {
     if (document.documentElement &&
        (document.documentElement.clientWidth ||
         document.documentElement.clientHeight))
     {
       //For the fix for IE 6 and Firefox versions less than 3
       $get("clientwidth").value = document.documentElement.clientWidth;
       $get("clientheight").value = document.documentElement.clientHeight;
     }
 }
</script>

CODE BEHIND:

protected void Map1_ServerLoadMap(object sender, EventArgs e)
{
    ResizeMap();
}

private void ResizeMap()
{
    if (Request.Browser.Type == "IE6" ||
       (Request.Browser.Browser == "Firefox" &&
        Request.Browser.MajorVersion < 3))
    {
        Map1.Resize(Convert.ToInt16(clientwidth.Value), 
                    Convert.ToInt16(clientheight.Value));
    }
}

Unfortunately at this time we cannot get the resize events to work (the Resize event only fires if you manually resize the control, not if you resize the browser window) but do check back again soon as we are continuing to work on this.

Please download an example of a working case to of all of the above in action.

We’re hiring!

Tuesday, October 30th, 2007

That’s right Earthware are continuing to expand beyond our expectations so we are looking for an experiences asp.net web developer. Earthware is an innovative small start-up company where individuals can really make a difference. If you are a quick learner and keen to pickup new and exciting skills and experience then why not apply today.

For the full details of the role please click here.

Writing KML & KMZ files to the browser with ASP.Net

Wednesday, August 9th, 2006

Over the last few weeks we have been busy finishing of various demos including our upcomming uk cinemas demo. During development we’ve come across a few ‘issues’ with writing KML an KMZ files to the users browser from an .aspx page using the “Content-Disposition” HTTP Header that I thought it would be helpful to share with other .Net Google Earth developers who may come acrross the same problems.

ALL the problems are due to Internet explorer! Firefox works perfectly all the time ;-) It seems I suffers from a number of problems, our specific ones being:

  1. IE often has problems honouring AddHeader(“Content-Disposition”,”attachment; filename=myfile.kmz”) and instead prompts the user to open a file called the same as the .aspx page they are on.
  2. IE also has problems actually downloading the file once you have the filename comming up ok, complaining about not being able to contact the internet site. Bizarely the page works fine it you follow a link to it from another page, but not if your enter the url directly into the address bar?

Both solutions in the end were simple, but not obvious

  1. If, just like us, you have IIS setup to compress all .aspx files (Gzip compression) then each .aspx request has a header “Content-Encoding: gzip” that IIS adds for you. Unfortunatly IE then ignores your “Content-Disposition” header, so to fix it add Response.AppendHeader(“Content-Encoding”, “none;”) and then it works!
  2. This one is even simplier, but we have not idea why this works. Just add Response.ClearHeaders() and the file will work properly from a direct url

So other than now having a bigger hate for IE, its all working. We hope to have some of the first demos live soon.