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