osmdroid API解读(四)

来源:互联网 发布:淘宝买家秀大尺度下载 编辑:程序博客网 时间:2024/06/05 20:50

osmdroid API解读(四)

osmdroid-android模块 org.osmdroid.tileprovider包(一)

1.MapTile

地图瓦片使用观察者模式分割,瓦片由tile provider下发。本类必须保持不变,因为其备用于缓存hash map的key

public class MapTile {    public static final int MAPTILE_SUCCESS_ID = 0;    public static final int MAPTILE_FAIL_ID = MAPTILE_SUCCESS_ID + 1;    private final int x;//瓦片的坐标位置x    private final int y;//瓦片的坐标位置y    private final int zoomLevel;//该瓦片缩放等级    private Date expires;//瓦片到期时间    public MapTile(final int zoomLevel, final int tileX, final int tileY) {        this.zoomLevel = zoomLevel;        this.x = tileX;        this.y = tileY;    }    public Date getExpires() {        return expires;    }    public void setExpires(Date expires) {        this.expires = expires;    }    public int getZoomLevel() {        return zoomLevel;    }    public int getX() {        return x;    }    public int getY() {        return y;    }    @Override    public String toString() {        return "/" + zoomLevel + "/" + x + "/" + y;    }    @Override    public boolean equals(final Object obj) {        if (obj == null)            return false;        if (obj == this)            return true;        if (!(obj instanceof MapTile))            return false;        final MapTile rhs = (MapTile) obj;        return zoomLevel == rhs.zoomLevel && x == rhs.x && y == rhs.y;    }    @Override    public int hashCode() {        int code = 17;        code *= 37 + zoomLevel;        code *= 37 + x;        code *= 37 + y;        return code;    }}

1.1 LRUMapTileCache

瓦片集合缓存,继承自LinkedHashMap,以MapTile(用于定位图片位置)为key,Drawable为value。用于管理一系列的瓦片。

public class LRUMapTileCache extends LinkedHashMap<MapTile, Drawable> {    public interface TileRemovedListener {        void onTileRemoved(MapTile mapTile);    }    private static final long serialVersionUID = -541142277575493335L;    private int mCapacity;//瓦片容量    private TileRemovedListener mTileRemovedListener;//瓦片移除监听器    public LRUMapTileCache(final int aCapacity) {        super(aCapacity + 2, 0.1f, true);        mCapacity = aCapacity;    }    public void ensureCapacity(final int aCapacity) {        if (aCapacity > mCapacity) {            Log.i(IMapView.LOGTAG, "Tile cache increased from " + mCapacity + " to " + aCapacity);            mCapacity = aCapacity;        }    }    @Override//移除瓦片    public Drawable remove(final Object aKey) {        final Drawable drawable = super.remove(aKey);        // Only recycle if we are running on a project less than 2.3.3 Gingerbread.        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {            if (drawable instanceof BitmapDrawable) {                final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();                if (bitmap != null) {                    bitmap.recycle();                }            }        }        if (getTileRemovedListener() != null && aKey instanceof MapTile)            getTileRemovedListener().onTileRemoved((MapTile) aKey);        if (drawable instanceof ReusableBitmapDrawable)            BitmapPool.getInstance().returnDrawableToPool((ReusableBitmapDrawable) drawable);        return drawable;    }    @Override//清除所有瓦片    public void clear() {        // remove them all individually so that they get recycled        while (!isEmpty()) {            remove(keySet().iterator().next());        }        // and then clear        super.clear();    }    @Override    protected boolean removeEldestEntry(final java.util.Map.Entry<MapTile, Drawable> aEldest) {        if (size() > mCapacity) {            final MapTile eldest = aEldest.getKey();            if (Configuration.getInstance().isDebugMode()) {                    Log.d(IMapView.LOGTAG,"LRU Remove old tile: " + eldest);            }            remove(eldest);            // don't return true because we've already removed it        }        return false;    }    public TileRemovedListener getTileRemovedListener() {        return mTileRemovedListener;    }    public void setTileRemovedListener(TileRemovedListener tileRemovedListener) {        mTileRemovedListener = tileRemovedListener;    }}

1.2 MapTileCache

持有瓦片集合LRUMapTileCache,并有相应的瓦片操作方法

public class MapTileCache {    protected final Object mCachedTilesLockObject = new Object();    protected LRUMapTileCache mCachedTiles;//持有的瓦片集合    public MapTileCache() {        this(Configuration.getInstance().getCacheMapTileCount());    }    //最大缓存尺寸    public MapTileCache(final int aMaximumCacheSize) {        this.mCachedTiles = new LRUMapTileCache(aMaximumCacheSize);    }    public void ensureCapacity(final int aCapacity) {        synchronized (mCachedTilesLockObject) {            mCachedTiles.ensureCapacity(aCapacity);        }    }    public Drawable getMapTile(final MapTile aTile) {        synchronized (mCachedTilesLockObject) {            return this.mCachedTiles.get(aTile);        }    }    public void putTile(final MapTile aTile, final Drawable aDrawable) {        if (aDrawable != null) {            synchronized (mCachedTilesLockObject) {                this.mCachedTiles.put(aTile, aDrawable);            }        }    }    public boolean containsTile(final MapTile aTile) {        synchronized (mCachedTilesLockObject) {            return this.mCachedTiles.containsKey(aTile);        }    }    public void clear() {        synchronized (mCachedTilesLockObject) {            this.mCachedTiles.clear();        }    }}

2.ExpirableBitmapDrawable

可过期图片,提供了不同的时间状态(更新状态 过期 缩放 没有发现 等状态)。

public class ExpirableBitmapDrawable extends BitmapDrawable {    //状态    public static final int UP_TO_DATE  = -1;    public static final int EXPIRED     = -2;    public static final int SCALED      = -3;    public static final int NOT_FOUND   = -4;    private static final int defaultStatus  = UP_TO_DATE;    private static final int[] settableStatuses = new int[] {EXPIRED, SCALED, NOT_FOUND};    private int[] mState;    public ExpirableBitmapDrawable(final Bitmap pBitmap) {        super(pBitmap);        mState = new int[0];    }    @Override    public int[] getState() {        return mState;    }    @Override    public boolean isStateful() {        return mState.length > 0;    }    @Override    public boolean setState(final int[] pStateSet) {        mState = pStateSet;        return true;    }    @Deprecated    public static boolean isDrawableExpired(final Drawable pTile) {        return getState(pTile) == EXPIRED;    }    public static int getState(final Drawable pTile) {        for(final int statusItem : pTile.getState()) {            for (final int statusReference : settableStatuses) {                if (statusItem == statusReference) {                    return statusItem;                }            }        }        return defaultStatus;    }    /**     * @deprecated use {@link #setState(Drawable, int)} instead     */    @Deprecated    public static void setDrawableExpired(final Drawable pTile) {        setState(pTile, EXPIRED);    }    public static void setState(final Drawable pTile, final int status) {        pTile.setState(new int[]{status});    }}

2.1 ReusableBitmapDrawable

继承自ExpirableBitmapDrawable,保持对图片使用引用跟踪。具体看内部方法。

public class ReusableBitmapDrawable extends ExpirableBitmapDrawable {    private boolean mBitmapRecycled = false;    private int mUsageRefCount = 0;    public ReusableBitmapDrawable(Bitmap pBitmap) {        super(pBitmap);    }    //开始使用图片    public void beginUsingDrawable() {        synchronized (this) {            mUsageRefCount++;        }    }    //结束使用图片    public void finishUsingDrawable() {        synchronized (this) {            mUsageRefCount--;            if (mUsageRefCount < 0)                throw new IllegalStateException("Unbalanced endUsingDrawable() called.");        }    }    //回收    public Bitmap tryRecycle() {        synchronized (this) {            if (mUsageRefCount == 0) {                mBitmapRecycled = true;                return getBitmap();            }        }        return null;    }    //检测是否有效    public boolean isBitmapValid() {        synchronized (this) {            return !mBitmapRecycled;        }    }}

2.2 BitmapPool

持有并管理所有的瓦片图片。

public class BitmapPool {    final LinkedList<Bitmap> mPool = new LinkedList<Bitmap>();    private static BitmapPool sInstance;    public static BitmapPool getInstance() {        if (sInstance == null)            sInstance = new BitmapPool();        return sInstance;    }    public void returnDrawableToPool(ReusableBitmapDrawable drawable) {        Bitmap b = drawable.tryRecycle();        if (b != null && b.isMutable())            synchronized (mPool) {                mPool.addLast(b);            }    }    public void applyReusableOptions(final BitmapFactory.Options aBitmapOptions) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {            aBitmapOptions.inBitmap = obtainBitmapFromPool();            aBitmapOptions.inSampleSize = 1;            aBitmapOptions.inMutable = true;        }    }    public Bitmap obtainBitmapFromPool() {        synchronized (mPool) {            if (mPool.isEmpty()) {                return null;            } else {                final Bitmap bitmap = mPool.removeFirst();                if (bitmap.isRecycled()) {                    return obtainBitmapFromPool(); // recurse                } else {                    return bitmap;                }            }        }    }    public Bitmap obtainSizedBitmapFromPool(final int aWidth, final int aHeight) {        synchronized (mPool) {            if (mPool.isEmpty()) {                return null;            } else {                for (final Bitmap bitmap : mPool) {                    if (bitmap.isRecycled()) {                        mPool.remove(bitmap);                        return obtainSizedBitmapFromPool(aWidth, aHeight); // recurse to prevent ConcurrentModificationException                    } else if (bitmap.getWidth() == aWidth && bitmap.getHeight() == aHeight) {                        mPool.remove(bitmap);                        return bitmap;                    }                }            }        }        return null;    }    public void clearBitmapPool() {        synchronized (sInstance.mPool) {            while (!sInstance.mPool.isEmpty()) {                Bitmap bitmap = sInstance.mPool.remove();                bitmap.recycle();            }        }    }}
原创粉丝点击