/alaspatial/src/main/webapp/scripts/filter2.js

http://alageospatialportal.googlecode.com/ · JavaScript · 545 lines · 389 code · 114 blank · 42 comment · 58 complexity · 99827ce832fdb5483220f7f91f305ba5 MD5 · raw file

  1. /* image scaling, 1 to 2 */
  2. var images = new Array();
  3. var images_min = new Array();
  4. var images_max = new Array();
  5. var filters_min = new Array();
  6. var filters_max = new Array();
  7. var next_min = new Array();
  8. var next_max = new Array();
  9. var inputData = new Array();
  10. var input = new Array();
  11. var contexts = new Array();
  12. var canvas = new Array();
  13. var basefilter;
  14. var layerpresence = new Array();
  15. var inputDataI = new Array();
  16. var inputDataI2 = new Array();
  17. var max_value = 32768;
  18. function addLayer(n,name){
  19. /* document.getElementById("log").innerHTML = "addLayer(" + n + "," + name + ")<br>" + document.getElementById("log").innerHTML;*/
  20. document.getElementById('inputs_div').innerHTML +=
  21. '<image id="i' + n + '" src="" onload="loadLayer(' + n + ',&quot;' + name + '&quot;)" />';
  22. document.getElementById("i" + n).src = name;
  23. }
  24. function loadLayer(n, name){
  25. if(images[n] != null){
  26. return;
  27. }
  28. /*document.getElementById("log").innerHTML = "loadLayer(" + n + "," + name + ")<br>" + document.getElementById("log").innerHTML;*/
  29. document.getElementById("i" + n).onload = "";
  30. // data management
  31. new_image = new Image();
  32. new_image.src = name;
  33. images[n] = new_image;
  34. filters_min[n] = 0;
  35. filters_max[n] = max_value;
  36. images_min[n] = 0;
  37. images_max[n] = max_value;
  38. // canvas management
  39. canvas[n] = document.getElementsByTagName('canvas')[n];
  40. contexts[n] = canvas[n].getContext('2d');
  41. contexts[n].drawImage(new_image, 0, 0);
  42. // get the image data to manipulate
  43. input[n] = contexts[n].getImageData(0, 0, canvas[n].width, canvas[n].height);
  44. inputData[n] = input[n].data;
  45. n = n * 1;
  46. if(n>0){ //0 is base image
  47. // unpack data
  48. index_offset = images[n].width*256*4;
  49. d = inputData[n];
  50. inputDataI[n] = new Array();
  51. di = inputDataI[n];
  52. /* di2 not needed with correctly operating packaging */
  53. inputDataI2[n] = new Array();
  54. di2 = inputDataI2[n];
  55. width = canvas[n].width/2; //data fix will make this 1:1
  56. height = 255;//todo: fix after data fix
  57. for(i=1, p=0/* png data offset (fix when packaging settings fixed) */ ;i<index_offset;i+=8,p++){
  58. /* same for /8 +=8, fix with data fix*/
  59. x = 1*d[i]*width + 1*d[i+1];
  60. y = height - ( 1*d[i+4]*width + 1*d[i+5]);
  61. di[p] = (y*width + x)*4;
  62. di2[p] = (y*512 + x)*8; //will go away later
  63. }
  64. /* if possible, destroy objects no longer required here */
  65. }else{
  66. portalRefresh();
  67. }
  68. // initial filtering, for missing values
  69. if(n > 0 && n < 19){
  70. applyFilter(1*n-1, 0, 1);
  71. }else if(n >= 19){
  72. applyFilterCtx(1*n-1,-1,false);
  73. }
  74. }
  75. function checkForLayer(n){
  76. /* document.getElementById("log").innerHTML = "checkForLayer(" + n + ")<br>" + document.getElementById("log").innerHTML;*/
  77. if(layerpresence[n] == null){
  78. layerpresence[n] = true;
  79. if(n<10){
  80. addLayer(n,"images/00" + n + ".png");
  81. }else{
  82. addLayer(n,"images/0" + n + ".png");
  83. }
  84. return false;
  85. }else if(inputData[n] == null){
  86. return false;
  87. }else{
  88. return true;
  89. }
  90. }
  91. /* applyFilter takes n as 0.., i.e. it adds one */
  92. var applying_filter = false;
  93. function applyFilter(n, new_min, new_max){
  94. n = 1*n + 1;
  95. //make sure layer is loaded, or at least, loading
  96. if(!checkForLayer(n)){
  97. return;
  98. }
  99. //translate min/max
  100. if(1*new_min >= -1 && 1*new_min <= 0){
  101. new_min = 1;
  102. }else{
  103. new_min = Math.floor(new_min*(max_value-2) + 1);
  104. }
  105. new_max = Math.floor(new_max*max_value + 1);
  106. if(new_max > max_value-1){
  107. new_max = max_value-1;
  108. }
  109. if(new_max < new_min){
  110. new_max = new_min;
  111. }
  112. //record repeat action
  113. next_min[n] = new_min;
  114. next_max[n] = new_max;
  115. //stop if currently processing
  116. if(applying_filter){
  117. return;
  118. }
  119. applying_filter = true;
  120. old_min = filters_min[n];
  121. old_max = filters_max[n];
  122. while(filters_min[n] != next_min[n] || filters_max[n] != next_max[n]){
  123. new_max = next_max[n];
  124. new_min = next_min[n];
  125. old_min = filters_min[n];
  126. old_max = filters_max[n];
  127. if(old_max < old_min){
  128. old_max = old_min;
  129. }
  130. d = inputData[n];
  131. outputData = inputData[0];
  132. //current idx
  133. index_offset = images[n].width*256*4;
  134. if(old_min <= 0){
  135. old_min_idx = 0;
  136. }else if(old_min >= max_value-1){
  137. old_min_idx = index_offset/4/2;
  138. }else{
  139. old_min_idx = (d[index_offset+4*old_min+1]*256 + 1*d[index_offset+4*old_min+2]);
  140. }
  141. if(new_min <= 0){
  142. new_min_idx = 0;
  143. }else if(new_min >= max_value-2){
  144. new_min_idx = index_offset/4/2;
  145. }else{
  146. new_min_idx = (d[index_offset+4*new_min+1]*256 + 1*d[index_offset+4*new_min+2]);
  147. }
  148. old_max_idx = (d[index_offset+4*old_max+1]*256 + 1*d[index_offset+4*old_max+2]);
  149. new_max_idx = (d[index_offset+4*new_max+1]*256 + 1*d[index_offset+4*new_max+2]);
  150. if(old_max_idx == 0){
  151. old_max_idx = index_offset/4/2;
  152. }
  153. if(new_max_idx == 0){
  154. new_max_idx = index_offset/4/2;
  155. }
  156. if(old_min_idx > index_offset/4/2){
  157. old_min_idx = index_offset/4/2;
  158. }
  159. if(new_min_idx > index_offset/4/2){
  160. new_min_idx = index_offset/4/2;
  161. }
  162. if(old_max_idx > index_offset/4/2){
  163. old_max_idx = index_offset/4/2;
  164. }
  165. if(new_max_idx > index_offset/4/2){
  166. new_max_idx = index_offset/4/2;
  167. }
  168. di = inputDataI[n];
  169. di2 = inputDataI2[n];
  170. while(new_min_idx > old_min_idx){
  171. i = di[old_min_idx];
  172. i2 = di2[old_min_idx]
  173. base_filter[i] |= 0x00000001 << n;
  174. // hide image pixel
  175. outputData[i2 + 3] = 120;
  176. outputData[i2 + 7] = 120;
  177. outputData[i2 + 2051] = 120;
  178. outputData[i2 + 2055] = 120;
  179. old_min_idx++;
  180. }
  181. while(new_min_idx < old_min_idx){
  182. i = di[old_min_idx];
  183. i2 = di2[old_min_idx]
  184. base_filter[i] &= ~(0x00000001 << n);
  185. // unhide image pixel
  186. if (base_filter[i] == 0) {
  187. outputData[i2 + 3] = 255;
  188. outputData[i2 + 7] = 255;
  189. outputData[i2 + 2051] = 255;
  190. outputData[i2 + 2055] = 255;
  191. }
  192. old_min_idx--;;
  193. }
  194. while(new_max_idx > old_max_idx){
  195. i = di[old_max_idx];
  196. i2 = di2[old_max_idx]
  197. base_filter[i] &= ~(0x00000001 << n);
  198. // unhide image pixel
  199. if (base_filter[i] == 0) {
  200. outputData[i2 + 3] = 255;
  201. outputData[i2 + 7] = 255;
  202. outputData[i2 + 2051] = 255;
  203. outputData[i2 + 2055] = 255;
  204. }
  205. old_max_idx++;
  206. }
  207. while(new_max_idx < old_max_idx){
  208. i = di[old_max_idx];
  209. i2 = di2[old_max_idx]
  210. base_filter[i] |= 0x00000001 << n;
  211. // hide image pixel
  212. outputData[i2 + 3] = 120;
  213. outputData[i2 + 7] = 120;
  214. outputData[i2 + 2051] =120;
  215. outputData[i2 + 2055] = 120;
  216. old_max_idx--;
  217. }
  218. // write back new min/max
  219. filters_min[n] = new_min;
  220. filters_max[n] = new_max;
  221. // write back image bytes
  222. contexts[0].putImageData(input[0], 0, 0);
  223. portalRefresh();
  224. }
  225. applying_filter = false;
  226. }
  227. /* use contextual layer at [n], with 'value' and if show is true, make it visible
  228. *
  229. */
  230. function applyFilterCtx(n, value, show){
  231. value = value*1;
  232. n = 1*n + 1;
  233. //make sure layer is loaded, or at least, loading
  234. if(!checkForLayer(n)){
  235. return;
  236. }
  237. d = inputData[n];
  238. outputData = inputData[0];
  239. index_offset = images[n].width*256*4;
  240. end_value = index_offset / 4 / 2;
  241. if(value == -2){
  242. start_idx = 0;
  243. end_idx = end_value;
  244. }else{
  245. if(value == 0){
  246. start_idx = 0;
  247. }else{
  248. start_idx = (d[index_offset+4*value+1]*256 + 1*d[index_offset+4*value+2]);
  249. }
  250. end_idx = (d[index_offset+4*(value+1)+1]*256 + 1*d[index_offset+4*(value+1)+2]);
  251. if(end_idx == 0 || end_idx > index_offset/4/2){
  252. end_idx = end_value;
  253. }
  254. }
  255. di = inputDataI[n];
  256. di2 = inputDataI2[n];
  257. if(!show){
  258. for(p=start_idx;p<end_idx;p++){
  259. i = di[p];
  260. i2 = di2[p];
  261. base_filter[i] |= 0x00000001 << n;
  262. // hide image pixel
  263. outputData[i2 + 3] = 120;
  264. outputData[i2 + 7] = 120;
  265. outputData[i2 + 2051] = 120;
  266. outputData[i2 + 2055] = 120;
  267. }
  268. }else{
  269. for(p=start_idx;p<end_idx;p++){
  270. i = di[p];
  271. i2 = di2[p]
  272. base_filter[i] &= ~(0x00000001 << n);
  273. // unhide image pixel
  274. if (base_filter[i] == 0) {
  275. outputData[i2 + 3] = 255;
  276. outputData[i2 + 7] = 255;
  277. outputData[i2 + 2051] = 255;
  278. outputData[i2 + 2055] = 255;
  279. }
  280. }
  281. }
  282. // write back image bytes
  283. contexts[0].putImageData(input[0], 0, 0);
  284. portalRefresh();
  285. }
  286. var portal_html;
  287. var portal;
  288. function init(){
  289. addLayer(0,"images/bluemarble.jpg",0,256);
  290. base_filter = new Array(256*256);
  291. portal_html = document.getElementById("portal");
  292. portal = portal_html.getContext('2d');
  293. portalRefit();
  294. }
  295. var dx_ = 0;
  296. var dy_ = 0;
  297. var dwidth_ = 512;
  298. var dheight_ = 512;
  299. var pwidth_ = 0;
  300. var pheight_ = 0;
  301. var px_ = 0;
  302. var py_ = 0;
  303. function portalRefresh(){
  304. portal.clearRect(0,0,portal_html.width,portal_html.height);
  305. portal.drawImage(canvas[0],dx_,dy_,dwidth_,dheight_,px_,py_,portal_html.width + pwidth_,portal_html.height + pheight_);
  306. }
  307. var layer_long1 = 112;
  308. var layer_lat1 = -9;
  309. var layer_long2 = 154;
  310. var layer_lat2 = -51;
  311. var layer_width = 512;
  312. var layer_height = 512;
  313. var last_long1 = 112;
  314. var last_long2 = 154;
  315. var last_lat1 = -9;
  316. var last_lat2 = -51;
  317. function portalPosition(longitude1, latitude1, longitude2, latitude2){
  318. //fix edges within layer bounds
  319. if(longitude1 < layer_long1){
  320. longitude2 += (layer_long1-longitude1)
  321. longitude1 = layer_long1;
  322. }
  323. if(longitude2 > layer_long2){
  324. longitude1 += (layer_long2-longitude2)
  325. longitude2 = layer_long2;
  326. }
  327. if(latitude2 < layer_lat2){
  328. latitude1 += (layer_lat2 - latitude2)
  329. latitude2 = layer_lat2;
  330. }
  331. if(latitude1 > layer_lat1){
  332. latitude2 += (layer_lat1-latitude1)
  333. latitude1 = layer_lat1;
  334. }
  335. //visible layer resolution
  336. dx = (longitude2 - longitude1)/layer_width;
  337. dy = (latitude2 - latitude1)/layer_height;
  338. //layer resolution
  339. lx = (layer_long2 - layer_long1)/layer_width;
  340. ly = (layer_lat2 - layer_lat1)/layer_height;
  341. dx_ = -1*Math.floor((layer_long1 - longitude1)/lx);
  342. dwidth_ = Math.floor((longitude2 - longitude1)/lx);
  343. dy_ = -1*Math.floor((layer_lat1 - latitude1)/ly);
  344. dheight_ = Math.floor((latitude2 - latitude1)/ly);
  345. portalRefresh();
  346. last_long1 = longitude1;
  347. last_lat1 = latitude1;
  348. last_long2 = longitude2;
  349. last_lat2 = latitude2;
  350. }
  351. var mouse_down = false;
  352. var mousex = 0;
  353. var mousey = 0;
  354. function portal_mousemove(e){
  355. if(mouse_down){
  356. //pan
  357. //x/y movement
  358. rx = (1*e.clientX-1*mousex)/(1*portal_html.width);
  359. ry = (1*e.clientY-1*mousey)/(1*portal_html.height);
  360. width = 1*last_long2 - 1*last_long1;
  361. height = 1*last_lat2 - 1*last_lat1;
  362. new_long1 = last_long1 - rx*width;
  363. new_lat1 = last_lat1 - ry*height;
  364. new_long2 = last_long2 - rx*width;
  365. new_lat2 = last_lat2 - ry*height;
  366. portalPosition(new_long1,new_lat1,new_long2,new_lat2);
  367. mousex = e.clientX;
  368. mousey = e.clientY;
  369. }
  370. }
  371. function portal_mousedown(e){
  372. mousex = e.clientX;
  373. mousey = e.clientY;
  374. mouse_down = true;
  375. }
  376. function portal_mouseup(e){
  377. mouse_down = false;
  378. }
  379. //zoom in/out (out with modifier SHIFT or CTRL)
  380. //does not work correctly with browser enlarge/reduce size
  381. function portal_dblclick(e){
  382. pos = findPos(portal_html);
  383. //zoom to point by 2x
  384. rx = (1*e.clientX-1*pos.x)/(1*portal_html.width);
  385. ry = (1*e.clientY-1*pos.y)/(1*portal_html.height);
  386. width = 1*last_long2 - 1*last_long1;
  387. height = 1*last_lat2 - 1*last_lat1;
  388. new_long = (1*last_long1 + Math.floor((width)*rx));
  389. new_lat = (1*last_lat1 + Math.floor((height)*ry));
  390. if(e.shiftKey || e.ctrlKey){
  391. width *= 2;
  392. height *= 2;
  393. }else{
  394. width /= 2;
  395. height /= 2;
  396. }
  397. new_long1 = new_long - width/2;
  398. new_lat1 = new_lat - height/2;
  399. new_long2 = new_long + width/2;
  400. new_lat2 = new_lat + height/2;
  401. portalPosition(new_long1,new_lat1,new_long2,new_lat2);
  402. }
  403. //recentre
  404. function portal_click(e){
  405. pos = findPos(portal_html);
  406. //zoom to point by 2x
  407. rx = (1*e.clientX-1*pos.x)/(1*portal_html.width);
  408. ry = (1*e.clientY-1*pos.y)/(1*portal_html.height);
  409. width = 1*last_long2 - 1*last_long1;
  410. height = 1*last_lat2 - 1*last_lat1;
  411. new_long1 = (1*last_long1 + Math.floor((width)*rx)) - width/2;
  412. new_lat1 = (1*last_lat1 + Math.floor((height)*ry)) - height/2;
  413. new_long2 = new_long1 + width;
  414. new_lat2 = new_lat1 + height;
  415. portalPosition(new_long1,new_lat1,new_long2,new_lat2);
  416. }
  417. function findPos(obj)
  418. {
  419. var left = !!obj.offsetLeft ? obj.offsetLeft : 0;
  420. var top = !!obj.offsetTop ? obj.offsetTop : 0;
  421. while(obj = obj.offsetParent)
  422. {
  423. left += !!obj.offsetLeft ? obj.offsetLeft : 0;
  424. top += !!obj.offsetTop ? obj.offsetTop : 0;
  425. }
  426. return{x:left, y:top};
  427. }
  428. function portalRefit(){
  429. // set dimensions of window, also need a resize function somewhere here
  430. portalRefresh();
  431. }