use OverlayMarker instead of Drawable

This commit is contained in:
Hannes Janetzek 2013-06-21 10:03:47 +02:00
parent 6232c401db
commit 0bc986607d
4 changed files with 187 additions and 151 deletions

View File

@ -17,14 +17,11 @@ package org.oscim.layers.overlay;
import java.util.List;
import org.oscim.app.R;
import org.oscim.core.BoundingBox;
import org.oscim.core.PointF;
import org.oscim.view.MapView;
import org.oscim.view.MapViewPosition;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverlay<Item> {
@ -36,28 +33,16 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
private final PointF mItemPoint = new PointF();
public ItemizedIconOverlay(
final MapView mapView,
final List<Item> pList,
final Drawable pDefaultMarker,
final ItemizedIconOverlay.OnItemGestureListener<Item> pOnItemGestureListener) {
public ItemizedIconOverlay(MapView mapView, List<Item> list, OverlayMarker defaultMarker,
ItemizedIconOverlay.OnItemGestureListener<Item> onItemGestureListener) {
super(mapView, pDefaultMarker);
super(mapView, defaultMarker);
this.mItemList = pList;
this.mOnItemGestureListener = pOnItemGestureListener;
this.mItemList = list;
this.mOnItemGestureListener = onItemGestureListener;
populate();
}
public ItemizedIconOverlay(
final MapView mapView,
final Context pContext,
final List<Item> pList,
final ItemizedIconOverlay.OnItemGestureListener<Item> pOnItemGestureListener) {
this(mapView, pList, pContext.getResources().getDrawable(R.drawable.marker_default),
pOnItemGestureListener);
}
@Override
public boolean onSnapToItem(final int pX, final int pY, final PointF pSnapPoint) {
// TODO Implement this!
@ -139,6 +124,7 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
return onSingleTapUpHelper(index, that.mItemList.get(index));
}
};
@Override
public boolean onLongPress(final MotionEvent event) {
return activateSelectedItems(event, mActiveItemLongPress) || super.onLongPress(event);
@ -186,7 +172,7 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
for (int i = 0; i < size; i++) {
Item item = getItem(i);
if (!bbox.contains(item.mGeoPoint)){
if (!bbox.contains(item.mGeoPoint)) {
//Log.d(TAG, "skip: " + item.getTitle());
continue;
}

View File

@ -21,6 +21,8 @@ package org.oscim.layers.overlay;
// - and to make this work for multiple overlays
// a global scenegraph is probably required.
import org.oscim.android.AndroidGraphics;
import org.oscim.app.R;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.core.PointD;
@ -28,11 +30,11 @@ import org.oscim.core.Tile;
import org.oscim.layers.overlay.OverlayItem.HotspotPlace;
import org.oscim.renderer.GLRenderer.Matrices;
import org.oscim.renderer.layers.BasicRenderLayer;
import org.oscim.renderer.sublayers.SymbolItem;
import org.oscim.renderer.sublayers.SymbolLayer;
import org.oscim.utils.GeometryUtils;
import org.oscim.view.MapView;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@ -56,7 +58,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
//private final static String TAG = ItemizedOverlay.class.getName();
protected final Drawable mDefaultMarker;
protected final OverlayMarker mDefaultMarker;
protected boolean mDrawFocusedItem = true;
class InternalItem {
@ -161,7 +163,8 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
if (mDrawFocusedItem && (mFocusedItem == it.item))
state = OverlayItem.ITEM_STATE_FOCUSED_MASK;
Drawable marker = it.item.getDrawable();
//Drawable marker = it.item.getDrawable();
OverlayMarker marker = it.item.getMarker(0);
if (marker == null)
marker = mDefaultMarker;
@ -171,7 +174,17 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
// } else
// marker = item.getMarker(state);
mSymbolLayer.addDrawable(marker, state, it.x, it.y);
//mSymbolLayer.addDrawable(marker, state, it.x, it.y);
SymbolItem s = SymbolItem.pool.get();
s.bitmap = marker.getBitmap();
s.x = it.x;
s.y = it.y;
s.offset = marker.getHotspot();
s.billboard = true;
mSymbolLayer.addSymbol(s);
}
}
@ -179,6 +192,10 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
layers.textureLayers = mSymbolLayer;
newData = true;
}
@Override
public synchronized void compile() {
super.compile();
}
}
/**
@ -198,14 +215,17 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
*/
public abstract int size();
public ItemizedOverlay(MapView mapView, final Drawable pDefaultMarker) {
public ItemizedOverlay(MapView mapView, OverlayMarker defaultMarker) {
super(mapView);
if (pDefaultMarker == null) {
throw new IllegalArgumentException("You must pass a default marker to ItemizedOverlay.");
if (defaultMarker == null) {
defaultMarker = AndroidGraphics.makeMarker(mapView.getContext().getResources()
.getDrawable(R.drawable.marker_default), null);
//throw new IllegalArgumentException("You must pass a default marker to ItemizedOverlay.");
}
this.mDefaultMarker = pDefaultMarker;
//this.mDefaultMarker = OverlayMarker.makeMarker(pDefaultMarker, null);
mDefaultMarker = defaultMarker;
mLayer = new ItemOverlay(mapView);
}
@ -270,14 +290,8 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
return null;
}
// return mInternalItemList.get(position);
}
// private Drawable getDefaultMarker(final int state) {
// OverlayItem.setState(mDefaultMarker, state);
// return mDefaultMarker;
// }
/**
* See if a given hit point is within the bounds of an item's marker.
* Override to modify the way an item is hit tested. The hit point is
@ -393,91 +407,4 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
return marker;
}
public static Drawable makeMarker(Resources res, int id, HotspotPlace place) {
Drawable marker = res.getDrawable(id);
if (place == null)
boundToHotspot(marker, HotspotPlace.CENTER);
else
boundToHotspot(marker, place);
return marker;
}
// /**
// * Draw a marker on each of our items. populate() must have been called
// * first.<br/>
// * <br/>
// * The marker will be drawn twice for each Item in the Overlay--once in the
// * shadow phase, skewed and darkened, then again in the non-shadow phase.
// * The bottom-center of the marker will be aligned with the geographical
// * coordinates of the Item.<br/>
// * <br/>
// * The order of drawing may be changed by overriding the getIndexToDraw(int)
// * method. An item may provide an alternate marker via its
// * OverlayItem.getMarker(int) method. If that method returns null, the
// * default marker is used.<br/>
// * <br/>
// * The focused item is always drawn last, which puts it visually on top of
// * the other items.<br/>
// *
// * @param canvas
// * the Canvas upon which to draw. Note that this may already have
// * a transformation applied, so be sure to leave it the way you
// * found it
// * @param mapView
// * the MapView that requested the draw. Use
// * MapView.getProjection() to convert between on-screen pixels
// * and latitude/longitude pairs
// * @param shadow
// * if true, draw the shadow layer. If false, draw the overlay
// * contents.
// */
// @Override
// public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
//
// if (shadow) {
// return;
// }
//
// final Projection pj = mapView.getProjection();
// final int size = this.mInternalItemList.size() - 1;
//
// /*
// * Draw in backward cycle, so the items with the least index are on the
// * front.
// */
// for (int i = size; i >= 0; i--) {
// final Item item = getItem(i);
// pj.toMapPixels(item.mGeoPoint, mCurScreenCoords);
//
// onDrawItem(canvas, item, mCurScreenCoords);
// }
// }
// /**
// * Draws an item located at the provided screen coordinates to the canvas.
// *
// * @param canvas
// * what the item is drawn upon
// * @param item
// * the item to be drawn
// * @param curScreenCoords
// * the screen coordinates of the item
// */
// protected void onDrawItem(final Canvas canvas, final Item item, final Point curScreenCoords) {
// int state = 0;
//
// if (mDrawFocusedItem && (mFocusedItem == item))
// state = OverlayItem.ITEM_STATE_FOCUSED_MASK;
//
// Drawable marker;
//
// if (item.getMarker(state) == null)
// marker = getDefaultMarker(state);
// else
// marker = item.getMarker(state);
//
// boundToHotspot(marker, item.getMarkerHotspot());
//
// // draw it
// Overlay.drawAt(canvas, marker, curScreenCoords.x, curScreenCoords.y, false);
// }
}

