import com.brainoff.worldkitMain; import com.brainoff.worldkitConfig; import com.brainoff.worldkitInteraction; import com.brainoff.worldkitUtil; //import flash.display.*; class com.brainoff.worldkitImages { static private var imagemc:MovieClip; static private var layer:Number; private var main:worldkitMain; private var conf:worldkitConfig; private var interact:worldkitInteraction; private var imglist:Object; private var loadinglist:Object; private var imagesLoading:Number; private var startLoading:Number; private var loaderId:Number; public function worldkitImages(main:worldkitMain) { this.main = main; /* create a main level holding mc for all images perhaps best to have a main level method for allocating movie clips, levels REVISIT */ main.parent.createEmptyMovieClip("worldkitImages",1); imagemc = main.parent.worldkitImages; layer = 1; imagesLoading = 0; startLoading = 0; loaderId = -1; imglist = new Object(); loadinglist = new Object(); loadinglist.size = 0; } public function load():Void { conf = main.getConfig(); interact = main.getInteract(); /* Load by displaytype. This is a relic structure, since there's many ways to load images now (wms, etc) displaytype should be deprecated sooner or later and all these ways of loading and modelling images refactored //REVISIT */ switch (conf.displaytype) { case("day"): if ((conf.dayimg).length > 0) { /* 0 length dayimg indicates don't load one */ loadImage(imagemc, "day", conf.dayimg, layer, "", 1, 0, undefined, undefined, undefined, true); layer++; } break; case("daynight"): loadImage(imagemc, "day", conf.dayimg, layer+1, "Mask", 1, 0, undefined, undefined, undefined, true); loadImage(imagemc, "night", conf.nightimg, layer, "",1,0, undefined, undefined, undefined, true); layer += 3; //+=3 because mask mc is created layer, should just create here REVISIT break; case("dymax"): //No one is using dymax, deprecate REVISIT loadImage(imagemc, "dymax", conf.dymaximg, layer, "", 1, 0, undefined, undefined, undefined, true); layer++; break; case("polar"): //slighty more useful than dymax but REVISIT loadImage(imagemc, "polar", conf.polarimg, layer, "", 1, undefined, undefined, undefined, undefined, true); layer++; break; } /* preload in the icons used by RSS annotations */ for (var s in conf.icon) { if (conf.icon[s] != "") { loadImage(imagemc,"icon" + s, conf.icon[s], layer, "MakeInvisible",0,1, undefined, undefined, undefined, true); layer++; } } /* swftemplate: a way to specify a tiling on a single level this should be our base representation of images -- a single image is a special case of tiling */ var l=0; for (var s in conf.swftemplate) { imagemc.createEmptyMovieClip(s, layer + conf.swftemplate[s].layer); conf.swftemplate[ s ].mc_created = true; } layer += conf.swftemplatelayer; // checkSwfTemplate(); /* swflayer can actually load in any type of image with additional positioning parameters */ for (var swf in conf.swflayer) { if (conf.swflayer[swf].preload != false && conf.swflayer[swf].fromtemplate != true) { //need to save layer level if not preload loadImage(imagemc, "swflayer" + swf, conf.swflayer[swf].url, layer, "AdjustSwf", 0,1, conf.swflayer[swf].w, conf.swflayer[swf].h, conf.swflayer[swf].extent, true); layer++; } conf.swflayer[swf].parent = imagemc; } if (startLoading == 0) { main.signalDone("IMAGES"); } } /* load a single image into worldKit, and rectify */ private function loadImage(mc:MovieClip, id:String, url:String, level:Number, callback:String, resize:Number, bg:Number, width:Number, height:Number, extent:String,start:Boolean):Void { addLoading(mc,id,url,level,callback,resize,bg,width,height,extent,start); mc.createEmptyMovieClip(id, level); //if (bg == 1) { mc[ id ]._alpha = 0; //} MovieClipLoaderFix(mc._name + ":" + id); //var image_mcl:MovieClipLoader = new MovieClipLoader(); //image_mcl.addListener(this); //image_mcl.loadClip(url, mc[ id ]); imageDialog(); } /* Keep record of parameters for loading image Can't be stored in the MovieClip itself, since that is overwritten by the loaded image */ private function addLoading(mc:MovieClip, id:String, url:String, level:Number, callback:String, resize:Number, bg:Number, width:Number, height:Number, extent:String,start:Boolean):Void { var key:String = mc._name + ":" + id; imglist[ key ] = new Object(); imglist[ key ].mc = mc; imglist[ key ].id = id; imglist[ key ].url = url; imglist[ key ].level = level; imglist[ key ].callback = callback; imglist[ key ].resize = resize; imglist[ key ].bg = bg; imglist[ key ].width = width; imglist[ key ].height = height; imglist[ key ].extent = extent; imglist[ key ].starttime = new Date(); imglist[ key ].start = start; imagesLoading++; if (start == true) startLoading++; } private function MovieClipLoaderFix(key:String):Void { var mc = imglist[ key ].mc; mc[ imglist[key].id ].loadMovie( imglist[ key ].url ); loadinglist[ key ] = true; loadinglist.size++; if (loaderId == -1) { var i = 250; loaderId = setInterval( this, "MovieClipLoaderInterval", i ); } } public function MovieClipLoaderInterval():Void { var key; for (key in loadinglist) { if (key == "size") { continue; } var mc = imglist[ key ].mc[ imglist[key].id ]; var bl = mc.getBytesLoaded(); var bt = mc.getBytesTotal(); var w = mc._width; var h = mc._height; if (bt > 0 && bl >= bt && w > 0 && h > 0) { delete loadinglist[ key ]; loadinglist.size--; if (loadinglist.size == 0) { clearInterval( loaderId ); loaderId = -1; } onLoadInit(mc); } } } /* Callback on loaded image */ public function onLoadInit(target_mc:MovieClip):Void { var key:String = target_mc._parent._name + ":" + target_mc._name; /* var parent = target_mc._parent; var name = target_mc._name; var level = target_mc.getDepth(); var myBitmap = new BitmapData(target_mc._width, target_mc._height, true, 0x00ffffff); myBitmap.draw(target_mc); removeMovieClip(target_mc); parent.createEmptyMovieClip(name, level); target_mc.attachBitmap(myBitmap, 1, "never", true); */ target_mc.loaded = true; if (conf.dontstretchimage) { target_mc.origwidth = conf.w; target_mc.origheight = conf.h; } else { if (imglist[key].width != undefined) { target_mc.origwidth = imglist[key].width; } else { target_mc.origwidth = target_mc._width; } target_mc.actualwidth = target_mc._width; if (imglist[key].height != undefined) { target_mc.origheight = imglist[key].height; } else { target_mc.origheight = target_mc._height; } target_mc.actualheight = target_mc._height; } if (imglist[key].resize == 1) { interact.scaleAndPosition(imglist[key].mc, imglist[key].id, imglist[key].extent); } if (imglist[key].callback != "") { this[ imglist[key].callback ].apply(this, [imglist[key].mc, imglist[key].id]); } if (! imglist[key].bg) { target_mc._alpha = 100; } imagesLoading--; imageDialog(); if (imglist[key].start) { startLoading--; if (startLoading == 0) { main.signalDone("IMAGES"); } } } public function onLoadError(target_mc:MovieClip):Void { var key:String = target_mc._parent._name + ":" + target_mc._name; /* if (imglist[key].start) { startLoading--; if (startLoading == 0) { main.signalDone("IMAGES"); } } */ delete imglist[key]; interact.LoadingDialog("Could not load " + target_mc._name); target_mc.removeMovieClip(); imagesLoading--; } private function imageDialog():Void { if (imagesLoading == 0) { interact.LoadingDialog(); } else if (conf.loadimgmsg.length > 0) { interact.LoadingDialog(conf.loadimgmsg); } else if (imagesLoading == 1) { interact.LoadingDialog("1 Image Loading"); } else if (imagesLoading > 1) { interact.LoadingDialog(String(imagesLoading) + " Images Loading"); } } /* Callbacks on image load */ public function Mask(mc:MovieClip, id:String):Void { var maskname = id + "Masker"; mc.createEmptyMovieClip(maskname, mc[id].getDepth+1); mc[id].setMask(mc[maskname]); sino(mc, id, maskname); setInterval(this,"sino",60000,mc,id,maskname); //Update mask every minute } public function MakeInvisible(mc:MovieClip, id:String):Void { mc[id]._visible = 0; } public function AdjustSwf(mc:MovieClip, id:String):Void { var confid = id.substr(8); if (conf.swflayer[confid].mask == true) { if (mc[ id ].masker == undefined) { mc[ id ].createEmptyMovieClip( "masker", 0); //parent[ swf ].setMask( parent[ swf ].mask ); mc[ id ].masker.moveTo(0,0); mc[ id ].masker.beginFill(0x000000); mc[ id ].masker.lineTo(0, conf.swflayer[confid].h); mc[ id ].masker.lineTo(conf.swflayer[confid].w, conf.swflayer[confid].h); mc[ id ].masker.lineTo(conf.swflayer[confid].w, 0); mc[ id ].masker.lineTo(0,0); mc[ id ].masker.endFill(); } var clip = mc[ id ]; clip.setMask( clip[ "masker"] ); } interact.scaleAndPosition(mc, id, conf.swflayer[confid].extent, true); mc[ id ]._alpha = 100; if (isSwfVisible(mc,id)) { //setTimeNavAlpha(mc,id); mc[ id ]._visible = true; } else { mc[ id ]._visible = false; } } private function checkSwf(mc:MovieClip, id:String):Void { var confid:String = id.substr(8); if (isSwfVisible(mc,id)) { if (mc[id] == undefined) { loadImage(mc, id, conf.swflayer[confid].url, layer, "AdjustSwf", 0, 1, conf.swflayer[confid].w, conf.swflayer[confid].h, conf.swflayer[confid].extent); layer++; } else if (mc[id].loaded == true) { interact.scaleAndPosition(mc, id, conf.swflayer[confid].extent, true); var wsen = conf.swflayer[confid].extent.split(','); //interact.onJRSSComm("" + conf.swflayer[confid].extent + "" + wsen[1] + " " + wsen[0] + " " + wsen[3] + " " + wsen[2] + ""); mc[ id ]._visible = true; //setTimeNavAlpha(mc,id); } } else { mc[ id ]._visible = false; } } private function checkSwfTemplate():Void { if (conf.swftemplate == undefined) { return; } for (var id in conf.swftemplate) { //for each template, see if its extent and scale cover current viewing var wsen:Array = conf.swftemplate[id].extent.split(","); var w = Number(wsen[0]); var s = Number(wsen[1]); var e = Number(wsen[2]); var n = Number(wsen[3]); //REVISIT break this out into several statements if (interact.scale >= conf.swftemplate[id].minscale && interact.scale <= conf.swftemplate[id].maxscale && interact.cnorth > s && interact.csouth < n && interact.ceast > w && interact.cwest < e && (conf.swftemplate[id].category == undefined || conf.categories[ conf.swftemplate[id].category ] != false)) { //this template is viewable, so determing which tiles are required //and request them if not already cached var latspan = (n - s) / conf.swftemplate[id].spany; var longspan = (e - w) / conf.swftemplate[id].spanx; var curlong; var curlat; curlong = interact.cwest; while (curlong <= interact.ceast) { curlat = interact.cnorth; while (curlat >= interact.csouth) { this.posToTile(curlat,curlong,id); if (curlat == interact.csouth) { break; } else { curlat -= latspan; if (curlat < interact.csouth) { curlat = interact.csouth; } } } if (curlong == interact.ceast) { break; } else { curlong += longspan; if (curlong > interact.ceast) { curlong = interact.ceast; } } } } } } public function addNewSwfTemplates() { for (var s in conf.swftemplate) { if (conf.swftemplate[ s ].mc_created != true) { imagemc.createEmptyMovieClip(s, layer + conf.swftemplate[s].layer); conf.swftemplate[ s ].mc_created = true; } } } /* Given a location and swftemplate id determine which tiles to load */ private function posToTile(lat:Number, lon:Number, id:String):Void { var i,j; var wsen:Array = conf.swftemplate[id].extent.split(","); var w = Number(wsen[0]); var s = Number(wsen[1]); var e = Number(wsen[2]); var n = Number(wsen[3]); var latspan = (n - s) / conf.swftemplate[id].spany; var longspan = (e - w) / conf.swftemplate[id].spanx; i = Math.floor( (lon-w) / longspan ); j = Math.floor( (n-lat) / latspan ); if (i >= 0 && i < conf.swftemplate[id].spanx && j >= 0 && j < conf.swftemplate[id].spany) { var tilenorth = n - (j * latspan); var tilesouth = n - ((j+1) * latspan); var tilewest = w + (i * longspan); var tileeast = w + ((i+1) * longspan); var tilelat = (tilenorth + tilesouth ) / 2; var tilelon = (tileeast + tilewest) / 2; var tileid = id + "i" + i + "j" + j; if (conf.swflayer[tileid] == undefined) { conf.swflayer[tileid] = new Object(); conf.swflayer[tileid].extent = tilewest + "," + tilesouth + "," + tileeast + "," + tilenorth; if (conf.projection == "mercator") { tilesouth = 180 / Math.PI * ( 2 * Math.atan(Math.exp(tilesouth * Math.PI / 180)) - Math.PI/2); tilenorth = 180 / Math.PI * ( 2 * Math.atan(Math.exp(tilenorth * Math.PI / 180)) - Math.PI/2); } var tileurl = conf.swftemplate[id].url; if (conf.swftemplate[id].tilemap) { tileurl = worldkitUtil.myreplace(tileurl,"ZOOM", (Math.log(conf.swftemplate[id].minscale)/Math.log(2)).toString()); tileurl = worldkitUtil.myreplace(tileurl,"XTILE", i); if (conf.swftemplate[ id ].origin == "nw") { tileurl = worldkitUtil.myreplace(tileurl,"YTILE", j); } else { tileurl = worldkitUtil.myreplace(tileurl,"YTILE", (conf.swftemplate[id].spany -j - 1).toString()); } //tileurl = tileurl + Math.log(conf.swftemplate[id].minscale)/Math.log(2) + "/" + i + "/" + (conf.swftemplate[id].spany - j - 1) + ".jpg"; } else if (conf.swftemplate[id].zoomify != undefined) { var group = Math.floor((conf.swftemplate[id].tilecount + i + (j * conf.swftemplate[id].spanx)) / 256); tileurl = tileurl + "TileGroup" + group + "/" + conf.swftemplate[id].zoomify + "-" + i + "-" + j + ".jpg"; trace(tileurl); } else { tileurl = worldkitUtil.myreplace(tileurl,"NORTH",tilenorth); tileurl = worldkitUtil.myreplace(tileurl,"SOUTH",tilesouth); tileurl = worldkitUtil.myreplace(tileurl,"EAST",tileeast); tileurl = worldkitUtil.myreplace(tileurl,"WEST",tilewest); tileurl = worldkitUtil.myreplace(tileurl,"LAT",tilelat); tileurl = worldkitUtil.myreplace(tileurl,"LON",tilelon); } conf.swflayer[tileid].url = tileurl; conf.swflayer[tileid].h = conf.swftemplate[id].tileheight; conf.swflayer[tileid].w = conf.swftemplate[id].tilewidth; conf.swflayer[tileid].minscale = conf.swftemplate[id].minscale; conf.swflayer[tileid].maxscale = conf.swftemplate[id].maxscale; conf.swflayer[tileid].minview = conf.swftemplate[id].minview; conf.swflayer[tileid].maxview = conf.swftemplate[id].maxview; conf.swflayer[tileid].category = conf.swftemplate[id].category; conf.swflayer[tileid].time = conf.swftemplate[id].time; conf.swflayer[tileid].parent = imagemc[id]; conf.swflayer[tileid].fromtemplate = true; loadImage( imagemc[ id ], "swflayer" + tileid, tileurl, layer, "AdjustSwf", 0, 1, conf.swflayer[ tileid ].w, conf.swflayer[ tileid ].h, conf.swflayer[ tileid ].extent ); layer++; } } } private function isSwfVisible(mc:MovieClip, id:String):Boolean { var confid = id.substr(8); var visible = true; if (conf.swflayer[confid].extent != undefined) { var wsen = conf.swflayer[confid].extent.split(","); var w = Number(wsen[0]); var s = Number(wsen[1]); var e = Number(wsen[2]); var n = Number(wsen[3]); if (w > interact.ceast || s > interact.cnorth || e < interact.cwest || n < interact.csouth) { visible = false; } } if (conf.swflayer[confid].minview != undefined && conf.swflayer[confid].maxview != undefined) { if (conf.swflayer[confid].minview > interact.scale || conf.swflayer[confid].maxview < interact.scale) { visible = false; } } //lots of inconsistencies in how layers are addressed (in conf, in imagelayer, in javascript api) REVISIT if ((conf.swflayer[confid].category != undefined && conf.categories[ conf.swflayer[confid].category ] == false) || (conf.categories[ confid ] == false)) { visible = false; } //if (conf.timenav != false && conf.swflayer[confid].time != undefined) { // var diff = Math.abs( interact.maxtime - conf.swflayer[confid].time ); // trace(diff); // if (diff > 1382400000 * 2) { // trace("out of range"); // visible = false; // } //} //visible = true; return visible; } //ALPHA wms time nav public function setTimeNavAlpha(mc:MovieClip, id:String):Void { var confid:String = id.substr(8); if (conf.timenav != false && conf.swflayer[confid].time != undefined) { var diff = Math.abs( Number(interact.maxtime) - Number(conf.swflayer[confid].time) ); mc[id]._alpha = 100 * (1382400000 * 2 - diff) / (1382400000 * 2)+ 30; } } public function sino(mc:MovieClip, id:String, mask:String):Void { mc[mask].clear(); var width = mc[id].origwidth; var height = mc[id].origheight; var myTime = new Date(); var m_offset = new Array(0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334); //adjust for leap year var txtphase1 = 2 * Math.PI * (myTime.getDate() + m_offset[ myTime.getMonth()+1 ] - 80)/360; var txttilt = 1 / (Math.sin (txtphase1) * Math.tan(23.45 * Math.PI / 180)); var dot; if (txttilt>0) { dot = 0;} else {dot = height;} var auxiliary_phase2 = (myTime.getHours()*60+myTime.getMinutes()+myTime.getTimezoneOffset()); //REVISIT -- what is "offset" //var txtphase2 = 3.14159*2*(myTime.getHours()*60+offset+myTime.getMinutes()+myTime.getTimezoneOffset())/(24*60); var txtphase2 = 3.14159*2*(myTime.getHours()*60+myTime.getMinutes()+myTime.getTimezoneOffset())/(24*60); for (var j=1; j conf.south) { bottomy = height; if (lon > conf.north) { topy = 0; } else { topy = height * (conf.north - lon) / (conf.north - conf.south); } } } mc[mask].lineStyle(1,0x000000); mc[mask].beginFill(0x000000); mc[mask].moveTo(j,topy); mc[mask].lineTo(j,bottomy); mc[mask].lineTo(j+1,bottomy); mc[mask].lineTo(j+1,topy); mc[mask].lineTo(j,topy); mc[mask].endFill(); } //Scale and reposition mask to maskee //Need to do this every update?? mc[mask].origwidth = mc[id].origwidth; mc[mask].origheight = mc[id].origheight; mc[mask]._xscale = mc[id]._xscale; mc[mask]._yscale = mc[id]._yscale; mc[mask]._x = mc[id]._x; mc[mask]._y = mc[id]._y; } public function Pan():Void { interact.scaleAndPosition(imagemc,"day"); if (conf.displaytype == "daynight") { interact.scaleAndPosition(imagemc,"night"); interact.scaleAndPosition(imagemc,"dayMasker"); } //POLAR AND DYMAX?! for (var swf in conf.swflayer) { checkSwf(conf.swflayer[swf].parent, "swflayer" + swf); } checkSwfTemplate(); } static public function nextLayer():Number { layer++; return layer - 1; } static public function getmc():MovieClip { return imagemc; } public function highLoad():Boolean { return imagesLoading > conf.maximageload; } public function loadicon(mc:MovieClip, id:String):Boolean { if (imagemc[id].loaded) { var key:String = imagemc._name + ":" + id; mc.loadMovie(imglist[key].url); mc._x = - .5 * imglist[key]["mc"][id]._width; mc._y = - .5 * imglist[key]["mc"][id]._height; return true; } else { return false; } } public function loadrssicon(mc:MovieClip, url:String):Boolean { var key:String = imagemc._name + ":" + escape(url); if (imagemc[ escape(url) ].loaded) { mc.loadMovie(url); var w = imglist[key]["mc"][escape(url)]._width; var h = imglist[key]["mc"][escape(url)]._height; mc._xscale = 100 * conf.rssiconwidth / w; mc._yscale = 100 * conf.rssiconwidth / w; mc._x = - .5 * (conf.rssiconwidth); mc._y = - .5 * (conf.rssiconwidth * h / w); return true; } else if (imglist[ key ] == undefined) { loadImage(imagemc, escape(url), url, layer, "MakeInvisible", 0, 1, undefined, undefined, undefined, false); layer++; } return false; } public function activateicon(mc:MovieClip, url:String, iconwidth:Number) { var key:String = imagemc._name + ":" + escape(url); var w = imglist[key]["mc"][escape(url)]._width; var h = imglist[key]["mc"][escape(url)]._height; mc._xscale = 100 * iconwidth / w; mc._yscale = 100 * iconwidth / w; mc._x = - .5 * (iconwidth); mc._y = - .5 * (iconwidth * h / w); } }