Android Open Source - SmartNavi Marker






From Project

Back to project page SmartNavi.

License

The source code is released under:

Apache License

If you think the Android project SmartNavi listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.osmdroid.bonuspack.overlays;
//w ww.  ja  va 2s.co  m
import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.ResourceProxy.bitmap;
import org.osmdroid.bonuspack.utils.BonusPackHelper;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.Overlay;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;

/**
 * An icon placed at a particular point on the map's surface. 
 * Mimics the Marker class from Google Maps Android API v2 as much as possible. Main differences:<br/>
 * - Doesn't support Z-Index: as other osmdroid overlays, Marker is drawn in the order of appearance. <br/>
 * - The icon can be any standard Android Drawable, instead of the BitmapDescriptor introduced in Google Maps API v2. <br/>
 * - The icon can be changed at any time. <br/>
 * - The InfoWindow hosts a standard Android View. It can handle Android widgets like buttons and so on. <br/>
 * - Supports a "sub-description", to be displayed in the InfoWindow, under the snippet, in a smaller text font. <br/>
 * - Supports an image, to be displayed in the InfoWindow. <br/>
 * - Supports "panning to view" on/off option (when touching a marker, center the map on marker position). <br/>
 * - Opening a Marker InfoWindow automatically close others only if it's the same InfoWindow shared between Markers. <br/>
 * - Events listeners are set per marker, not per map. <br/>
 * 
 * TODO: <br/>
 * Impact of marker rotation on hitTest<br/>
 * When map is rotated, when panning the map, bug on the InfoWindow positioning (osmdroid issue #524)<br/>
 * 
 * @see MarkerInfoWindow
 * @see http://developer.android.com/reference/com/google/android/gms/maps/model/Marker.html
 * 
 * @author M.Kergall
 *
 */
public class Marker extends Overlay {

  /*attributes for standard features:*/
  protected Drawable mIcon;
  protected GeoPoint mPosition;
  protected float mBearing;
  protected float mAnchorU, mAnchorV;
  protected float mIWAnchorU, mIWAnchorV;
  protected float mAlpha;
  protected String mTitle, mSnippet;
  protected boolean mDraggable, mIsDragged;
  protected MarkerInfoWindow mInfoWindow;
  protected boolean mFlat;
  protected OnMarkerClickListener mOnMarkerClickListener;
  protected OnMarkerDragListener mOnMarkerDragListener;
  
  /*attributes for non-standard features:*/
  protected Drawable mImage;
  protected String mSubDescription;
  protected boolean mPanToView;
  protected Object mRelatedObject;
  
  /*internals*/
  protected Point mPositionPixels;
  protected static MarkerInfoWindow mDefaultInfoWindow = null;
  protected static Drawable mDefaultIcon = null; //cache for default icon (resourceProxy.getDrawable being slow)
  
  /** Usual values in the (U,V) coordinates system of the icon image */
  public static final float ANCHOR_CENTER=0.5f, ANCHOR_LEFT=0.0f, ANCHOR_TOP=0.0f, ANCHOR_RIGHT=1.0f, ANCHOR_BOTTOM=1.0f;
  
  public Marker(MapView mapView) {
    this(mapView, new DefaultResourceProxyImpl(mapView.getContext()));
  }

  public Marker(MapView mapView, final ResourceProxy resourceProxy) {
    super(resourceProxy);
    mBearing = 0.0f;
    mAlpha = 1.0f; //opaque
    mPosition = new GeoPoint(0.0, 0.0);
    mAnchorU = ANCHOR_CENTER;
    mAnchorV = ANCHOR_CENTER;
    mIWAnchorU = ANCHOR_CENTER;
    mIWAnchorV = ANCHOR_TOP;
    mDraggable = false;
    mIsDragged = false;
    mPositionPixels = new Point();
    mPanToView = true;
    mFlat = false; //billboard
    mOnMarkerClickListener = null;
    mOnMarkerDragListener = null;
    if (mDefaultIcon == null)
      mDefaultIcon = resourceProxy.getDrawable(bitmap.marker_default);
    mIcon = mDefaultIcon;
    if (mDefaultInfoWindow == null || mDefaultInfoWindow.mMapView != mapView){
      //build default bubble, that will be shared between all markers using the default one:
      Context context = mapView.getContext();
      String packageName = context.getPackageName();
      int defaultLayoutResId = context.getResources().getIdentifier("bonuspack_bubble", "layout", packageName);
      if (defaultLayoutResId == 0)
        Log.e(BonusPackHelper.LOG_TAG, "Marker: layout/bonuspack_bubble not found in "+packageName);
      else 
        mDefaultInfoWindow = new MarkerInfoWindow(defaultLayoutResId, mapView);
    }
    mInfoWindow = mDefaultInfoWindow;
  }

