PageRenderTime 47ms CodeModel.GetById 10ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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 + ',&quot;' + name + '&quot;)" />';
 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}