View File

@ -20,7 +20,6 @@ package org.oscim.layers.overlay;
import org.oscim.core.GeoPoint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
/**
* Immutable class describing a GeoPoint with a Title and a Description.
@ -57,7 +56,7 @@ public class OverlayItem {
public final String mTitle;
public final String mDescription;
public final GeoPoint mGeoPoint;
protected Drawable mMarker;
protected OverlayMarker mMarker;
protected HotspotPlace mHotspotPlace;
// ===========================================================
@ -114,18 +113,18 @@ public class OverlayItem {
* @return The marker for the current state, or null if the default marker
* for the overlay should be used.
*/
public Drawable getMarker(final int stateBitset) {
public OverlayMarker getMarker(int stateBitset) {
// marker not specified
if (mMarker == null) {
return null;
}
// set marker state appropriately
setState(mMarker, stateBitset);
// setState(mMarker, stateBitset);
return mMarker;
}
public void setMarker(final Drawable marker) {
public void setMarker(OverlayMarker marker) {
this.mMarker = marker;
}
@ -152,28 +151,28 @@ public class OverlayItem {
* R.attr.state_focused attributes, and then calling {@link
* Drawable.setState(int[])}.
*/
public static void setState(final Drawable drawable, final int stateBitset) {
final int[] states = new int[3];
int index = 0;
if ((stateBitset & ITEM_STATE_PRESSED_MASK) > 0)
states[index++] = android.R.attr.state_pressed;
if ((stateBitset & ITEM_STATE_SELECTED_MASK) > 0)
states[index++] = android.R.attr.state_selected;
if ((stateBitset & ITEM_STATE_FOCUSED_MASK) > 0)
states[index++] = android.R.attr.state_focused;
drawable.setState(states);
}
public Drawable getDrawable() {
return this.mMarker;
}
public int getWidth() {
return this.mMarker.getIntrinsicWidth();
}
public int getHeight() {
return this.mMarker.getIntrinsicHeight();
}
// public static void setState(final Drawable drawable, final int stateBitset) {
// final int[] states = new int[3];
// int index = 0;
// if ((stateBitset & ITEM_STATE_PRESSED_MASK) > 0)
// states[index++] = android.R.attr.state_pressed;
// if ((stateBitset & ITEM_STATE_SELECTED_MASK) > 0)
// states[index++] = android.R.attr.state_selected;
// if ((stateBitset & ITEM_STATE_FOCUSED_MASK) > 0)
// states[index++] = android.R.attr.state_focused;
//
// drawable.setState(states);
// }
//
// public Drawable getDrawable() {
// return this.mMarker;
// }
//
// public int getWidth() {
// return this.mMarker.getIntrinsicWidth();
// }
//
// public int getHeight() {
// return this.mMarker.getIntrinsicHeight();
// }
}

View File

@ -0,0 +1,124 @@
/*
* Copyright 2013
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.layers.overlay;
import org.oscim.core.PointF;
import org.oscim.layers.overlay.OverlayItem.HotspotPlace;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
public class OverlayMarker {
final Bitmap[] mBitmap;
// Hotspot offset
final PointF[] mOffset;
public OverlayMarker(Bitmap bitmap, float relX, float relY) {
mBitmap = new Bitmap[1];
mBitmap[0] = bitmap;
mOffset = new PointF[1];
mOffset[0] = new PointF(relX, relY);
}
public OverlayMarker(Bitmap bitmap, HotspotPlace hotspot) {
float x = 0, y = 0;
switch (hotspot) {
default:
case NONE:
break;
case CENTER:
x = 0.5f;
y = 0.5f;
break;
case BOTTOM_CENTER:
x = 0.5f;
y = 1.0f;
break;
case TOP_CENTER:
x = 0.5f;
y = 0.0f;
break;
case RIGHT_CENTER:
x = 1.0f;
y = 0.5f;
break;
case LEFT_CENTER:
x = 0.0f;
y = 0.5f;
break;
case UPPER_RIGHT_CORNER:
x = 1.0f;
y = 0.0f;
break;
case LOWER_RIGHT_CORNER:
x = 1.0f;
y = 1.0f;
break;
case UPPER_LEFT_CORNER:
x = 0.0f;
y = 0.0f;
break;
case LOWER_LEFT_CORNER:
x = 0.0f;
y = 1.0f;
break;
}
mBitmap = new Bitmap[1];
mBitmap[0] = bitmap;
mOffset = new PointF[1];
mOffset[0] = new PointF(x, y);
}
public PointF getHotspot() {
return mOffset[0];
}
public Bitmap getBitmap() {
return mBitmap[0];
}
public static Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Config.ARGB_8888);
android.graphics.Canvas canvas = new android.graphics.Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static OverlayMarker makeMarker(Resources res, int id, HotspotPlace place) {
return makeMarker(res.getDrawable(id), place);
}
public static OverlayMarker makeMarker(Drawable drawable, HotspotPlace place) {
if (place == null)
place = HotspotPlace.CENTER;
return new OverlayMarker(drawableToBitmap(drawable), place);
}
}