  /** Sets the icon for the marker. Can be changed at any time. 
   * @param icon if null, the default osmdroid marker is used. 
   */
  public void setIcon(Drawable icon){
    if (icon != null)
      mIcon = icon;
    else 
      mIcon = mDefaultIcon;
  }
  
  public GeoPoint getPosition(){
    return mPosition;
  }
  
  public void setPosition(GeoPoint position){
    mPosition = position.clone();
  }

  public float getRotation(){
    return mBearing;
  }
  
  public void setRotation(float rotation){
    mBearing = rotation;
  }
  
  public void setAnchor(float anchorU, float anchorV){
    mAnchorU = anchorU;
    mAnchorV= anchorV;
  }
  
  public void setInfoWindowAnchor(float anchorU, float anchorV){
    mIWAnchorU = anchorU;
    mIWAnchorV= anchorV;
  }
  
  public void setAlpha(float alpha){
    mAlpha = alpha;
  }
  
  public float getAlpha(){
    return mAlpha;
  }
  
  public void setTitle(String title){
    mTitle = title;
  }
  
  public String getTitle(){
    return mTitle;
  }
  
  public void setSnippet(String snippet){
    mSnippet= snippet;
  }
  
  public String getSnippet(){
    return mSnippet;
  }

  public void setDraggable(boolean draggable){
    mDraggable = draggable;
  }
  
  public boolean isDraggable(){
    return mDraggable;
  }

  public void setFlat(boolean flat){
    mFlat = flat;
  }
  
  public boolean isFlat(){
    return mFlat;
  }
  
  /** 
   * Removes this Marker from the MapView. 
   * Note that this method will operate only if the Marker is in the MapView overlays 
   * (it should not be included in a container like a FolderOverlay). 
   * @param mapView
   */
  public void remove(MapView mapView){
    mapView.getOverlays().remove(this);
  }

  public void setOnMarkerClickListener(OnMarkerClickListener listener){
    mOnMarkerClickListener = listener;
  }
  
  public void setOnMarkerDragListener(OnMarkerDragListener listener){
    mOnMarkerDragListener = listener;
  }
  
  /** set the "sub-description", an optional text to be shown in the InfoWindow, below the snippet, in a smaller text size */
  public void setSubDescription(String subDescription){
    mSubDescription = subDescription;
  }
  
  public String getSubDescription(){
    return mSubDescription;
  }

  /** set an image to be shown in the InfoWindow  - this is not the marker icon */
  public void setImage(Drawable image){
    mImage = image;
  }

  /** get the image to be shown in the InfoWindow - this is not the marker icon */
  public Drawable getImage(){
    return mImage;
  }

  /** Set the InfoWindow to be used. 
   * Default is a MarkerInfoWindow, with the layout named "bonuspack_bubble". 
   * You can use this method either to use your own layout, or to use your own sub-class of InfoWindow. 
   * Note that this InfoWindow will receive the Marker object as an input, so it MUST be able to handle Marker attributes. 
   * If you don't want any InfoWindow to open, you can set it to null. */
  public void setInfoWindow(MarkerInfoWindow infoWindow){
    mInfoWindow = infoWindow;
  }

  /** If set to true, when clicking the marker, the map will be centered on the marker position. 
   * Default is true. */
  public void setPanToView(boolean panToView){
    mPanToView = panToView;
  }
  
  /** Allows to link an Object (any Object) to this marker. 
   * This is particularly useful to handle custom InfoWindow. */
  public void setRelatedObject(Object relatedObject){
    mRelatedObject = relatedObject;
  }

  /** @return the related object. */
  public Object getRelatedObject(){
    return mRelatedObject;
  }
  
  public void showInfoWindow(){
    if (mInfoWindow == null)
      return;
    int markerWidth = 0, markerHeight = 0;
    markerWidth = mIcon.getIntrinsicWidth(); 
    markerHeight = mIcon.getIntrinsicHeight();
    
    int offsetX = (int)(mIWAnchorU*markerWidth) - (int)(mAnchorU*markerWidth);
    int offsetY = (int)(mIWAnchorV*markerHeight) - (int)(mAnchorV*markerHeight);
    
    mInfoWindow.open(this, mPosition, offsetX, offsetY);
  }
  
