Mission:Make loading a bit faster, and a bit cleaner
Goal:Load data in set of information tiles
Step 1. Load data into map
Lets request server for tiles in visible viewport
$.get("ajax/load-map-data?SE="+MySECorner.toString()+"&NE="+MyNECorner.toString()+"&zoom"+currentZoom,
function(data){
//wow! i got the data for map!
//forwhole visible viewport( and just for it)
});
Step 2. Kill users, server and youself
Just answer two single things- will you rerequest data if maps is moved by pixel
- can you cache request
And if you still here - you loading your data in wrong way, yet. Until now.
Step 3. How google loads image for tiles?
He(it?) loads it in.. tiles, segments 256x256 pixels :)Step 4. Think! Why not to do same?
If you load you marker data in set of tiles -- you can Perfectly cache them
- Map shift below 256px will not produce any requests to server
- Normal browser can perform 4-6 request to one server at one moment, so you`ll ask tiles in parrallel, 4-6 times faster
var ServerFetchedTiles=[];
function ServerFetchMapType() {
}
ServerFetchMapType.prototype.tileSize = new google.maps.Size(256,256);
ServerFetchMapType.prototype.maxZoom = 32;
ServerFetchMapType.prototype.name = "Server Tile #s";
ServerFetchMapType.prototype.alt = "Server Data Tile Map Type";
ServerFetchMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var addr=this.getAddr(coord,zoom);
//test - may be we allready load this block?
if(ServerFetchedTiles[addr]){
return
}
$.get("ajax/load-map-tile?"+addr,
function(data){
ServerFetchedTiles[addr]=data;
//wow! i got the data just for this tile
//and any map moving is nothing for me!
});
};
//and add this tile overlay to current map type
map.overlayMapTypes.insertAt(0, new ServerFetchMapType() );
And you can request tiles in two ways - as google do (x,y,z), or as latlngbox.I write some code for second variant( i think you`ll use second at the begining )
//we can request tile as tile(x,y,z)
ServerFetchMapType.prototype.getAddrXY = function(coord, zoom){
return "x="+coord.x+"&y="+coor.y+"&z="+zoom;
}
//or as latlng box
ServerFetchMapType.prototype.getAddrLatLng = function(coord, zoom){
//helper function for mercator projection
var mercator = function(point){
//
var numtiles=Math.pow(2,point.zoom);
var bitmapsize=numtiles*256;
var bitmaporigo =bitmapsize/2;
var pixelsperlondegree=bitmapsize/360;
var pixelsperlonradian=bitmapsize/(2*Math.PI);
var lat=bitmaporigo+(pixelsperlondegree*point.x);
var ged2rad=((point.t*Math.PI)/180.0);
var sn=Math.sin(deg2rad);
var lng=((bitmaporigo - 0.5 * log((1+sn)/(1-sn)) * pixelsperlonradian));
return new google.maps.LatLng(lat,lng);
}
var point1={x:coord.x*256,y:coord.y*256,z:zoom} ;
var point2={x:(coord.x+1)*256,y:(coord.y+1)*256,z:zoom} ;
var ne=mercator(point1);
var sw=mercator(point2);
return "NE="+ne.toString()+"&SW="+sw.toString()+"&z="+zoom;
}
more info about map tiles can be found at google code, and there they point this idea somehow.Idea - you can load not only images
Step 5. Enjoy
Now try to impliment pieces of this into your own code. Or see how it works onWhat lasts?
Ask one question - what you will do if there is no data for tile( you are viewing siberia ), may be just load tile for other zoom( currrent_zoom-2? ).And how to do it?(we do it).
Homework: and why cites, listed above use other technics? Benefits of quadtree?
( ps: in this mode tiles can he cached on file level. For dirrect nginx access )
( ps: in this mode tiles can he cached on file level. For dirrect nginx access )
All of sections, i list here, is allready done by me. I need just to wrap code into article, and, yap, english article :)
If you want to know more - ask
If you want to know more - ask
kashey there are lots of bugs in this code bro, the mercator function has some bugs , i fixed somthing but i dont know if its ok now, it gives me thiese values
ReplyDeleteNE=(90, 67.0800315827073)&SW=(90, -91.8723804030451)&z=10
NE=(90, -91.8723804030451)&SW=(90, 42.957327474228805)&z=10
NE=(90, 67.0800315827073)&SW=(90, -91.8723804030451)&z=10
etc..
are they ok?