/bin/html/map/gridconfig/com.secondlife.agni.js

https://bitbucket.org/VirtualReality/software-testing · 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. mapapi['gridConfigs'] = mapapi['gridConfigs'] || {};
  39. var SecondLifeTileSource = new tileSource({
  40. 'copyright' : 'Š 2007 - ' + (new Date).getFullYear() + ' Linden Lab',
  41. 'label' : 'Land & Objects',
  42. 'maxZoom' : 7,
  43. 'backgroundColor' : '#1d475f'
  44. });
  45. // This Function returns the appropriate image tile from the S3 storage site corresponding to the
  46. // input location and zoom level on the google map.
  47. SecondLifeTileSource['getTileURL'] = function(pos, zoom){
  48. var
  49. sl_zoom = Math.floor(zoom + 1),
  50. regions_per_tile_edge = Math.pow(2, sl_zoom - 1),
  51. x = pos['x'],
  52. y = pos['y']
  53. ;
  54. x -= x % regions_per_tile_edge;
  55. y -= y % regions_per_tile_edge;
  56. if(x < 0 || y < 0){
  57. return null;
  58. }
  59. return (
  60. [ // 2 hosts so that we get faster performance on clients with lots of bandwidth but possible browser limits on number of open files
  61. "http://map.secondlife.com.s3.amazonaws.com",
  62. "http://map.secondlife.com"
  63. ][((x / regions_per_tile_edge) % 2)] // Pick a server
  64. + ["/map", sl_zoom, x, y, "objects.jpg"].join("-") // Get image tiles from Amazon S3
  65. );
  66. }
  67. var
  68. pos2region_pool = 0,
  69. region2pos_pool = 0,
  70. agni = new gridConfig({
  71. 'namespace' : 'com.secondlife.agni',
  72. 'vendor' : 'Linden Lab',
  73. 'name' : 'Second Life',
  74. 'description' : 'Linden Lab\'s Agni grid',
  75. 'label' : 'Agni',
  76. 'size' : new size(1048576, 1048576),
  77. 'tileSources' : [
  78. SecondLifeTileSource
  79. ],
  80. 'maxZoom' : 7,
  81. 'pos2region' : function(pos, success, fail){
  82. if(!(pos instanceof mapapi['gridPoint'])){
  83. throw 'Position should be an instance of mapapi.gridPoint';
  84. }
  85. function noIndexedDB(p, s, f){
  86. if(console != undefined){
  87. console.log('IndexedDB cache miss @ ' + Math.floor(p['x']) + ',' + Math.floor(p['y']));
  88. }
  89. var
  90. cachecheck = agni['apiCacheCheck']('pos2region', Math.floor(p['x']), Math.floor(p['y']));
  91. ;
  92. if(cachecheck != undefined){
  93. if(s){
  94. s({'pos':p, 'region': cachecheck});
  95. }
  96. return;
  97. }
  98. var
  99. script = document['createElement']('script'),
  100. _var = 'com_secondlife_agni_posToRegion_' + ((++pos2region_pool) + '')['replace'](/\d/g,function(a){ return 'ABCDEFGHIJ'[a]; })
  101. ;
  102. function done(){
  103. if(window[_var] == undefined){
  104. if(f){
  105. f('slurl.com API failed to load script variable');
  106. }
  107. }else if(window[_var]['error'] != undefined){
  108. if(f){
  109. f('slurl.com API call failed, perhaps your arguments were invalid');
  110. }
  111. }else{
  112. var
  113. region = window[_var] + ''
  114. ;
  115. if(s){
  116. s({'pos':p, 'region': region,'cache':false});
  117. }
  118. if(agni['IndexedDB']){
  119. var
  120. transaction = agni['IndexedDB']['transaction']('pos2region', IDBTransaction['READ_WRITE']),
  121. objstore = transaction['objectStore']('pos2region'),
  122. req = objstore['add']({
  123. 'pos' : Math.floor(p['x']) + '_' + Math.floor(p['y']),
  124. 'region' : region,
  125. 'l_region' : region['toLowerCase'](),
  126. 'cached' : Math.floor(new Date()['getTime']() / 1000)
  127. })
  128. ;
  129. if(console != undefined){
  130. req['onsuccess'] = function(){
  131. console.log('IndexedDB cache write @ ' + Math.floor(p['x']) + ',' + Math.floor(p['y']) + ' for ' + region);
  132. }
  133. }
  134. }
  135. agni['APIcache']['pos2region'][Math.floor(p['x'])] = agni['APIcache']['pos2region'][Math.floor(p['x'])] || {};
  136. agni['APIcache']['pos2region'][Math.floor(p['x'])][Math.floor(p['y'])] = window[_var] + '';
  137. script['parentNode']['removeChild'](script);
  138. }
  139. }
  140. script['onload'] = done;
  141. script['onreadystatechange'] = function(){
  142. if(script['readyState'] == 'complete' || script['readyState'] == 'loaded'){
  143. done();
  144. }
  145. }
  146. script['onerror'] = function(){
  147. if(f){
  148. f('Error with script loading the slurl.com API');
  149. }
  150. setTimeout(function(){
  151. script['parentNode']['removeChild'](script);
  152. },30000);
  153. }
  154. 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('&'));
  155. document['getElementsByTagName']('head')[0]['appendChild'](script);
  156. }
  157. if(agni['IndexedDB']){
  158. var
  159. index = agni['IndexedDB']['transaction']('pos2region')['objectStore']('pos2region')
  160. ;
  161. index['get'](Math.floor(pos['x']) + '_' + Math.floor(pos['y']))['onsuccess'] = function(e){
  162. if(e['target']['result']){
  163. if(console != undefined){
  164. console.log('IndexedDB cache hit @ ' + Math.floor(pos['x']) + ',' + Math.floor(pos['y']));
  165. }
  166. if(success){
  167. success({'pos':pos, 'region':e['target']['result']['region'],'cache':'hit'});
  168. }
  169. }else{
  170. noIndexedDB(pos, success, fail);
  171. }
  172. }
  173. }else{
  174. noIndexedDB(pos, success, fail);
  175. }
  176. },
  177. 'region2pos' : function(region, success, fail){
  178. var
  179. script = document['createElement']('script'),
  180. _var = 'com_secondlife_agni_regionTopos_' + ((++region2pos_pool) + '')['replace'](/\d/g,function(a){ return 'ABCDEFGHIJ'[a]; })
  181. ;
  182. function noIndexedDB(r, s, f){
  183. function done(){
  184. if(window[_var] == undefined){
  185. if(f){
  186. f('slurl.com API failed to load script variable');
  187. }
  188. }else if(window[_var]['error'] != undefined){
  189. if(f){
  190. f('slurl.com API call failed, perhaps your arguments were invalid');
  191. }
  192. }else{
  193. var
  194. pos = window[_var]
  195. ;
  196. if(s){
  197. s({'pos':gridPoint['fuzzy'](pos), 'region': r, 'cache':false});
  198. }
  199. if(agni['IndexedDB']){
  200. agni['pos2region'](pos);
  201. }
  202. script['parentNode']['removeChild'](script);
  203. }
  204. }
  205. script['onload'] = done;
  206. script['onreadystatechange'] = function(){
  207. if(script['readyState'] == 'complete' || script['readyState'] == 'loaded'){
  208. done();
  209. }
  210. }
  211. script['onerror'] = function(){
  212. if(f){
  213. f('Error with script loading the slurl.com API');
  214. }
  215. setTimeout(function(){
  216. script['parentNode']['removeChild'](script);
  217. },30000);
  218. }
  219. script['setAttribute']('src', 'http://slurl.com/get-region-coords-by-name?' + ['var=' + escape(_var), 'sim_name=' + escape(r)].join('&'));
  220. document['getElementsByTagName']('head')[0]['appendChild'](script);
  221. }
  222. if(agni['IndexedDB']){
  223. var
  224. req = agni['IndexedDB']['transaction']('pos2region')['objectStore']('pos2region')['index']('l_region')['get'](region['toLowerCase']())
  225. ;
  226. req['onsuccess'] = function(e){
  227. if(e['target']['result']){
  228. if(console != undefined){
  229. console.log('IndexedDB cache hit @ ' + region['toLowerCase']());
  230. }
  231. var
  232. pos = e['target']['result']['pos']['split']('_')
  233. ;
  234. if(success){
  235. success({'pos':gridPoint['fuzzy']({'x':pos[0],'y':pos[1]}),'region':e['target']['result']['region'],'cache':'hit'})
  236. }
  237. }else{
  238. noIndexedDB(region, success, fail);
  239. }
  240. }
  241. req['onerror'] = function(e){
  242. console.log('IndexedDB cache miss @ ' + region['toLowerCase']());
  243. noIndexedDB(region, success, fail);
  244. }
  245. }else{
  246. noIndexedDB(region, success, fail);
  247. }
  248. }
  249. })
  250. ;
  251. mapapi['gridConfigs']['com.secondlife.agni'] = agni;
  252. })(window);