/bin/html/map/gridconfig/com.secondlife.agni.js
JavaScript | 258 lines | 226 code | 6 blank | 26 comment | 50 complexity | 8752d08533db51fd83c73fc71e0a101f MD5 | raw file
1/** 2* @license License and Terms of Use 3* 4* Copyright (c) 2011 SignpostMarv 5* Copyright (c) 2010 Linden Research, Inc. 6* 7* Permission is hereby granted, free of charge, to any person obtaining a copy 8* of this software and associated documentation files (the "Software"), to deal 9* in the Software without restriction, including without limitation the rights 10* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11* copies of the Software, and to permit persons to whom the Software is 12* furnished to do so, subject to the following conditions: 13* 14* The above copyright notice and this permission notice shall be included in 15* all copies or substantial portions of the Software. 16* 17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23* THE SOFTWARE. 24*/ 25(function(window, undefined){ 26 window['mapapi'] = window['mapapi'] || {}; 27 var 28 document = window['document'], 29 mapapi = window['mapapi'], 30 IDBTransaction = window['IDBTransaction'], 31 Date = window['Date'], 32 console = window['console'], 33 gridConfig = mapapi['gridConfig'], 34 tileSource = mapapi['tileSource'], 35 size = mapapi['size'], 36 gridPoint = mapapi['gridPoint'] 37 ; 38 39 mapapi['gridConfigs'] = mapapi['gridConfigs'] || {}; 40 41 var SecondLifeTileSource = new tileSource({ 42 'copyright' : ' 2007 - ' + (new Date).getFullYear() + ' Linden Lab', 43 'label' : 'Land & Objects', 44 'maxZoom' : 7, 45 'backgroundColor' : '#1d475f' 46 }); 47 48// This Function returns the appropriate image tile from the S3 storage site corresponding to the 49// input location and zoom level on the google map. 50 SecondLifeTileSource['getTileURL'] = function(pos, zoom){ 51 var 52 sl_zoom = Math.floor(zoom + 1), 53 regions_per_tile_edge = Math.pow(2, sl_zoom - 1), 54 x = pos['x'], 55 y = pos['y'] 56 ; 57 x -= x % regions_per_tile_edge; 58 y -= y % regions_per_tile_edge; 59 60 if(x < 0 || y < 0){ 61 return null; 62 } 63 return ( 64 [ // 2 hosts so that we get faster performance on clients with lots of bandwidth but possible browser limits on number of open files 65 "http://map.secondlife.com.s3.amazonaws.com", 66 "http://map.secondlife.com" 67 ][((x / regions_per_tile_edge) % 2)] // Pick a server 68 + ["/map", sl_zoom, x, y, "objects.jpg"].join("-") // Get image tiles from Amazon S3 69 ); 70 } 71 72 var 73 pos2region_pool = 0, 74 region2pos_pool = 0, 75 agni = new gridConfig({ 76 'namespace' : 'com.secondlife.agni', 77 'vendor' : 'Linden Lab', 78 'name' : 'Second Life', 79 'description' : 'Linden Lab\'s Agni grid', 80 'label' : 'Agni', 81 'size' : new size(1048576, 1048576), 82 'tileSources' : [ 83 SecondLifeTileSource 84 ], 85 'maxZoom' : 7, 86 'pos2region' : function(pos, success, fail){ 87 if(!(pos instanceof mapapi['gridPoint'])){ 88 throw 'Position should be an instance of mapapi.gridPoint'; 89 } 90 function noIndexedDB(p, s, f){ 91 if(console != undefined){ 92 console.log('IndexedDB cache miss @ ' + Math.floor(p['x']) + ',' + Math.floor(p['y'])); 93 } 94 var 95 cachecheck = agni['apiCacheCheck']('pos2region', Math.floor(p['x']), Math.floor(p['y'])); 96 ; 97 if(cachecheck != undefined){ 98 if(s){ 99 s({'pos':p, 'region': cachecheck}); 100 } 101 return; 102 } 103 var 104 script = document['createElement']('script'), 105 _var = 'com_secondlife_agni_posToRegion_' + ((++pos2region_pool) + '')['replace'](/\d/g,function(a){ return 'ABCDEFGHIJ'[a]; }) 106 ; 107 function done(){ 108 if(window[_var] == undefined){ 109 if(f){ 110 f('slurl.com API failed to load script variable'); 111 } 112 }else if(window[_var]['error'] != undefined){ 113 if(f){ 114 f('slurl.com API call failed, perhaps your arguments were invalid'); 115 } 116 }else{ 117 var 118 region = window[_var] + '' 119 ; 120 if(s){ 121 s({'pos':p, 'region': region,'cache':false}); 122 } 123 if(agni['IndexedDB']){ 124 var 125 transaction = agni['IndexedDB']['transaction']('pos2region', IDBTransaction['READ_WRITE']), 126 objstore = transaction['objectStore']('pos2region'), 127 req = objstore['add']({ 128 'pos' : Math.floor(p['x']) + '_' + Math.floor(p['y']), 129 'region' : region, 130 'l_region' : region['toLowerCase'](), 131 'cached' : Math.floor(new Date()['getTime']() / 1000) 132 }) 133 ; 134 if(console != undefined){ 135 req['onsuccess'] = function(){ 136 console.log('IndexedDB cache write @ ' + Math.floor(p['x']) + ',' + Math.floor(p['y']) + ' for ' + region); 137 } 138 } 139 } 140 agni['APIcache']['pos2region'][Math.floor(p['x'])] = agni['APIcache']['pos2region'][Math.floor(p['x'])] || {}; 141 agni['APIcache']['pos2region'][Math.floor(p['x'])][Math.floor(p['y'])] = window[_var] + ''; 142 script['parentNode']['removeChild'](script); 143 } 144 } 145 script['onload'] = done; 146 script['onreadystatechange'] = function(){ 147 if(script['readyState'] == 'complete' || script['readyState'] == 'loaded'){ 148 done(); 149 } 150 } 151 script['onerror'] = function(){ 152 if(f){ 153 f('Error with script loading the slurl.com API'); 154 } 155 setTimeout(function(){ 156 script['parentNode']['removeChild'](script); 157 },30000); 158 } 159 script['setAttribute']('src', 'http://slurl.com/get-region-name-by-coords?' + ['var=' + escape(_var), 'grid_x=' + escape(Math.floor(p['x'])), 'grid_y=' + escape(Math.floor(p['y']))].join('&')); 160 document['getElementsByTagName']('head')[0]['appendChild'](script); 161 } 162 if(agni['IndexedDB']){ 163 var 164 index = agni['IndexedDB']['transaction']('pos2region')['objectStore']('pos2region') 165 ; 166 index['get'](Math.floor(pos['x']) + '_' + Math.floor(pos['y']))['onsuccess'] = function(e){ 167 if(e['target']['result']){ 168 if(console != undefined){ 169 console.log('IndexedDB cache hit @ ' + Math.floor(pos['x']) + ',' + Math.floor(pos['y'])); 170 } 171 if(success){ 172 success({'pos':pos, 'region':e['target']['result']['region'],'cache':'hit'}); 173 } 174 }else{ 175 noIndexedDB(pos, success, fail); 176 } 177 } 178 }else{ 179 noIndexedDB(pos, success, fail); 180 } 181 }, 182 'region2pos' : function(region, success, fail){ 183 var 184 script = document['createElement']('script'), 185 _var = 'com_secondlife_agni_regionTopos_' + ((++region2pos_pool) + '')['replace'](/\d/g,function(a){ return 'ABCDEFGHIJ'[a]; }) 186 ; 187 function noIndexedDB(r, s, f){ 188 function done(){ 189 if(window[_var] == undefined){ 190 if(f){ 191 f('slurl.com API failed to load script variable'); 192 } 193 }else if(window[_var]['error'] != undefined){ 194 if(f){ 195 f('slurl.com API call failed, perhaps your arguments were invalid'); 196 } 197 }else{ 198 var 199 pos = window[_var] 200 ; 201 if(s){ 202 s({'pos':gridPoint['fuzzy'](pos), 'region': r, 'cache':false}); 203 } 204 if(agni['IndexedDB']){ 205 agni['pos2region'](pos); 206 } 207 script['parentNode']['removeChild'](script); 208 } 209 } 210 script['onload'] = done; 211 script['onreadystatechange'] = function(){ 212 if(script['readyState'] == 'complete' || script['readyState'] == 'loaded'){ 213 done(); 214 } 215 } 216 script['onerror'] = function(){ 217 if(f){ 218 f('Error with script loading the slurl.com API'); 219 } 220 setTimeout(function(){ 221 script['parentNode']['removeChild'](script); 222 },30000); 223 } 224 script['setAttribute']('src', 'http://slurl.com/get-region-coords-by-name?' + ['var=' + escape(_var), 'sim_name=' + escape(r)].join('&')); 225 document['getElementsByTagName']('head')[0]['appendChild'](script); 226 } 227 if(agni['IndexedDB']){ 228 var 229 req = agni['IndexedDB']['transaction']('pos2region')['objectStore']('pos2region')['index']('l_region')['get'](region['toLowerCase']()) 230 ; 231 req['onsuccess'] = function(e){ 232 if(e['target']['result']){ 233 if(console != undefined){ 234 console.log('IndexedDB cache hit @ ' + region['toLowerCase']()); 235 } 236 var 237 pos = e['target']['result']['pos']['split']('_') 238 ; 239 if(success){ 240 success({'pos':gridPoint['fuzzy']({'x':pos[0],'y':pos[1]}),'region':e['target']['result']['region'],'cache':'hit'}) 241 } 242 }else{ 243 noIndexedDB(region, success, fail); 244 } 245 } 246 req['onerror'] = function(e){ 247 console.log('IndexedDB cache miss @ ' + region['toLowerCase']()); 248 noIndexedDB(region, success, fail); 249 } 250 }else{ 251 noIndexedDB(region, success, fail); 252 } 253 } 254 }) 255 ; 256 257 mapapi['gridConfigs']['com.secondlife.agni'] = agni; 258})(window);