I will cut you into tiles. Part one

    imageDespite all my attempts to correct the situation with the technology of loading data onto a card, people continue and continue to work the old fashioned way, loading either all viewport data at the slightest movement of the map, or simply loading all the data in general.
    As long as the direction meters rasterize markers into pictures, build super grouping and clustering systems and tremble over every extra kilobyte in scripts, let me tell you the easiest, most stable, and banal way to make my life, my users, my cards and my server a little more beautiful.
    As will be said a little later, conquering cards consists of 5 steps.
    The first of them is loading a map (not everything is as simple as it seems), but the second is loading onto these very data cards.
    He is interesting to us.

    Currently, there are two common approaches to loading this marker on the map.
    1. We load all the data through ajax, or javascript right away
    2. We pull the server for the subject “what objects do we have in the current viewport?”
    The first option has the right to life, especially if there are few markers, and markermanager helps here (hide invisible ones) , but let's forget the second one like a nightmare.

    So, we will consider

    that we have a function for loading coordinate box data
    1. $.get("ajax/load-map-data?SE="+MySECorner.toString()+"&NE="+MyNECorner.toString()+"&zoom="+currentZoom,
    2.    function(data){
    3.     //wow! i got the data for map!
    4.     //for whole visible viewport( and just for it)
    5.    });
    * This source code was highlighted with Source Code Highlighter.

    Using it, we kill our server with the impossibility of caching, and the user with delays at the slightest card shift (fi 4 aroundme number of times).

    How does this fucking google work so fast!

    He seems to upload pictures of his cards ... in small pieces, 256x256 pixels.

    Think% username%, why not do the same?


    If we loaded our data in this way:
    • could just cache on the server
    • moving the map less than 256 pixels would most likely not result in loading new data blocks
    • And since a normal browser supports 4-6 concurrent requests to one server (or even more, use jsonp luke! For a couple of subdomains), we would get the same amount of data in a couple of streams and, as a result, it’s faster


    Personally, I belong to the category of perverts, and my implementation of such tricky requests, plus marker manager & clustering takes about 6,000 lines.
    I will not torment you now with what I will discuss in subsequent articles.

    I’ll just tell you

    How to make it easy


    The implementation is presented for google maps v3, it can be redone for yandex cards in seconds (we take tiles on Google and display them on Yandex maps , or we implement the described interface initially on Yandex ITile and use their carpet), or, after working a little file, under google maps v2
    In any case, there is a wonderful SparseTileLayer that you can disassociate from both api maps and everything else (and which we are currently using, since there were no user options in v3 at the time of development of maps)


    So let's create our map type
    1. function ServerFetchMapType() {
    2. }
    3.  
    4. ServerFetchMapType.prototype.tileSize = new google.maps.Size(256,256);
    5. ServerFetchMapType.prototype.maxZoom = 32;
    6. ServerFetchMapType.prototype.name = "Server Tile #s";
    7. ServerFetchMapType.prototype.alt = "Server Data Tile Map Type";   
    8.  
    9.  
    10. ServerFetchMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
    11.  var addr=this.getAddr(coord,zoom);
    12.  //test - may be we allready load this block?
    13.  if(ServerFetchedTiles[addr]){
    14.   return
    15.  }
    16.  
    17.  $.get("ajax/load-map-tile?"+addr,
    18.    function(data){
    19.     ServerFetchedTiles[addr]=data;
    20.     //wow! i got the data just for this tile
    21.    });
    22.  
    23. };
    24.  
    25.  
    26. //and add this tile overlay to current map type
    27. map.overlayMapTypes.insertAt(0, new ServerFetchMapType() );
    * This source code was highlighted with Source Code Highlighter.

    It’s not strange - that’s all :)
    We created our type of card, only instead of pictures we execute requests to the server.
    And there are two options: Google like when we address a tile by its x, y, z or standard, by bouncing box.
    Implementation of these methods:
    1. //we can request tile as tile(x,y,z)
    2. ServerFetchMapType.prototype.getAddrXY = function(coord, zoom){
    3.   return "x="+coord.x+"&y="+coor.y+"&z="+zoom;
    4. }
    5.  
    6. //or as latlng box
    7. ServerFetchMapType.prototype.getAddrLatLng = function(coord, zoom){
    8.   
    9.   //helper function for mercator projection
    10.   var mercator = function(point){
    11.    //
    12.    var numtiles=Math.pow(2,point.zoom);
    13.    var bitmapsize=numtiles*256;
    14.    var bitmaporigo    =bitmapsize/2;
    15.    var pixelsperlondegree=bitmapsize/360;
    16.    var pixelsperlonradian=bitmapsize/(2*Math.PI);
    17.   
    18.    var lat=bitmaporigo+(pixelsperlondegree*point.x);
    19.    var ged2rad=((point.t*Math.PI)/180.0);
    20.    var sn=Math.sin(deg2rad);
    21.    var lng=((bitmaporigo - 0.5 * log((1+sn)/(1-sn)) * pixelsperlonradian));
    22.    return new google.maps.LatLng(lat,lng);
    23.   }
    24.   var point1={x:coord.x*256,y:coord.y*256,z:zoom} ;
    25.   var point2={x:(coord.x+1)*256,y:(coord.y+1)*256,z:zoom} ;
    26.   var ne=mercator(point1);
    27.   var sw=mercator(point2);
    28.   return "NE="+ne.toString()+"&SW="+sw.toString()+"&z="+zoom;
    29. }
    * This source code was highlighted with Source Code Highlighter.

    * in this case, we did not very nicely implement our function of the Mercator, it is much better to use the built-in converters (yandex.converter) and projectors (overlay.projection) API cards.

    What remains


    It remains to answer the question - what will happen if you do not have data for the downloaded tiles (you are in the middle of the Ural mountains) and why do you need to load the data at all in this case.

    I gave the answer to this question a year and a half ago.
    Well, in the end , let's compare how data loading on wikimapia , esosedi , gdeetotdom and (shame and shame on programmers!) Aroundme by the

    way should be clarified that the three indicated “smart” sites use the “z-tiles” encoding, essentially a quadtree path, but wikimapia, through its api, it allows you to request data in xzy addressing.

    That's all


    I hope that my thoughts will reach people in need of these thoughts, if you have questions - ask.
    If there are just questions on cartography, ask too, since I had to start my blog ( blogspot mirror ) in my clumsy English, I will always be happy to write about problems that concern the masses.

    Well, I’ll go and finish writing the second article in which I will tell you many new secrets, which were not announced before on the hub. Do you stock up on coffee and chat

    Also popular now: