osmdroid API解读(十三)

osmdroid API解读(十三)

osmdroid-android org.osmdroid.views.overlay.infowindow包

前面介绍的Marker Polygon Polyline可以再点击的时候弹出InfoWindow,本包就是封装InfoWindow的类。

1. InfoWindow

InfoWindow是一个可弹出的视图,可以在MapView中显示,并与IGeoPoint关联。

public abstract class InfoWindow {

    protected View mView;
    protected boolean mIsVisible;
    protected MapView mMapView;

    ...

    //Abstract methods to implement in sub-classes:
    public abstract void onOpen(Object item);
    public abstract void onClose();

}

2. BasicInfoWindow

为OverlayWithIW类实现的默认的InfoWindow。可以处理一个title、一个description、一个description信息。在弹出框上点击将关闭弹出窗口。

public class BasicInfoWindow extends InfoWindow {

    /**
     * resource id value meaning "undefined resource id"
     */
    public static final int UNDEFINED_RES_ID = 0;

    static int mTitleId=UNDEFINED_RES_ID, 
            mDescriptionId=UNDEFINED_RES_ID, 
            mSubDescriptionId=UNDEFINED_RES_ID, 
            mImageId=UNDEFINED_RES_ID; //resource ids

    private static void setResIds(Context context){
        String packageName = context.getPackageName(); //get application package name
        mTitleId = context.getResources().getIdentifier("id/bubble_title", null, packageName);
        mDescriptionId = context.getResources().getIdentifier("id/bubble_description", null, packageName);
        mSubDescriptionId = context.getResources().getIdentifier("id/bubble_subdescription", null, packageName);
        mImageId = context.getResources().getIdentifier("id/bubble_image", null, packageName);
        if (mTitleId == UNDEFINED_RES_ID || mDescriptionId == UNDEFINED_RES_ID 
                || mSubDescriptionId == UNDEFINED_RES_ID || mImageId == UNDEFINED_RES_ID) {
            Log.e(IMapView.LOGTAG, "BasicInfoWindow: unable to get res ids in "+packageName);
        }
    }

    public BasicInfoWindow(int layoutResId, MapView mapView) {
        super(layoutResId, mapView);

        if (mTitleId == UNDEFINED_RES_ID)
            setResIds(mapView.getContext());

        //default behavior: close it when clicking on the bubble:
        mView.setOnTouchListener(new View.OnTouchListener() {
            @Override public boolean onTouch(View v, MotionEvent e) {
                if (e.getAction() == MotionEvent.ACTION_UP)
                    close();
                return true;
            }
        });
    }

    @Override public void onOpen(Object item) {
        OverlayWithIW overlay = (OverlayWithIW)item;
        String title = overlay.getTitle();
        if (title == null)
            title = "";
        if (mView==null) {
            Log.w(IMapView.LOGTAG, "Error trapped, BasicInfoWindow.open, mView is null!");
            return;
        }
        TextView temp=((TextView)mView.findViewById(mTitleId /*R.id.title*/));

        if (temp!=null) temp.setText(title);

        String snippet = overlay.getSnippet();
        if (snippet == null)
            snippet = "";
        Spanned snippetHtml = Html.fromHtml(snippet);
        ((TextView)mView.findViewById(mDescriptionId /*R.id.description*/)).setText(snippetHtml);

        //handle sub-description, hidding or showing the text view:
        TextView subDescText = (TextView)mView.findViewById(mSubDescriptionId);
        String subDesc = overlay.getSubDescription();
        if (subDesc != null && !("".equals(subDesc))){
            subDescText.setText(Html.fromHtml(subDesc));
            subDescText.setVisibility(View.VISIBLE);
        } else {
            subDescText.setVisibility(View.GONE);
        }

    }

    @Override public void onClose() {
        //by default, do nothing
    }

}

3. MarkerInfoWindow

MarkerInfoWindow为Marker提供的一个默认的弹出框。它可以处理R.id.bubble_title 、R.id.bubble_subdescription、R.id.bubble_description、R.id.bubble_image四种类型的数据。

public class MarkerInfoWindow extends BasicInfoWindow {

    protected Marker mMarkerRef; //reference to the Marker on which it is opened. Null if none.

    /**
     * @param layoutResId layout that must contain these ids: bubble_title,bubble_description,
     *                       bubble_subdescription, bubble_image
     * @param mapView
     */
    public MarkerInfoWindow(int layoutResId, MapView mapView) {
        super(layoutResId, mapView);
        //mMarkerRef = null;
    }

    /**
     * reference to the Marker on which it is opened. Null if none.
     * @return
     */
    public Marker getMarkerReference(){
        return mMarkerRef;
    }

    @Override public void onOpen(Object item) {
        super.onOpen(item);

        mMarkerRef = (Marker)item;
        if (mView==null) {
            Log.w(IMapView.LOGTAG, "Error trapped, MarkerInfoWindow.open, mView is null!");
            return;
        }
        //handle image
        ImageView imageView = (ImageView)mView.findViewById(mImageId /*R.id.image*/);
        Drawable image = mMarkerRef.getImage();
        if (image != null){
            imageView.setImageDrawable(image); //or setBackgroundDrawable(image)?
            imageView.setVisibility(View.VISIBLE);
        } else
            imageView.setVisibility(View.GONE);
    }

