package com.androidol.layer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.view.animation.Animation.AnimationListener;
import com.androidol.Map;
import com.androidol.R;
import com.androidol.basetypes.Pixel;
import com.androidol.basetypes.Size;
import com.androidol.constants.UtilConstants;
import com.androidol.events.TileEvents;
import com.androidol.map.schema.TileSchema;
import com.androidol.tile.Tile;
import com.androidol.util.Util;
import com.androidol.util.tiles.TileProvider;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
public class Grid extends HTTPRequest implements UtilConstants {
// ===========================================================
// fields related to grid layer itself
// ===========================================================
protected TileSchema schema = null;
protected Size tileSize = null;
protected Coordinate tileOrigin = null;
protected boolean singleTile = false;
protected double ratio = 1.5;
public int numLoadingTiles = 0;
protected Pixel origin = null;
protected ArrayList<ArrayList<Tile>> grid = null;
protected TileProvider tileProvider = null;
protected TileEventsHandler tileEventsHandler = new TileEventsHandler();
// ===========================================================
// fields related to Android View
// ===========================================================
// ===========================================================
// Constructor
// ===========================================================
public Grid(Context context) {
super(context);
// TODO:
//this.singleTile = false; // by default set this.singleTile to false
//
this.grid = new ArrayList<ArrayList<Tile>>();
this.tileProvider = new TileProvider(context); // utilities dealing with tiles
this.tileProvider.events.registerAll(this.tileEventsHandler);
this.tileProvider.setOfflineMode(this.isOfflineMode);
this.tileProvider.setLayer(this);
}
public Grid(Context context, AttributeSet attrs) {
super(context, attrs);
// configuration options user could set through constructor:
// tileSize
// tileOrigin
// singleTile
// ratio
//
// TODO: apply configure options
// configure this.singleTile to true or false based on settings in layout xml
this.singleTile = attrs.getAttributeBooleanValue(ANDROIDOL_NAMESPACE, "isSingleTile", false);
//
this.grid = new ArrayList<ArrayList<Tile>>();
this.tileProvider = new TileProvider(context); // utilities dealing with tiles
this.tileProvider.events.registerAll(this.tileEventsHandler);
//
this.tileProvider.setOfflineMode(this.isOfflineMode);
this.tileProvider.setLayer(this);
}
/**
*
*/
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
//
this.canvas = canvas;
/*
if(this.dragging == true) {
this.canvas.translate(this.dragDx, this.dragDy);
this.dragging = false;
}
*/
//Util.printDebugMessage("... layer " + this.name + " onDraw() is callled...");
redraw();
//
}
/**
* Old Constructor Grid
*
* @param name
* @param url
* @param params
* @param options
*/
/*
public Grid(String name, String url, HashMap<String, String> params, HashMap<String, Object> options) {
super(name, url, params, options);
// configuration options user could set through constructor:
// tileSize
// tileOrigin
// singleTile
// ratio
//
// TODO: apply configure options
//
this.grid = new ArrayList<ArrayList<Tile>>();
}
*/
/**
* API Method: destroy
*
* @param newBaseLayer
* whether to set new base layer or not
*/
@Override
public void destroy(boolean newBaseLayer) {
this.clearGrid();
this.grid = null;
this.tileSize = null;
this.tileOrigin = null;
super.destroy(newBaseLayer);
}
/**
* API Method: clearGrid
*
* clean up the this.grid matrix
*/
public void clearGrid() {
if(this.grid != null && this.grid.size()>0) {
for(int iRow=0; iRow<this.grid.size(); iRow++) {
ArrayList<Tile> row = this.grid.get(iRow);
if(row!=null && row.size()>0) {
for(int iCol=0; iCol<row.size(); iCol++) {
Tile tile = row.get(iCol);
// TODO: this.removeTileMonitoringHooks(tile);
tile.destroy();
}
}
row.clear();
}
this.grid.clear();
}
}
/**
* dragTo(Coordinate oldCenter, Coordinate newCenter)
*
*/
@Override
public void drag(int dx, int dy) {
super.drag(dx, dy);
// TODO: deal with big delta where it's outof bounds
/*
* implement gridded tile shifting by changing the position of each by dx and dy in this.grid -
* - and redraw them
*/
shiftGriddedTiles(dx, dy);
spiralTileLoad();
postInvalidate();
/*
* implement gridded tile shifting by calling this.canvas.translate((float)dx, (float)dy) in each layer
*/
//shiftGriddedTilesUsingCanvas(dx, dy);
}
/**
* API Method: moveTo
*
* @param bounds
* @param zoomChanged
* @param dragging
*
*/
@Override
public void moveTo(Envelope bounds, boolean zoomChanged, boolean centerChanged) {
super.moveTo(bounds, zoomChanged, centerChanged);
//Util.printDebugMessage("@...Grid.moveTo() is called...");
if(bounds == null) {
bounds = this.map.getExtent();
}
//Util.printDebugMessage("zoom changed: " + zoomChanged);
//Util.printDebugMessage("center changed: " + centerChanged);
if(bounds != null) {
boolean forceReTile = false;
if(this.grid.size()==0 || zoomChanged) { // re-tiling when grid is empty or zoom level changed
forceReTile = true;
}
//Util.printDebugMessage(" ...is forced to re-tiling: " + forceReTile + "...");
Envelope tilesBounds = this.getTilesBounds();
if(this.singleTile == true) {
if(forceReTile==true || tilesBounds.contains(bounds)==false) {
//Util.printDebugMessage(" ...it is single tile...");
this.initSingleTile(bounds);
} else {
// just draw old tile
if(this.grid.size()>0) {
ArrayList<Tile> tiles = this.grid.get(0);
Tile singleTile = tiles.get(0);
if(singleTile != null) {
singleTile.draw(this.tileProvider, this.canvas, this.paint, createDrawSignature());
}
}
}
} else {
boolean forceInitGriddedTiles = false;
if(forceReTile==true || centerChanged==true) {
forceInitGriddedTiles = true;
}
//Util.printDebugMessage(" ...it is tile grid...");
if(forceInitGriddedTiles == true) {
this.initGriddedTiles(bounds);
} else {
this.spiralTileLoad();
}
// old code from OpenLayers
/*
if(forceReTile == true || tilesBounds.containsBounds(bounds, true, true)==false) {
//Util.printDebugMessage(" ...reload all tiles...", true);
this.initGriddedTiles(bounds);
printCurrentGridStatus();
} else {
//Util.printDebugMessage(" ...only shift tile grid...", true);
this.moveGriddedTiles(bounds);
printCurrentGridStatus();
}
*/
//printCurrentGridStatus();
}
}
}
/**
* API Method: setMap
*
* @param map
*/
@Override
public void setMap(Map map) {
super.setMap(map);
if(this.schema!=null && this.schema instanceof TileSchema) {
// do nothing
} else if(map.getMapSchema() instanceof TileSchema) {
this.schema = (TileSchema)map.getMapSchema();
} else {
// TODO: if map's schema only supports MapSchema interface
// throw exception or trying to associate a TileSchema to a MapSchema
//throw new Exception("...map's schema doesn't support TileSchema interface...");
}
if(this.singleTile == true) {
this.setImageSize(this.map.getSize());
this.setTileSize(this.map.getCurrentSize());
} else {
if(this.tileSize == null) { // inherit map's tile size if not set by constructor
this.tileSize = this.schema.getDefaultTileSize();
if(this.tileSize.getWidth() == 256 && this.tileSize.getHeight() == 256) {
this.tileProvider.setLoadingTile(BitmapFactory.decodeResource(context.getResources(), R.drawable.loading_256));
}
if(this.tileSize.getWidth() == 512 && this.tileSize.getHeight() == 512) {
this.tileProvider.setLoadingTile(BitmapFactory.decodeResource(context.getResources(), R.drawable.loading_512));
}
}
}
}
/**
* API Method: clone
*
*/
@Override
public Grid clone() {
// TODO: to be implemented
return null;
}
// old OpenLayers code
/*
private Bounds getGridBounds() {
return this.getTilesBounds();
}
*/
/**
* API Method: getTilesBounds
*
* @return bounds
* the extent where all tiles in grid cover
*/
public Envelope getTilesBounds() {
Envelope bounds = null;
if(this.grid!=null && this.grid.size()>0) {
int bottom = this.grid.size() - 1;
Tile bottomLeftTile = this.grid.get(bottom).get(0);
int right = this.grid.get(0).size() - 1;
Tile topRightTile = this.grid.get(0).get(right);
bounds = new Envelope(
bottomLeftTile.getBounds().getMinX(),
topRightTile.getBounds().getMaxX(),
bottomLeftTile.getBounds().getMinY(),
topRightTile.getBounds().getMaxY()
);
}
return bounds;
}
/**
* API Method: getTileBounds
*
* @param viewPortPx
* @return bounds
* given a point on screen, calculate the bounds of the tile which that point is in
*/
public Envelope getTileBounds(Pixel viewPortPx) {
Envelope maxExtent = this.maxExtent;
double resolution = this.getResolution();
double tileMapWidth= resolution * this.tileSize.getWidth();
double tileMapHeight = resolution * this.tileSize.getHeight();
Coordinate mapPoint = this.getCoordinateFromViewPortPx(viewPortPx);
double tileLeft = maxExtent.getMinX() + (tileMapWidth*Math.floor((mapPoint.x-maxExtent.getMinX())/tileMapWidth));
double tileBottom = maxExtent.getMinY() + (tileMapHeight*Math.floor((mapPoint.y-maxExtent.getMinY())/tileMapHeight));
return new Envelope(tileLeft, tileLeft + tileMapWidth, tileBottom, tileBottom + tileMapHeight);
}
/**
* API Method: initSingleTile
*
* @param bounds
*/
public void initSingleTile(Envelope bounds) {
//Util.printDebugMessage("@...Grid.initSingleTile() is called...");
Coordinate center = bounds.centre();
double tileWidth = bounds.getWidth() * this.ratio;
double tileHeight = bounds.getHeight() * this.ratio;
Envelope tileBounds =
new Envelope(
center.x - (tileWidth/2),
center.x + (tileWidth/2),
center.y - (tileHeight/2),
center.y + (tileHeight/2));
Coordinate ul = new Coordinate(tileBounds.getMinX(), tileBounds.getMaxY());
Pixel px = this.map.getLayerPxFromCoordinate(ul);
if(this.grid.size() == 0) {
this.grid.add(new ArrayList<Tile>());
}
Tile tile = null;
if(this.grid.get(0).size() > 0) {
tile = this.grid.get(0).get(0);
}
if(tile == null) {
tile = this.addTile(tileBounds, px, new Pixel(0,0), this.canvas, this.paint);
// TODO: this.addTileMonitoringHooks(tile);
this.grid.get(0).add(tile);
} else {
tile.moveTo(tileBounds, px); // move the tile
}
tile.draw(this.tileProvider, this.canvas, this.paint); // redraw the tile
this.removeExcessTiles(1,1);
}
/**
* shiftGriddedTiles(int dx, int dy)
*
* @param dx
* @param dy
*/
public void shiftGriddedTiles(int dx, int dy) {
if(this.grid != null) {
for(int i=0; i<this.grid.size(); i++) {
ArrayList<Tile> row = this.grid.get(i);
if(row != null) {
for(int j=0; j<row.size(); j++) {
Tile tile = row.get(j);
Pixel position = new Pixel(tile.getPosition().getX()+dx, tile.getPosition().getY()+dy);
tile.setPosition(position);
}
}
}
}
}
/**
* shiftGriddedTilesUsingMatrix(int dx, int dy)
*
* @param dx
* @param dy
*/
public void shiftGriddedTilesUsingMatrix(int dx, int dy) {
}
/**
* shiftGriddedTilesUsingMatrix(int dx, int dy)
*
* @param dx
* @param dy
*/
public void shiftGriddedTilesUsingCanvas(int dx, int dy) {
//Grid.this.canvas.translate((float)dx, (float)dy);
if(this.dragging == false) {
this.dragging = true;
}
this.dragDx = this.dragDx + (dx);
this.dragDy = this.dragDy + (dy);
invalidate();
}
/**
* API Method: initGriddedTiles
*
* @param bounds
*/
public void initGriddedTiles(Envelope bounds) {
//Util.printDebugMessage("@...Grid.initGriddedTiles() is called...");
//Util.printDebugMessage(" ...grid bounds: " + bounds.toString() + "...");
// get map width and height on screen e.g. 1024 * 768
Size viewSize = this.map.getSize();
// minimum number of tiles needed to cover the height of the map
int minRows = (int)Math.ceil(viewSize.getHeight()/this.tileSize.getHeight()) + Math.max(1, 2 * this.buffer);
//Util.printDebugMessage(" ...minimum rows needed: " + minRows + "...");
// minimum number of tiles needed to cover the width of the map
int minCols = (int)Math.ceil(viewSize.getWidth()/this.tileSize.getWidth()) + Math.max(1, 2 * this.buffer);
//Util.printDebugMessage(" ...minimum cols needed: " + minCols + "...");
// maximum extent of the map
Envelope extent = this.getMaxExtent();
// map resolution meaning how many meters/degrees does one pixel represent on map
double resolution = this.map.getResolution();
// 'tilelon' and 'tilelat' are how many meters/degrees does a tile cover on map
double tilelon = resolution * this.tileSize.getWidth();
double tilelat = resolution * this.tileSize.getHeight();
// distance between left-most point of maxExtent and left-most point of current extent
double offsetlon = bounds.getMinX() - extent.getMinX();
// number of tiles needed to cover the space
// between left-most point of maxExtent and left-most point of current extent
int tilecol = (int)Math.floor(offsetlon/tilelon) - this.buffer;
// the fractional tile needed to reach the left-most point of current extent
double tilecolremain = offsetlon/tilelon - tilecol;
// how many pixels this fractional tile represent
double tileoffsetx = -tilecolremain * this.tileSize.getWidth();
// the lon where the left-most tile starts to cover the map current extent
double tileoffsetlon = extent.getMinX() + tilecol * tilelon;
// distance between bottom-most point of maxExtent and top-most point of current extent
// plus one more tile span
double offsetlat = bounds.getMaxY() - (extent.getMinY() + tilelat);
// number of tiles needed to cover the space
// between bottom-most point of maxExtent and top-most point of current extent
int tilerow = (int)Math.ceil(offsetlat/tilelat) + this.buffer;
// the fractional tile needed to reach the top-most point of current extent
double tilerowremain = tilerow - offsetlat/tilelat;
// how many pixels this fractional tile represent
double tileoffsety = -tilerowremain * this.tileSize.getHeight();
// the lat where the bottom-most tile starts to cover the map current extent
double tileoffsetlat = extent.getMinY() + tilerow * tilelat;
// God help us
tileoffsetx = Math.round(tileoffsetx);
tileoffsety = Math.round(tileoffsety);
// the position on screen where the top-left tile should be placed
this.origin = new Pixel(tileoffsetx, tileoffsety);
double startX = tileoffsetx;
double startLon = tileoffsetlon;
int rowidx = 0;
int colidx = 0;
//long startTime = System.currentTimeMillis();
do {
ArrayList<Tile> row = null;
if(rowidx >= this.grid.size() || this.grid.get(rowidx) == null) {
row = new ArrayList<Tile>();
this.grid.add(row);
} else {
row = this.grid.get(rowidx);
}
rowidx++;
tileoffsetlon = startLon;
tileoffsetx = startX;
colidx = 0;
do {
Envelope tileBounds = new Envelope(
tileoffsetlon,
tileoffsetlon + tilelon,
tileoffsetlat,
tileoffsetlat + tilelat);
double x = tileoffsetx;
//x -= (int)(this.map.getLayerContainerCanvasLeft()); // this.map.getLayerContainerCanvasLeft() should always be 0.0
double y = tileoffsety;
//y -= (int)(this.map.getLayerContainerCanvasTop()); // this.map.getLayerContainerCanvasTop() should always be 0.0
Pixel px = new Pixel(x, y);
Tile tile = null;
if(colidx >= row.size() || row.get(colidx) == null) {
//Util.printDebugMessage(" ...add tile..." + "bounds: " + tileBounds.toString() + " position: " + px.toString() + "...");
//Util.printDebugMessage(" ...add tile..." + this.getUrl(tileBounds) + "...");
tile = this.addTile(tileBounds, px, new Pixel(rowidx, colidx), this.canvas, this.paint);
// TODO: this.addTileMonitoringHooks(tile);
row.add(tile);
} else {
//Util.printDebugMessage(" ...move tile to..." + "bounds: " + tileBounds.toString() + "...");
//Util.printDebugMessage(" ...move tile to..." + this.getUrl(tileBounds) + "...");
tile = row.get(colidx);
tile.moveTo(tileBounds, px);
}
colidx++;
tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.getWidth();
} while((tileoffsetlon <= bounds.getMaxX() + tilelon * this.buffer) || colidx < minCols);
tileoffsetlat -= tilelat;
tileoffsety += this.tileSize.getHeight();
} while((tileoffsetlat >= bounds.getMinY() - tilelat * this.buffer) || rowidx < minRows);
//String timeSpent = Long.toString(System.currentTimeMillis()-startTime);
//Util.printDebugMessage(" ...calculating tile matrix: " + timeSpent + "ms");
this.removeExcessTiles(rowidx, colidx);
/*
Util.printDebugMessage(" ...grid rows number: " + this.grid.size() + "...");
for(int i=0; i<this.grid.size(); i++) {
Util.printDebugMessage(" ...grid row : " + i + " col: " + this.grid.get(i).size() + "...");
}
*/
this.spiralTileLoad();
}
/**
* private method: spiralTileLoad
*
*
*/
private void spiralTileLoad() {
//Util.printDebugMessage("@...Grid.spiralTileLoad() is called...");
ArrayList<Tile> tileQueue = new ArrayList<Tile>();
String[] directions = {"right", "down", "left", "up"};
int iRow = 0;
int iCell = -1;
int direction = 0; // 'right'
int directionsTried = 0;
while(directionsTried < directions.length) {
int testRow = iRow;
int testCell = iCell;
if(directions[direction].equalsIgnoreCase("right") == true) {
testCell++;
}
if(directions[direction].equalsIgnoreCase("down") == true) {
testRow++;
}
if(directions[direction].equalsIgnoreCase("left") == true) {
testCell--;
}
if(directions[direction].equalsIgnoreCase("up") == true) {
testRow--;
}
// if the test grid coordinates are within the bounds of the
// grid, get a reference to the tile.
Tile tile = null;
if((testRow < this.grid.size()) && (testRow >= 0) && (testCell < this.grid.get(0).size()) && (testCell >= 0)) {
tile = this.grid.get(testRow).get(testCell);
}
if((tile != null) && (tile.isQueued()==false)) {
//add tile to beginning of queue, mark it as queued.
tileQueue.add(0, tile);
tile.setQueued(true);
//Util.printDebugMessage(" ...spirally load tile: (" + testRow + "," + testCell + ")...");
//restart the directions counter and take on the new coords
directionsTried = 0;
iRow = testRow;
iCell = testCell;
} else {
//need to try to load a tile in a different direction
direction = (direction + 1) % 4;
directionsTried++;
}
}
// now go through and draw the tiles in forward order
//Util.printDebugMessage(" ...tiles are queued to be loaded...");
//Util.printDebugMessage(" ...number of tiles to load: " + tileQueue.size() + "...");
for(int i=0, len=tileQueue.size(); i<len; i++) {
Tile tile = tileQueue.get(i);
tile.draw(this.tileProvider, this.canvas, this.paint, createDrawSignature());
tile.setQueued(false);
}
}
/**
* createDrawSignature()
* @return String
*/
private String createDrawSignature() {
return this.map.createDrawSignature();
}
/**
* cancelLoadingThreads()
*/
@Override
public void cancelLoadingThreads() {
getTileProvider().cleanupHTTPLoaderThreadQueue(createDrawSignature());
getTileProvider().cleanupFSLoaderThreadQueue(createDrawSignature());
}
/**
* API Method: addTile
*
* @param bounds
* @param position
*
* @return tile
*/
public Tile addTile(Envelope bounds, Pixel position, Pixel cell, Canvas canvas, Paint paint) {
// to be implemented by subclass
return null;
}
/**
* API Method: ,ergeNewParams
*
* @param newParams
*/
@Override
public void mergeNewParams(HashMap<String, String> newParams) {
super.mergeNewParams(newParams);
if(this.map != null) {
// when new parameters are merged in, url for each tile could change
// so do a re-tiling
//moveTo(this.map.getExtent(), false, false);
}
}
/**
* API Method: removeExcessTiles
*
* @param rows
* @param columns
*/
public void removeExcessTiles(int rows, int columns) {
//Util.printDebugMessage("@...Grid.removeExcessTiles() is called...");
ArrayList<Tile> row = null;
Tile tile = null;
while(this.grid.size() > rows) {
row = this.grid.remove(this.grid.size()-1); /* this.grid.pop() */
//Util.printDebugMessage(" ...one row of tiles removed from grid...");
for(int i=0,l=row.size(); i<l; i++) {
tile = row.get(i);
//this.removeTileMonitoringHooks(tile);
tile.destroy();
}
this.grid.trimToSize();
}
while(this.grid.get(0).size() > columns) {
//Util.printDebugMessage(" ...one column of tiles removed from grid...");
for(int i=0, l=this.grid.size(); i<l; i++) {
row = this.grid.get(i);
tile = row.remove(row.size()-1); /* row.pop() */
row.trimToSize();
//this.removeTileMonitoringHooks(tile);
tile.destroy();
}
}
}
/**
* API Method: onMapResize
*
*/
@Override
public void onMapResize() {
if(this.singleTile == true) {
this.clearGrid();
this.tileSize = null;
this.setTileSize(this.map.getCurrentSize());
this.initSingleTile(this.map.getExtent());
}
}
/**
* API Method: setTileSize
*/
public void setTileSize(Size size) {
if(this.singleTile == true) {
Size newSize = size.clone();
newSize.setHeight((int)(size.getHeight() * this.ratio));
newSize.setWidth((int)(size.getWidth() * this.ratio));
this.tileSize = newSize;
} else {
this.tileSize = size;
}
}
/**
*
* @return the tileSize
*/
public Size getTileSize() {
return this.tileSize;
}
/**
* @return the imageSize
*/
@Override
public Size getImageSize() {
if(this.imageSize == null) {
this.imageSize = this.map.getSize();
}
if(this.imageSize == null) {
return this.tileSize;
} else {
return this.imageSize;
}
}
/**
* @return the origin
*/
public Pixel getOrigin() {
return origin;
}
/**
* @param origin the origin to set
*/
public void setOrigin(Pixel origin) {
this.origin = origin;
}
/**
* API Method: getMissingTileUrl
*
* @return url
* the url to a missing tile resource
*/
public String getMissingTileUrl() {
String missing_url = this.schema.getMissingTileUri();
if(missing_url != null && missing_url.equalsIgnoreCase("")==false) {
return missing_url;
} else {
return Util.DEFAULT_MISSING_TILE_URL;
}
}
/**
* API Method: getTransparentTileUrl
*
* @return url
* the url to a transparent tile resource
*/
public String getTransparentTileUrl() {
String transparent_url = this.schema.getTransparentTileUri();
if(transparent_url != null && transparent_url.equalsIgnoreCase("")==false) {
return transparent_url;
} else {
return Util.DEFAULT_TRANSPARENT_TILE_URL;
}
}
/**
* @return the singleTile
*/
public boolean isSingleTile() {
return singleTile;
}
/**
* @param singleTile the singleTile to set
*/
public void setSingleTile(boolean singleTile) {
this.singleTile = singleTile;
}
/**
* @return the tileOrigin
*/
public Coordinate getTileOrigin() {
return tileOrigin;
}
/**
* @param tileOrigin the tileOrigin to set
*/
public void setTileOrigin(Coordinate tileOrigin) {
this.tileOrigin = tileOrigin;
}
public TileProvider getTileProvider() {
return tileProvider;
}
public void setTileProvider(TileProvider tileProvider) {
this.tileProvider = tileProvider;
}
// ===========================================================
// utilities functions
// ===========================================================
/**
* private method: printCurrentGridStatus
*/
protected void printCurrentGridStatus() {
if(this.grid.size() == 0) { return; }
Log.i(DEBUGTAG, " //=============================================================================");
for(int i=0; i<this.grid.size(); i++) {
ArrayList<Tile> row = this.grid.get(i);
if(row.size() == 0) { continue; }
for(int j=0; j<row.size(); j++) {
Tile col = row.get(j);
Log.i(DEBUGTAG, " //...tile position: " + col.getPosition().toString());
Log.i(DEBUGTAG, " //...tile url: " + col.getUrl());
}
}
Log.i(DEBUGTAG, " //=============================================================================");
}
/**
*
* @author
*
*/
private class TileEventsHandler extends Handler {
@Override
public void handleMessage(final Message msg) {
switch(msg.what) {
case TileEvents.HTTP_LOAD_SUCCESS:
//Util.printDebugMessage(" ...TileEventsHandler: http load success...");
// uncomment this when using memory tile cache
//Grid.this.redraw(); // TODO: redraw() or postInvalidate()?
// uncomment this when using file system only tile cache
Grid.this.postInvalidate(); // TODO: redraw() or postInvalidate()?
break;
case TileEvents.FS_LOAD_SUCCESS:
//Util.printDebugMessage(" ...TileEventsHandler: fs load success...");
//if(Grid.this.getTileProvider().isFSStillLoading() == false) {
//Util.printDebugMessage("...layer postInvalidate() is called because fs loader pending queue is 0...");
Grid.this.postInvalidate();
//}
break;
case TileEvents.FS_TILE_CORRUPTED:
//Util.printDebugMessage(" ...TileEventsHandler: fs tile corrupted...");
break;
case TileEvents.HTTP_TILE_INACCESSIBLE:
//Util.printDebugMessage(" ...TileEventsHandler: http tile inaccessible...");
break;
case TileEvents.MEM_LOAD_SUCCESS:
//Util.printDebugMessage(" ...MapViewUpdateListener: mem load success...");
break;
case TileEvents.HTTP_LOAD_FAILURE:
//Util.printDebugMessage(" ...TileEventsHandler: http load failure...");
break;
case TileEvents.FS_LOAD_FAILURE:
//Util.printDebugMessage(" ...TileEventsHandler: fs load failure...");
break;
case TileEvents.MEM_LOAD_FAILURE:
//Util.printDebugMessage(" ...TileEventsHandler: mem load failure...");
break;
}
}
}
}