Two people doing their own thing.

Microsoft Certified Partner Soul Solutions
May 14

Written by: Soul Solutions
Wednesday, 14 May 2008

johnWeeGo I know I haven't posted something code related on Virtual Earth in ages, rest assured I've just been very busy.

VEStandardGrid

The 4 green boxes are the screen bounds passed to the server for data in many of my older virtual earth applications and samples, the 2 blue boxes are the standardised bounds I actually send these days.

This is the new JavaScript code I use to get the current screen bounds:

var points = new Array();    
if (map.GetMapStyle() == VEMapStyle.Birdseye) {          
    var be = map.GetBirdseyeScene();
    var rect = be.GetBoundingRectangle();
    points.push(rect.TopLeftLatLong);
    points.push(rect.BottomRightLatLong);
}else {
    var view = _map.GetMapView();
    //Bounds must be NW, SE. Reorder if not
    if (view.TopLeftLatLong.Latitude < view.BottomRightLatLong.Latitude) {
        var temp = view.TopLeftLatLong.Latitude;
        view.TopLeftLatLong.Latitude = view.BottomRightLatLong.Latitude;
        view.BottomRightLatLong.Latitude = temp;
    }
    if (view.TopLeftLatLong.Longitude > view.BottomRightLatLong.Longitude) {
        var temp = view.TopLeftLatLong.Longitude;
        view.TopLeftLatLong.Longitude = view.BottomRightLatLong.Longitude;
        view.BottomRightLatLong.Longitude = temp;
    }            
    
    //Round bounds to a standard grid. Improves server side caching performance and reduces web service calls.
    var zoom = map.GetZoomLevel();
    var latrounding = (90/(Math.pow(2,(zoom-2))));
    var lonrounding = (180/(Math.pow(2,(zoom-1))));
    
    var lat1 = view.TopLeftLatLong.Latitude;
    var lat2 = view.BottomRightLatLong.Latitude;
    var lon1 = view.TopLeftLatLong.Longitude;
    var lon2 = view.BottomRightLatLong.Longitude;
    
    var TLat = (Math.floor(lat1 / latrounding)+1) * latrounding;
    var BLat = (Math.floor(lat2 / latrounding)) * latrounding;
    var LLon = (Math.floor(lon1 / lonrounding)) * lonrounding;
    var RLon = (Math.floor(lon2 / lonrounding)+1) * lonrounding;             
    
    points.push(new VELatLong(TLat,LLon));   
    points.push(new VELatLong(BLat,RLon));                    
}

The idea here is to handle Bird's eye mode, 3D rotations and 2D in this one function. I'm going to talk more about the standard grid. Feel free to ask about Bird's eye or 3D if you have questions.

Previously I simply passed the current bounds to the server, it got the data I needed and passed it back - all was good. The issue was scalability, as hundreds of requests are made these bounds were very unique even if the data they wanted to show was the same.

The solution? Create and oversize a standard grid bounds. What this does is makes many more requests identical. It also has a side benefit that slight movements of the map don't even a trigger a new data request.

From here you can implement server side caching for popular requests and/or set the web server to a http "get" and allow client side caching if appropriate (eg if your data doesn't change).

More to come.

Tags:

2 comments so far...

Re: Querying data based on screen bounds? Use a standard grid.

Heh :) very kewl :) I was turning of my auto webmethod caching and then rounding the lat long 4 box points to a 3 or 4 places.

i like your method better :)

The only downside i can think (but it's a tiny tiny tiny tiny downside) is that someone can user firebug/Fiddler, etc to see the webservice/ajax call and then hack their own request string .. which means they are bypassing the possibility of caching.

besides that - good post (again!)

By PK on   Friday, 16 May 2008

Your name:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment    Cancel