123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- /* COPYRIGHT 2012 SUPERMAP
- * 本程序只能在有效的授权许可下使用。
- * 未经许可,不得以任何手段擅自使用或传播。*/
- /**
- * @requires SuperMap/Tile.js
- */
-
- /**
- * Class: SuperMap.Tile.WebGLImage
- * 瓦片拼接类(webgl)。
- * 用于管理图层图像拼贴。
- *
- * Inherits from:
- * - <SuperMap.Tile>
- */
-
- SuperMap.Tile.WebGLImage = SuperMap.Class(SuperMap.Tile, {
- /**
- * Property: url
- * {String} The URL of the image being requested. No default. Filled in by
- * layer.getURL() function.
- * 图片的url。
- */
- url: null,
-
- /**
- * Property: newImgTag
- * {String} tile最近请求的image的标签。
- */
- newImgTag:null,
-
- /**
- * Property: canvasType
- */
- canvasType: null,
-
- /**
- * Property: frame
- * {DOMElement} The canvas element is appended to the frame. Any gutter on
- * the canvas will be hidden behind the frame.
- */
- frame: null,
-
- /**
- * Property: isLoading
- * {Boolean} Indicates if the tile is currently waiting on a loading image.
- */
- isLoading: false,
-
- /**
- * Property: canvas
- * {DOMElement} The canvas element on which the image is drawn.
- */
- canvas: null,
-
- /**
- * Property: lastImage
- * {Image} The last requested image object. This property is used to make sure
- * that only the recent image is drawn.
- */
- lastImage: null,
-
- /**
- * Property: lastBounds
- * {<SuperMap.Bounds>} The bounds of the last requested image, needed for
- * VirtualCanvasImage.displayImage().
- */
- lastBounds: null,
-
- /**
- * Property: isBackBuffer
- * {Boolean} Is this tile a back buffer tile?
- */
- isBackBuffer: false,
-
- /**
- * Property: backBufferTile
- * {<SuperMap.Tile>} A clone of the tile used to create transition
- * effects when the tile is moved or changes resolution.
- */
- backBufferTile: null,
-
- /**
- * Property: fadingTimer
- * {Number} 记录fading动画的索引ID
- *
- */
- fadingTimer:null,
- /**
- * Constructor: SuperMap.Tile.WebGLImage
- * 瓦片拼接类。
- *
- * Parameters:
- * layer - {<SuperMap.Layer>} 瓦片所在的图层。
- * position - {<SuperMap.Pixel>}左上角的点。
- * bounds - {<SuperMap.Bounds>}瓦片大小。
- * url - {<String>}瓦片对应的url地址。
- * size - {<SuperMap.Size>}瓦片的size。
- * canvasType -
- */
- initialize: function(layer, position, bounds, url, size, canvasType) {
- var me = this;
- SuperMap.Tile.prototype.initialize.apply(me, arguments);
- me.url = url; //deprecated remove me
- me.canvasType = canvasType;
- me.events.addEventType("reprojectionProgress");
- me.events.addEventType("filterProgress");
- },
- /**
- * APIMethod: destroy
- * 解构 WebGLImage 类,释放资源。
- */
- destroy: function() {
- SuperMap.Tile.prototype.destroy.apply(this, arguments);
- var me = this;
- me.lastImage = null;
- me.canvas = null;
- me.canvasContext = null;
- // clean up the backBufferTile if it exists
- if (me.backBufferTile) {
- me.backBufferTile.destroy();
- me.backBufferTile = null;
- me.layer.events.unregister("loadend", me, me.hideBackBuffer);
- }
- },
- /**
- * Method: clone
- * 创建当前类的副本。
- * Parameters:
- * obj - {<SuperMap.Tile.Image>} The tile to be cloned
- *
- * Returns:
- * {<SuperMap.Tile.Image>} An exact clone of this <SuperMap.Tile.WebGLImage>
- */
- clone: function (obj) {
- var me = this;
- if (obj == null) {
- obj = new SuperMap.Tile.WebGLImage(me.layer,
- me.position,
- me.bounds,
- me.url,
- me.size,
- me.canvasType);
- }
- //pick up properties from superclass
- obj = SuperMap.Tile.prototype.clone.apply(me, [obj]);
- // a new canvas element should be created for the clone
- obj.canvas = null;
- return obj;
- },
-
- /**
- * Method: draw
- * Check that a tile should be drawn, and draw it. Starts a
- * transition if the layer requests one.
- *
- * Returns:
- * {Boolean} Always returns true.
- */
- draw: function() {
- var me = this;
- if (me.layer != me.layer.map.baseLayer && me.layer.reproject) {
- me.bounds = me.getBoundsFromBaseLayer(me.position);
- }
- var drawTile = SuperMap.Tile.prototype.draw.apply(me, arguments);
- me.startTransition(drawTile);
- if (!drawTile) {
- return;
- }
- if (me.isLoading) {
- // if we're already loading, send 'reload' instead of 'loadstart'.
- me.events.triggerEvent("reload");
- } else {
- me.isLoading = true;
- me.events.triggerEvent("loadstart");
- }
- return me.renderTile();
- },
-
- /**
- * Method: startTransition
- * Creates a backbuffer tile (if it does not exist already)
- * and then displays this tile.
- *
- * Parameters:
- * drawTile - {<Boolean>} Should the tile be drawn?
- */
- startTransition: function(drawTile) {
- // <SuperMap.CanvasLayer.> takes care about the transition
- },
-
- /**
- * Method: renderTile
- * Creates the canvas element and sets the URL.
- *
- * Returns:
- * {Boolean} Always returns true.
- */
- renderTile: function() {
- var me = this;
- me.url = me.layer.getURL(me.bounds);
- me.positionImage();
- return true;
- },
-
- /**
- * Method: createImage
- * Creates the image and starts loading it.
- */
- createImage: function() {
- //如果在缓存的内存图片可以找到的话,就不再创建图片,直接调用图片的onLoad事件的响应函数
- //不过这里需要注意,制作专题图的时候,需要清除已经缓存的内存图片
- //否则有可能看不到专题图的图片。
-
- if (this.lastImage !== null && !this.lastImage.complete) {
- // 平移多次时候将不会请求图片,chrome下不能用。 https://bugs.webkit.org/show_bug.cgi?id=35377
- this.lastImage.src = '';
- }
-
- //先查看内存中是否有保存
- var me = this, image = me.layer.getMemoryImg(me.bounds);
- me.lastBounds = me.bounds.clone();
- if (image) {
- me.newImgTag = "";
- //找到就显示
- me.lastImage = image;
- me.layer.drawCanvasTile(image, me.position);
- if(me.firstInView){
- me.setFirstInView();
- }
- } else {
- //构造新的image对象
- var key = me.layer.getXYZ(me.bounds);
- //如果使用andriod加载,则需本地加载完成后重新设置url。否则直接加载
- if (!SuperMap.isApp) {
- me.newImgTag = key.x + "_" + key.y + "_" + key.z;
- me.loadTileImage();
- } else{
- var strX = key.x,
- strY = key.y,
- strZ;
- if(me.layer instanceof SuperMap.Layer.CloudLayer || me.layer.storageType=="db"){
- strZ = key.z;
- } else{
- strZ = me.layer.scales[key.z].toExponential();
- }
- var canvasImageContext = {
- tile: me,
- X: strX,
- Y: strY,
- Z: strZ,
- viewRequestID: me.layer.map.viewRequestID
- };
- me.newImgTag = strX + "_" + strY + "_" + strZ;
- // var saveUrlProxy = function() {
- // this.tile.onLoadsaveUrlFunction(this);
- // }
- me.lastImage = new Image();
-
- var methodName = me.getMethodName();
- var callBack = function(canvasImageContext,methodName){
- return function(r){
- window[methodName] = null;
- canvasImageContext.tile.onLoadsaveUrlFunction(canvasImageContext,r);
- }
- }(canvasImageContext,methodName);
- window[methodName] = callBack;
- /*window.plugins.localstoragemanager.getImg(me.url, me.layer.name, strX, strY, strZ,methodName,
- function(){},
- function(e){//errorfunction
- }
- ); */
- cordova.exec(function(){}, function(e){}, "LocalStoragePlugin","getImg", [me.url, me.layer.name, strX, strY, strZ,methodName]);
- }
- }
- },
-
- getMethodName:function(){
- var dateTime=new Date();
- var yy=dateTime.getFullYear();
- var MM1=dateTime.getMonth()+1; //因为1月这个方法返回为0,所以加1
- var dd=dateTime.getDate();
- var hh=dateTime.getHours();
- var mm=dateTime.getMinutes();
- var ss=dateTime.getSeconds();
- var ms = dateTime.getMilliseconds();
-
- var name = "getImgFromLocal_"+yy+MM1+dd+hh+mm+ss+ms+(Math.round(Math.random()*10000));
- return name;
- },
-
- //重置本地URL,加载图片
- onLoadsaveUrlFunction:function(canvasImageContext, r) {
- var me = this;
- var nowImgTag = r.x + "_" + r.y + "_" + r.z;
- if(me.newImgTag != nowImgTag){
- return;
- }
- if(r.data){
- if(r.data=="null"){
- return false;
- }
- var src = "data:image/jpeg;base64,"+r.data;
- }
- else{
- var src = me.layer.sdcardPath + "SuperMap/" + me.layer.name + "/" +
- canvasImageContext.Z + "/" + canvasImageContext.X + "_" + canvasImageContext.Y + ".png";
- }
- me.url = src;
- me.loadTileImage();
- },
-
- /**
- * Method: loadTileImage
- * 通过url加载图片,并对加载后的图片做缓存处理
- */
- loadTileImage: function(){
- var me = this,
- image = new Image();
- image.firstInView = true;
- me.lastImage = image;
- var context = {
- image: image,
- tile: me,
- viewRequestID: me.layer.map.viewRequestID,
- newImgTag: me.newImgTag
- //bounds: me.bounds.clone()// todo: do we still need the bounds? guess no
- //urls: this.layer.url.slice() // todo: for retries?
- };
-
- var onLoadFunctionProxy = function() {
- if(this.tile.newImgTag == this.newImgTag){
- this.tile.onLoadFunction(this);
- }
- };
- var onErrorFunctionProxy = function() {
- this.tile.onErrorFunction(this);
- };
-
- image.onload = SuperMap.Function.bind(onLoadFunctionProxy, context);
- image.onerror = SuperMap.Function.bind(onErrorFunctionProxy, context);
- //图片的url赋予给image后就会从服务器获取到图片
- image.src = me.url;
- },
-
- /**
- * Method: positionImage
- * Sets the position and size of the tile's frame and
- * canvas element.
- */
- positionImage: function() {
- var me = this;
- // if the this layer doesn't exist at the point the image is
- // returned, do not attempt to use it for size computation
- if (!me.layer) {
- return;
- }
- me.createImage();
- },
-
- /**
- * Method: onLoadFunction
- * Called when an image successfully finished loading. Draws the
- * image on the canvas. 图片加载成功后在canvas上进行绘制
- *
- * Parameters:
- * context - {<Object>} The context from the onload event.
- */
- onLoadFunction: function(context) {
- if ((this.layer === null) ||
- (context.viewRequestID !== this.layer.map.viewRequestID) ||
- (context.image !== this.lastImage)) {
- return;
- }
- this.canvasContext = null;
- var image = context.image;
- if(context.tile.shouldDraw){
- //绘制图片
- this.displayImage(image,context.newImgTag);
- }
- //保存图片缓存
- this.layer.addMemoryImg(this.lastBounds, image, context);
- },
- /**
- * APIMethod: drawImgData
- *
- * 重新绘制进行像素操作后的imgdata
- *
- * Parameters:
- * imgData - {<String>} canvas.toDataURL()得到的图片字符串
- * evt - {<Object>} tileloaded事件返回的事件对象,layer.events.on({tileloaded: function(evt) {}})
- */
- drawImgData:function(imgData,evt){
- var m,idx=evt.idx;
- m = new Image();
- m.onload = function(me,m,idx){
- return function(){
- if(idx==me.newImgTag){
- //m.firstInView = true;
- me.lastImage = m;
- me.layer.drawCanvasTile(m, me.position);
- }
- }
- }(this,m,idx);
- if(idx==this.newImgTag){
- m.src = imgData;
- }
- },
-
-
- /**
- * Method: displayImage
- * Takes care of resizing the canvas and then draws the
- * canvas.
- *
- * Parameters:
- * image - {Image/Canvas} The image to display
- * idx - {String} tile的标记
- */
- displayImage: function(image,idx) {
- var me = this,
- layer = me.layer;
- if (layer.canvasFilter && !image.filtered) {
- // if a filter is set, apply the filter first and
- // then use the result
- me.filter(image);
- return;
- }
- if(image.firstInView){
- me.setFirstInView();
- }
- //绘制图片
- layer.fixPosition();
- // layer.drawCanvasTile(image, me.position);
- //更新图片状态
- me.isLoading = false;
- me.events.triggerEvent("loadend",{"idx":idx});
- },
- /**
- * Method: onErrorFunction
- * Called when an image finished loading, but not successfully.
- *
- * Parameters:
- * context - {<Object>} The context from the onload event.
- */
- onErrorFunction: function(context) {
- var me = this;
- //图片请求失败,就不绘这个tile,防止调用canvasContext.drawImage方法出错。
- if (context.image !== me.lastImage) {
- /* Do not trigger 'loadend' when a new image was request
- * for this tile, because then 'reload' was triggered instead
- * of 'loadstart'.
- * If we would trigger 'loadend' now, Grid would get confused about
- * its 'numLoadingTiles'.
- */
- return;
- }
- //retry? with different url?
- me._attempts = (me._attempts) ? (me._attempts + 1) : 1;
- if (me._attempts <= SuperMap.IMAGE_RELOAD_ATTEMPTS) {
- if (me.layer.url && SuperMap.Util.isArray(me.layer.url) && me.layer.url.length > 1){
- me.layer._attempts = me._attempts;
- me.draw();
- return ;
- }
- }else
- {
- me._attempts = 0;
- }
-
- me.events.triggerEvent("loadend");
- },
- /**
- * Method: setFirstInView
- *
- */
- setFirstInView: function(){
- var me = this;
- if(!me.fadingTimer){
- var context = {
- canvasImage:me,
- image: me.lastImage
- };
- me.fadingTimer = window.setTimeout(SuperMap.Function.bind(me.setNotFirstInView, context),100);
- }
- },
- /**
- * Method: setNotFirstInView
- *
- */
- setNotFirstInView: function(){
- var me = this;
- // me.lastImage.firstInView = false;
- me.image.firstInView = false;
- window.clearTimeout(me.canvasImage.fadingTimer);
- me.canvasImage.fadingTimer = null;
- me.canvasImage.displayImage(me.image);
- },
- /**
- * Method: show
- * Show the tile. Called in <SuperMap.Tile.showTile()>.
- */
- show: function() {},
-
- /**
- * Method: hide
- * Hide the tile. To be implemented by subclasses (but never called).
- */
- hide: function() { },
-
- /**
- * Method: isTooBigCanvas
- * Used to avoid that the backbuffer canvas gets too big when zooming in very fast.
- * Otherwise drawing the canvas would take too long and lots of memory would be
- * required.
- */
- isTooBigCanvas: function(size) {
- return size.w > 5000;
- },
- /**
- * Method: moveTo
- *
- */
- moveTo: function (bounds, position, redraw) {
- if (redraw == null) {
- redraw = true;
- }
- this.bounds = bounds.clone();
- this.position = position.clone();
- //设置不重置canvas
- this.layer.redrawCanvas = false;
- if (redraw) {
- this.draw();
- }
- },
- CLASS_NAME: "SuperMap.Tile.WebGLImage"
- });
|