    @Override public void onClose() {
        super.onClose();
        mMarkerRef = null;
        //by default, do nothing else
    }

}

osmdroid-android org.osmdroid.views.overlay.gridlines 包

1. LatLonGridlineOverlay

在MapView上显示经纬度线的Overlay。

public class LatLonGridlineOverlay {
    ...

}

osmdroid-android org.osmdroid.views.overlay.gestures包

1. RotationGestureDetector

这个类用于osmdroid内部,如果监听的话最好使用RotationListener。如果你监听的是MapView的旋转可以用MapView#setMapListener(MapListener)来监听,用MapView#getMapOrientation()来检查值。

public class RotationGestureDetector {

    public interface RotationListener {
        public void onRotate(float deltaAngle);
    }

    protected float mRotation;
    private RotationListener mListener;

    public RotationGestureDetector(RotationListener listener) {
        mListener = listener;
    }

    private static float rotation(MotionEvent event) {
        double delta_x = (event.getX(0) - event.getX(1));
        double delta_y = (event.getY(0) - event.getY(1));
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    public void onTouch(MotionEvent e) {
        if (e.getPointerCount() != 2)
            return;

        if (e.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
            mRotation = rotation(e);
        }

        float rotation = rotation(e);
        float delta = rotation - mRotation;
        mRotation += delta;
        mListener.onRotate(delta);
    }

}

2. RotationGestureOverlay

用于检测旋转手势,并旋转所有的Overlay。

public class RotationGestureOverlay extends Overlay implements
        RotationGestureDetector.RotationListener, IOverlayMenuProvider
{
    private final static boolean SHOW_ROTATE_MENU_ITEMS = false;

    private final static int MENU_ENABLED = getSafeMenuId();
    private final static int MENU_ROTATE_CCW = getSafeMenuId();
    private final static int MENU_ROTATE_CW = getSafeMenuId();

    private final RotationGestureDetector mRotationDetector;
    private MapView mMapView;
    private boolean mOptionsMenuEnabled = true;

    /** use {@link #RotationGestureOverlay(MapView)} instead. */
    @Deprecated
    public RotationGestureOverlay(Context context, MapView mapView) {
        this(mapView);
    }
    public RotationGestureOverlay(MapView mapView)
    {
        super();
        mMapView = mapView;
        mRotationDetector = new RotationGestureDetector(this);
    }

    @Override
    public void draw(Canvas c, MapView osmv, boolean shadow) {
        // No drawing necessary
    }

    @Override
    public boolean onTouchEvent(MotionEvent event, MapView mapView)
    {
        if (this.isEnabled()) {
            mRotationDetector.onTouch(event);
        }
        return super.onTouchEvent(event, mapView);
    }
    long timeLastSet=0L;
    final long deltaTime=25L;
    float currentAngle=0f;

    @Override
    public void onRotate(float deltaAngle)
    {
        currentAngle+=deltaAngle;
        if (System.currentTimeMillis() - deltaTime > timeLastSet){
            timeLastSet = System.currentTimeMillis();
            mMapView.setMapOrientation(mMapView.getMapOrientation() + currentAngle);
        }
    }

    @Override
    public void onDetach(MapView map){
        mMapView=null;
    }

    @Override
    public boolean isOptionsMenuEnabled()
    {
        return mOptionsMenuEnabled;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu pMenu, int pMenuIdOffset, MapView pMapView)
    {
        pMenu.add(0, MENU_ENABLED + pMenuIdOffset, Menu.NONE, "Enable rotation").setIcon(
                android.R.drawable.ic_menu_info_details);
        if (SHOW_ROTATE_MENU_ITEMS) {
            pMenu.add(0, MENU_ROTATE_CCW + pMenuIdOffset, Menu.NONE,
                    "Rotate maps counter clockwise").setIcon(android.R.drawable.ic_menu_rotate);
            pMenu.add(0, MENU_ROTATE_CW + pMenuIdOffset, Menu.NONE, "Rotate maps clockwise")
                    .setIcon(android.R.drawable.ic_menu_rotate);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem pItem, int pMenuIdOffset, MapView pMapView)
    {
        if (pItem.getItemId() == MENU_ENABLED + pMenuIdOffset) {
            if (this.isEnabled()) {
                mMapView.setMapOrientation(0);
                this.setEnabled(false);
            } else {
                this.setEnabled(true);
                return true;
            }
        } else if (pItem.getItemId() == MENU_ROTATE_CCW + pMenuIdOffset) {
            mMapView.setMapOrientation(mMapView.getMapOrientation() - 10);
        } else if (pItem.getItemId() == MENU_ROTATE_CW + pMenuIdOffset) {
            mMapView.setMapOrientation(mMapView.getMapOrientation() + 10);
        }

        return false;
    }

    @Override
    public boolean onPrepareOptionsMenu(final Menu pMenu, final int pMenuIdOffset, final MapView pMapView)
    {
        pMenu.findItem(MENU_ENABLED + pMenuIdOffset).setTitle(
                this.isEnabled() ? "Disable rotation" : "Enable rotation");
        return false;
    }

    @Override
    public void setOptionsMenuEnabled(boolean enabled)
    {
        mOptionsMenuEnabled = enabled;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值