  public void hideInfoWindow(){
    if (mInfoWindow != null)
      mInfoWindow.close();
  }

  public boolean isInfoWindowShown(){
    return (mInfoWindow != null) && mInfoWindow.isOpen() && (mInfoWindow.mMarkerRef==this);
  }
  
  @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    if (shadow)
      return;
    if (mIcon == null)
      return;
    
    final Projection pj = mapView.getProjection();
    
    pj.toPixels(mPosition, mPositionPixels);
    int width = mIcon.getIntrinsicWidth();
    int height = mIcon.getIntrinsicHeight();
    Rect rect = new Rect(0, 0, width, height);
    rect.offset(-(int)(mAnchorU*width), -(int)(mAnchorV*height));
    mIcon.setBounds(rect);
    
    mIcon.setAlpha((int)(mAlpha*255));
    
    float rotationOnScreen = (mFlat ? -mBearing : mapView.getMapOrientation()-mBearing);
    drawAt(canvas, mIcon, mPositionPixels.x, mPositionPixels.y, false, rotationOnScreen);
  }

  public boolean hitTest(final MotionEvent event, final MapView mapView){
    final Projection pj = mapView.getProjection();
    pj.toPixels(mPosition, mPositionPixels);
    final Rect screenRect = pj.getIntrinsicScreenRect();
    int x = -mPositionPixels.x + screenRect.left + (int) event.getX();
    int y = -mPositionPixels.y + screenRect.top + (int) event.getY();
    boolean hit = mIcon.getBounds().contains(x, y);
    return hit;
  }
  
  @Override public boolean onSingleTapConfirmed(final MotionEvent event, final MapView mapView){
    boolean touched = hitTest(event, mapView);
    if (touched){
      if (mOnMarkerClickListener == null){
        return onMarkerClickDefault(this, mapView);
      } else {
        return mOnMarkerClickListener.onMarkerClick(this, mapView);
      }
    } else
      return touched;
  }

  public void moveToEventPosition(final MotionEvent event, final MapView mapView){
    final Projection pj = mapView.getProjection();
    mPosition = (GeoPoint) pj.fromPixels((int)event.getX(), (int)event.getY());
    mapView.invalidate();
  }
  
  @Override public boolean onLongPress(final MotionEvent event, final MapView mapView) {
    boolean touched = hitTest(event, mapView);
    if (touched){
      if (mDraggable){
        //starts dragging mode:
        mIsDragged = true;
        hideInfoWindow();
        if (mOnMarkerDragListener != null)
          mOnMarkerDragListener.onMarkerDragStart(this);
        moveToEventPosition(event, mapView);
      }
    }
    return touched;
  }
  
  @Override public boolean onTouchEvent(final MotionEvent event, final MapView mapView) {
    if (mDraggable && mIsDragged){
      if (event.getAction() == MotionEvent.ACTION_UP) {
        mIsDragged = false;
        if (mOnMarkerDragListener != null)
          mOnMarkerDragListener.onMarkerDragEnd(this);
        return true;
      } else if (event.getAction() == MotionEvent.ACTION_MOVE){
        moveToEventPosition(event, mapView);
        if (mOnMarkerDragListener != null)
            mOnMarkerDragListener.onMarkerDrag(this);
        return true;
      } else 
        return false;
    } else 
      return false;
  }
  
  //-- Marker events listener interfaces ------------------------------------
  
  public interface OnMarkerClickListener{
    abstract boolean onMarkerClick(Marker marker, MapView mapView); 
  }
  
  public interface OnMarkerDragListener{
    abstract void onMarkerDrag(Marker marker);
    abstract void onMarkerDragEnd(Marker marker);
    abstract void onMarkerDragStart(Marker marker);
  }
  
  /** default behaviour when no click listener is set */
  protected boolean onMarkerClickDefault(Marker marker, MapView mapView) {
    marker.showInfoWindow();
    if (marker.mPanToView)
      mapView.getController().animateTo(marker.getPosition());
    return true;
  }
  
}




Java Source Code List

