package com.androidol.tile; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import com.androidol.R; import com.androidol.basetypes.Pixel; import com.androidol.basetypes.Size; import com.androidol.events.Event; import com.androidol.events.TileEvents; import com.androidol.layer.Layer; import com.androidol.util.Util; import com.androidol.util.tiles.TileProvider; import com.vividsolutions.jts.geom.Envelope; public class Image extends Tile { //private TileProvider tileProvider = null; protected Canvas canvas = null; protected Paint paint = null; /** * Constructor Image * * @param layer * @param position * @param bounds * @param url * @param size * */ public Image(Layer layer, Pixel position, Pixel cell, Envelope bounds, String url, Size size, Canvas canvas, Paint paint) { super(layer, position, cell, bounds, url, size); this.canvas = canvas; this.paint = paint; } /** * API Method: destroy */ @Override public void destroy() { this.clear(); super.destroy(); } /** * API Method: draw * * @param tileProvider * @param canvas * @param paint */ @Override public boolean draw(TileProvider tileProvider, Canvas canvas, Paint paint) { return draw(tileProvider, canvas, paint, null); } /** * API Method: draw * * @param tileProvider * @param canvas * @param paint */ @Override public boolean draw(TileProvider tileProvider, Canvas canvas, Paint paint, String signature) { //Util.printDebugMessage("@...Image.draw() is called..."); //this.tileProvider = tileProvider; this.clear(); if(this.layer != this.layer.getMap().getBaseLayer()) { //Util.printDebugMessage(" ...layer is not base layer...get bounds from base layer..."); this.bounds = this.getBoundsFromBaseLayer(this.position); } if(super.draw() == false) { //Util.printDebugMessage(" ...not drawing tile..." + this.getLayer().getUrl(this.getBounds()) + "..."); return false; } else { //Util.printDebugMessage(" ...drawing tile..." + this.getLayer().getUrl(this.getBounds()) + "..."); // only attache ImageTileListener to tile when you need to draw the tile //Util.printDebugMessage(" ...attache ImageTileListener to tile..."); //tileProvider.events.registerAll(new ImageTileListener()); } //if(this.url == null) { //Util.printDebugMessage(" ...tile bounds: " + this.bounds + "..."); this.url = this.layer.getUrl(this.bounds); //} //Util.printDebugMessage(" ...draw tile from url: " + this.url + "..."); //Util.printDebugMessage(" ...draw this tile at pixel: " + this.position.toString() + "..."); //tileProvider.addToPendingQueue(this.url); // TODO: may have conflict when two different layer requesting same tile same time //tileProvider.addToPendingMatrix(this); Bitmap tile = null; if(this.layer.isBaseLayer() == true) { tile = tileProvider.getTile(this.url, signature, this); // if it is baselayer use the 'loading' tile when loading } else { tile = tileProvider.getTile(this.url, signature, tileProvider.getTransparentTile(), this); // if it is non-baselayer use the transparent tile when loading } // TODO: call paint.setAlpha() to deal with layer transparency if(this.layer.getOpacity() < 1) { //Util.printDebugMessage(String.valueOf((int)(this.layer.getOpacity()*255))); paint.setAlpha((int)(this.layer.getOpacity()*255)); } //paint.setAlpha((int)(0.64*255)); if(tile!=null && tile.isRecycled()==false) { canvas.drawBitmap(tile, (int)this.position.getX(), (int)this.position.getY(), paint); } return true; } /** * API Method: clear */ @Override public void clear() { super.clear(); // TODO: remove event listener if there is any } /** * @return the queued */ public boolean isQueued() { return queued; } /** * @param queued the queued to set */ public void setQueued(boolean queued) { this.queued = queued; } public Canvas getCanvas() { return canvas; } public void setCanvas(Canvas canvas) { this.canvas = canvas; } public Paint getPaint() { return paint; } public void setPaint(Paint paint) { this.paint = paint; } /* private class ImageTileListener extends Handler { @Override public void handleMessage(final Message msg) { switch(msg.what) { case TileEvents.HTTP_LOAD_SUCCESS: //Util.printDebugMessage(" ...ImageTileListener: http load success..."); //Util.printDebugMessage(" ...unattache ImageTileListener from tile..."); // the data carried with HTTP_LOAD_SUCCESS message event is byte[] containing the image try { Object obj_http = msg.obj; byte[] data_http = (byte[])((Event)obj_http).properties.get("data"); if(data_http != null) { Bitmap tile_http = BitmapFactory.decodeByteArray(data_http, 0, data_http.length); //Util.printDebugMessage(" ...draw tile from HTTP..."); Image.this.canvas.drawBitmap(tile_http, (int)Image.this.position.getX(), (int)Image.this.position.getY(), Image.this.paint); } } catch(Exception e) { Util.printErrorMessage(" ...exception in drawing tile directly from HTTP..."); Util.printErrorMessage(e.toString()); } Image.this.tileProvider.events.unregister(TileEvents.HTTP_LOAD_SUCCESS, this); break; case TileEvents.FS_LOAD_SUCCESS: //Util.printDebugMessage(" ...ImageTileListener: fs load success..."); //Util.printDebugMessage(" ...unattache ImageTileListener from tile..."); // the data carried with FS_LOAD_SUCCESS message event is a bitmap try { Object data_fs = msg.obj; Bitmap tile_fs = (Bitmap)((Event)data_fs).properties.get("data"); if(tile_fs != null) { Image.this.canvas.drawBitmap(tile_fs, (int)Image.this.position.getX(), (int)Image.this.position.getY(), Image.this.paint); } //Util.printDebugMessage(" ...draw tile..." + Image.this.getUrl() + " directly when received from FS...not invalidating the map..."); } catch(Exception e) { Util.printErrorMessage(" ...exception in drawing tile..." + Image.this.getUrl() + " directly from FS..."); Util.printErrorMessage(e.toString()); } Image.this.tileProvider.events.unregister(TileEvents.FS_LOAD_SUCCESS, this); // TODO: update tileProvider pending queue Image.this.tileProvider.removeFromPendingQueue(Image.this.getUrl()); Util.printDebugMessage(" ...TileProvider pending queue size " + Image.this.tileProvider.getPendingQueueSize() + "..."); break; case TileEvents.MEM_LOAD_SUCCESS: //Util.printDebugMessage(" ...ImageTileListener: mem load success..."); //Util.printDebugMessage(" ...unattache ImageTileListener from tile..."); //Util.printDebugMessage(" ...draw tile directly when received from Mem...not invalidating the map..."); Image.this.tileProvider.events.unregister(TileEvents.MEM_LOAD_SUCCESS, this); break; case TileEvents.HTTP_LOAD_FAILURE: Util.printDebugMessage(" ...ImageTileListener: http load failure..."); Image.this.tileProvider.events.unregister(TileEvents.HTTP_LOAD_FAILURE, this); break; case TileEvents.FS_LOAD_FAILURE: //Util.printDebugMessage(" ...ImageTileListener: fs load failure..."); Image.this.tileProvider.events.unregister(TileEvents.FS_LOAD_FAILURE, this); break; case TileEvents.MEM_LOAD_FAILURE: //Util.printDebugMessage(" ...ImageTileListener: mem load failure..."); Image.this.tileProvider.events.unregister(TileEvents.MEM_LOAD_FAILURE, this); break; case TileEvents.FS_TILE_CORRUPTED: //Util.printDebugMessage(" ...ImageTileListener: fs tile corrupted..."); Image.this.tileProvider.events.unregister(TileEvents.FS_TILE_CORRUPTED, this); break; case TileEvents.HTTP_TILE_INACCESSIBLE: Util.printDebugMessage(" ...ImageTileListener: http tile inaccessible..."); Image.this.tileProvider.events.unregister(TileEvents.HTTP_TILE_INACCESSIBLE, this); break; } } }*/ }