您的位置:首页 > 其它

osmdroid API解读(四)

2017-10-24 19:09 323 查看

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();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  api 地图 osmdroid