com.ilm.sandwich.BuildConfig.java
com.ilm.sandwich.Config.java
com.ilm.sandwich.GoogleMapActivity.java
com.ilm.sandwich.Info.java
com.ilm.sandwich.MySupportMapFragment.java
com.ilm.sandwich.OsmMapActivity.java
com.ilm.sandwich.Settings.java
com.ilm.sandwich.Smartgeo.java
com.ilm.sandwich.StartChooser.java
com.ilm.sandwich.TouchableWrapper.java
com.ilm.sandwich.helferklassen.HttpRequests.java
com.ilm.sandwich.helferklassen.Locationer.java
com.ilm.sandwich.helferklassen.MapDownload.java
com.ilm.sandwich.helferklassen.MyItemizedOverlay.java
com.ilm.sandwich.helferklassen.PlacesAutoComplete.java
com.ilm.sandwich.helferklassen.PlacesTextSearch.java
com.ilm.sandwich.helferklassen.Rechnung.java
com.ilm.sandwich.helferklassen.SuggestionsAdapter.java
org.osmdroid.bonuspack.BuildConfig.java
org.osmdroid.bonuspack.BuildConfig.java
org.osmdroid.bonuspack.cachemanager.CacheManager.java
org.osmdroid.bonuspack.clustering.GridMarkerClusterer.java
org.osmdroid.bonuspack.clustering.MarkerClusterer.java
org.osmdroid.bonuspack.clustering.StaticCluster.java
org.osmdroid.bonuspack.kml.ColorStyle.java
org.osmdroid.bonuspack.kml.IconStyle.java
org.osmdroid.bonuspack.kml.KmlDocument.java
org.osmdroid.bonuspack.kml.KmlFeature.java
org.osmdroid.bonuspack.kml.KmlFolder.java
org.osmdroid.bonuspack.kml.KmlGeometry.java
org.osmdroid.bonuspack.kml.KmlGroundOverlay.java
org.osmdroid.bonuspack.kml.KmlLineString.java
org.osmdroid.bonuspack.kml.KmlMultiGeometry.java
org.osmdroid.bonuspack.kml.KmlPlacemark.java
org.osmdroid.bonuspack.kml.KmlPoint.java
org.osmdroid.bonuspack.kml.KmlPolygon.java
org.osmdroid.bonuspack.kml.LineStyle.java
org.osmdroid.bonuspack.kml.Style.java
org.osmdroid.bonuspack.location.FlickrPOIProvider.java
org.osmdroid.bonuspack.location.GeoNamesPOIProvider.java
org.osmdroid.bonuspack.location.GeocoderGisgraphy.java
org.osmdroid.bonuspack.location.GeocoderNominatimOld.java
org.osmdroid.bonuspack.location.GeocoderNominatim.java
org.osmdroid.bonuspack.location.NominatimPOIProvider.java
org.osmdroid.bonuspack.location.POI.java
org.osmdroid.bonuspack.location.PicasaPOIProvider.java
org.osmdroid.bonuspack.mapsforge.GenericMapView.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileModuleProvider.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileProvider.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileSource.java
org.osmdroid.bonuspack.overlays.DefaultInfoWindow.java
org.osmdroid.bonuspack.overlays.ExtendedOverlayItem.java
org.osmdroid.bonuspack.overlays.FolderOverlay.java
org.osmdroid.bonuspack.overlays.GroundOverlay.java
org.osmdroid.bonuspack.overlays.InfoWindow.java
org.osmdroid.bonuspack.overlays.ItemizedOverlayWithBubble.java
org.osmdroid.bonuspack.overlays.MapEventsOverlay.java
org.osmdroid.bonuspack.overlays.MapEventsReceiver.java
org.osmdroid.bonuspack.overlays.MarkerInfoWindow.java
org.osmdroid.bonuspack.overlays.Marker.java
org.osmdroid.bonuspack.overlays.Polygon.java
org.osmdroid.bonuspack.overlays.Polyline.java
org.osmdroid.bonuspack.routing.GoogleRoadManager.java
org.osmdroid.bonuspack.routing.MapQuestRoadManager.java
org.osmdroid.bonuspack.routing.OSRMRoadManager.java
org.osmdroid.bonuspack.routing.RoadLeg.java
org.osmdroid.bonuspack.routing.RoadManager.java
org.osmdroid.bonuspack.routing.RoadNode.java
org.osmdroid.bonuspack.routing.Road.java
org.osmdroid.bonuspack.utils.BonusPackHelper.java
org.osmdroid.bonuspack.utils.DouglasPeuckerReducer.java
org.osmdroid.bonuspack.utils.HttpConnection.java
org.osmdroid.bonuspack.utils.PolylineEncoder.java
org.osmdroid.bonuspack.utils.WebImageCache.java