Back to project page android-open-street-map.
The source code is released under:
Apache License
If you think the Android project android-open-street-map listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.android.lib.map.osm; //w w w . j a v a2s .c o m import java.util.LinkedList; import java.util.Queue; import android.graphics.Bitmap; import android.os.Handler; import android.os.Message; import com.android.lib.map.osm.models.MapTile; public class ResizedTilesCache extends Thread { private static int MAX_SCALE_FACTOR = 8; private LRUMap<String, Bitmap> mExtrapolatedBitmapCache = new LRUMap<String, Bitmap>(8,8); private Queue<Tile> mRequests = new LinkedList<Tile>(); private Tile mResizeTile; private TileScaler mTileScaler = new TileScaler(); private Object mLock = new Object(); private Handler mHandler; private Bitmap mMapTileUnavailableBitmap=null; public ResizedTilesCache(Handler handler) { this.mHandler = handler; start(); } public void setBitmapCacheSize(int size){ mExtrapolatedBitmapCache = new LRUMap<String, Bitmap>(size,size+2); } public void setMapTileUnavailableBitmap(Bitmap bitmap){ mMapTileUnavailableBitmap = bitmap; } public Tile findClosestMinusTile(Tile tile) { Tile minusZoomTile = generateMinusZoomTile(tile); //Log.i("findClosestCachedMinusTile", "LOOKING FOR zoom=" + tile.zoom + " mapX=" + tile.mapX + " mapY=" + tile.mapY); //Log.i("findClosestCachedMinusTile", "MinusTile LOOKING FOR zoom=" + minusZoomTile.zoom + " mapX=" + minusZoomTile.mapX + " mapY=" + minusZoomTile.mapY); if (minusZoomTile != null) { return minusZoomTile; } return null; } private Tile generateMinusZoomTile(Tile tile) { if (tile.zoom == 0) { return null; } Tile minusZoomTile = new Tile(); minusZoomTile.zoom = tile.zoom - 1; minusZoomTile.mapX = tile.mapX / 2; minusZoomTile.mapY = tile.mapY / 2; minusZoomTile.mapTypeId = tile.mapTypeId; minusZoomTile.key = minusZoomTile.zoom + "/" + minusZoomTile.mapX + "/" + minusZoomTile.mapY + ".png"; return minusZoomTile; } public void queueResize(Tile resizeRequest) { synchronized (mLock) { if(!hasRequest(resizeRequest) && !mExtrapolatedBitmapCache.containsKey(resizeRequest.key)) { mRequests.add(resizeRequest); } } synchronized (this) { this.notify(); } } private boolean hasRequest(Tile resizeRequest) { synchronized (mLock) { for(Tile request : mRequests) { if(request.key == resizeRequest.key) { return true; } } } return false; } @Override public void run() { while(true) { synchronized (mLock) { mResizeTile = mRequests.poll(); } if (mResizeTile != null) { Tile minusZoomTile = findClosestMinusTile(mResizeTile); if(minusZoomTile != null) { Bitmap minusZoomBitmap = null; float scaleFactor=0; while (minusZoomBitmap==null && scaleFactor < MAX_SCALE_FACTOR) { minusZoomBitmap = MapTile.getTile(minusZoomTile); if(minusZoomBitmap == null){ minusZoomTile = findClosestMinusTile(minusZoomTile); } if (minusZoomTile != null) { scaleFactor = (float)Math.pow(2,mResizeTile.zoom - minusZoomTile.zoom-1); } else { scaleFactor = MAX_SCALE_FACTOR; } } //System.out.println("FOUND TILE " + scaleFactor + " minusZoomBitmap = "+ minusZoomTile.zoom + " "+mResizeTile.zoom ); Bitmap closestBitmap = mTileScaler.scale(minusZoomBitmap, minusZoomTile, mResizeTile.mapX, mResizeTile.mapY,scaleFactor); if (closestBitmap != null) { synchronized (mLock) { mExtrapolatedBitmapCache.put(mResizeTile.key, closestBitmap); } }else{ synchronized (mLock) { mExtrapolatedBitmapCache.put(mResizeTile.key, mMapTileUnavailableBitmap);// to handle out of memory issues } } Message message = mHandler.obtainMessage(); message.arg1 = mRequests.size(); message.arg2 = 2; message.what = TileHandler.TILE_LOADED; mHandler.sendMessage(message); }else{ synchronized (mLock) { mExtrapolatedBitmapCache.put(mResizeTile.key, mMapTileUnavailableBitmap); //to handle resize limit exceeded } Message message = mHandler.obtainMessage(); message.arg1 = mRequests.size(); message.arg2 = 2; message.what = TileHandler.TILE_LOADED; mHandler.sendMessage(message); } } try { synchronized (this) { if(mRequests.size() == 0) { this.wait(); } } //Thread.sleep(50); } catch (InterruptedException e) { break; } } } public boolean hasTile(Tile tile) { return mExtrapolatedBitmapCache.containsKey(tile.key); } public Bitmap getTileBitmap(Tile tile) { synchronized (mLock) { return mExtrapolatedBitmapCache.get(tile.key); } } public void clear() { synchronized (mLock) { mExtrapolatedBitmapCache.clear(); } } class TileScaler { public Bitmap scale(Bitmap minusZoomBitmap, Tile minusZoomTile, int mapX, int mapY, float scaleFactor) { if (minusZoomBitmap == null) return null; Bitmap closestBitmap = scaleUpAndChop(minusZoomBitmap, minusZoomTile, mapX, mapY, scaleFactor); return closestBitmap; } private Bitmap scaleUpAndChop(Bitmap minusZoomBitmap, Tile minusZoomTile, int mapX, int mapY, float scaleFactor) { Bitmap scaledBitmap = null; int xIncrement = 1; if(minusZoomTile.mapX!= 1) { xIncrement = mapX % (int)(2*scaleFactor); } int yIncrement = 1; if(minusZoomTile.mapY != 1) { yIncrement = mapY % (int)(2*scaleFactor); } //scaledBitmap = BitmapScaler.scaleTo(minusZoomBitmap, mapX, mapY ,scaleFactor,(int)(256*2*scaleFactor), (int)(256*2*scaleFactor)); scaledBitmap = BitmapScaler.scaleTo(minusZoomBitmap, scaleFactor, xIncrement, yIncrement); return scaledBitmap; } } }