2013-07-05 6 views
11

Attualmente sto sviluppando un sistema di tracciamento per tracciare la traiettoria del movimento dell'utente all'interno di una stanza o in qualsiasi altro modo.Come disegnare un'immagine di un piccolo segnalino e continuare a rinfrescare la sua posizione sulla mia immagine mappa CUSTOM? - Android

Ora sono riuscito a importare la mia mappa nell'app e la mappa è libera di essere ingrandita e spostata. Il passaggio successivo consiste nel posizionare un indicatore per indicare la posizione dell'utente sulla mappa e spostare il segno attorno alla mappa. (come fluttuare sulla mappa)

L'ho letto da qualche parte e penso che questo possa essere fatto con MyLocationOverlay, ma la maggior parte degli esempi online sono tutti da applicare sullo google map. Tuttavia, nel mio caso, la mia mappa non è google map, è la mia mappa PROPRIA. (La mappa può essere la mappa della mia stanza o anche una mappa che disegno io stesso!)

Ho eseguito l'algoritmo di tracciamento, ad esempio so dove posizionare l'immagine del mio marcatore.

Quindi l'unica domanda rimane è come presentare l'immagine del marcatore sopra l'immagine della mappa.

In particolare, ho una visione auto-definiti, MapView, come segue:

package com.example.drsystem; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.drawable.Drawable; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 

public class MapView extends View { 

    private static final int INVALID_POINTER_ID = -1; 

    private Drawable mImage; 
    private float mPosX; 
    private float mPosY; 

    private float mLastTouchX; 
    private float mLastTouchY; 
    private int mActivePointerId = INVALID_POINTER_ID; 

    private ScaleGestureDetector mScaleDetector; 
    private float mScaleFactor = 1.f; 

    public MapView(Context context) { 
     this(context, null, 0); 

     mImage = getResources().getDrawable(R.drawable.lv12n); 
     mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight()); 
    } 

    // called when XML tries to inflate this View 
    public MapView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 

     mImage = getResources().getDrawable(R.drawable.lv12n); 
     mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight()); 
    } 

    public MapView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     // Let the ScaleGestureDetector inspect all events. 
     mScaleDetector.onTouchEvent(ev); 

     final int action = ev.getAction(); 
     switch (action & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: { 
      final float x = ev.getX(); 
      final float y = ev.getY(); 

      mLastTouchX = x; 
      mLastTouchY = y; 
      mActivePointerId = ev.getPointerId(0); 
      break; 
     } 

     case MotionEvent.ACTION_MOVE: { 
      final int pointerIndex = ev.findPointerIndex(mActivePointerId); 
      final float x = ev.getX(pointerIndex); 
      final float y = ev.getY(pointerIndex); 

      // Only move if the ScaleGestureDetector isn't processing a gesture. 
      if (!mScaleDetector.isInProgress()) { 
       final float dx = x - mLastTouchX; 
       final float dy = y - mLastTouchY; 

       mPosX += dx; 
       mPosY += dy; 

       invalidate(); 
      } 

      mLastTouchX = x; 
      mLastTouchY = y; 

      break; 
     } 

     case MotionEvent.ACTION_UP: { 
      mActivePointerId = INVALID_POINTER_ID; 
      break; 
     } 

     case MotionEvent.ACTION_CANCEL: { 
      mActivePointerId = INVALID_POINTER_ID; 
      break; 
     } 

     case MotionEvent.ACTION_POINTER_UP: { 
      final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
      final int pointerId = ev.getPointerId(pointerIndex); 
      if (pointerId == mActivePointerId) { 
       // This was our active pointer going up. Choose a new 
       // active pointer and adjust accordingly. 
       final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
       mLastTouchX = ev.getX(newPointerIndex); 
       mLastTouchY = ev.getY(newPointerIndex); 
       mActivePointerId = ev.getPointerId(newPointerIndex); 
      } 
      break; 
     } 
     } 

     return true; 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     canvas.save(); 
     Log.d("MapView", "X: " + mPosX + " Y: " + mPosY); 
     canvas.translate(mPosX, mPosY); 
     canvas.scale(mScaleFactor, mScaleFactor); 
     mImage.draw(canvas); 
     canvas.restore(); 
    } 

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      mScaleFactor *= detector.getScaleFactor(); 

      // Don't let the object get too small or too large. 
      mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); 

      invalidate(); 
      return true; 
     } 
    } 

} 

Fino a qui, la mappa è successo di ingresso in app, ed è sia mobile e cartina.

E poi, inserisco questa visualizzazione personalizzata nel file XML di layout come segue:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MapView" > 

    <com.example.drsystem.MapView 
     android:id="@+id/mapView1" 
     android:layout_width="fill_parent" 
     android:layout_height="400dp" 
     android:layout_above="@+id/button2" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" /> 

... 

</RelativeLayout> 

In base a tutte queste informazioni, come posso disegnare un punto e costantemente aggiornare la propria posizione sulla mia mappa?

Aggiornamento:

La questione è semplicemente di mettere un altro piccolo immagine sulla cima di una visualizzazione personalizzata e spostandolo intorno.

Allego inoltre lo screenshot qui per il vostro riferimento:

enter image description here

L'area sopra i pulsanti e textviews è il mio MapView

+1

Controllare la fonte di Redpin. Fa esattamente questo – Reno

risposta

1

Ecco parte del mio codice che ha fatto ciò che chiedete (ma solo per il gesto di trascinamento), lo zoom è un po 'complicato. Ho bisogno di sapere a quale punto si basa lo zoom, ad esempio la metà delle due dita o il (0.0) sullo schermo

prima iniziale il punto, ma invisibile

ImageButton dot = new ImageButton(this);// since I add onClick for the dot  
//setImageBitmap 
dot.setVisibility(View.INVISIBLE); 
RelativeLayout.LayoutParams dotparams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
dotparams.setMargins(0,0,0,0); 
dot.setLayoutParams(dotparams); 
final RelativeLayout myLayout = (RelativeLayout)findViewById(R.id.maplayout);//set an Id for your RelativeLayout 
myLayout.addView(dot,dotparams); 

per aggiungere punti con la posizione relativa di mappare

dotImageWidth/altezza può ottenere da Bitmap.getWidth()/getHeight()

private void displayPositon(int dotx, int doty) { 
    dot.setVisibility(View.VISIBLE); 
    RelativeLayout.LayoutParams dotparams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    dotparams.setMargins((int)(((android.widget.RelativeLayout.LayoutParams) mImage.getLayoutParams()).leftMargin + dotx - dotImageWidth/2),(int)(((android.widget.RelativeLayout.LayoutParams) mImage.getLayoutParams()).topMargin + doty - dotImageHeight),0,0); 
    dot.setLayoutParams(params); 

in onTouchEvent prima dello

RelativeLayout.LayoutParams params[]; 
params = new RelativeLayout.LayoutParams[2];//one is the top-left of your mapView, one is the dot 
params[0]= (android.widget.RelativeLayout.LayoutParams) dot.getLayoutParams(); 
params[1]= (android.widget.RelativeLayout.LayoutParams) mImage.getLayoutParams(); 

caso Action_Down

dotleftMargin = ((android.widget.RelativeLayout.LayoutParams) dot.getLayoutParams()).leftMargin; 
dottopMargin = ((android.widget.RelativeLayout.LayoutParams) dot.getLayoutParams()).topMargin; 
mapleftMargin = ((android.widget.RelativeLayout.LayoutParams) mImage.getLayoutParams()).leftMargin; 
maptopMargin = ((android.widget.RelativeLayout.LayoutParams) mImage.getLayoutParams()).topMargin; 

caso ACTION_MOVE

params[0].setMargins((int)(x - mLastTouchX + dotleftMargin), (int)(y- mLastTouchY + dottopMargin), 0, 0); 
params[1].setMargins((int)(x - mLastTouchX + mapleftMargin), (int)(y- mLastTouchY + maptopMargin), 0, 0); 
+0

Penso che tu abbia frainteso la mia domanda un po '. La mia domanda non è in realtà sulla mappa. In poche parole: come posso posizionare un'immagine sopra un'altra immagine? Potresti modificare la tua risposta di conseguenza? Grazie. –

+0

I AM rispondere alla tua domanda è sufficiente modificare ImageButton in ImageView e aggiungere l'id in RelativeLayout e aggiungere l'immagine nel layout. Non riesco a legare la mappa e il punto così ho scritto quando sposti la tua mappa su come spostare il punto con esso – Gina

2

Per cominciare, utilizzare LocationClient API (invece di LocationManager) dal momento che funzionano molto bene con i provider di GPS misti, wifi e rete. Usano anche sensori per riconoscere un movimento in modo che possano risparmiare sulla batteria.

Io uso il seguente codice LocationOverlay che posiziona le mie icone sulla mappa. Personalizzalo per te. È un po 'ruvido ma funziona.

private class LocationMarker extends ItemizedOverlay<OverlayItem> { 
    private Activity appContext; 
    private List<OverlayItem> items = new ArrayList<OverlayItem>(); 
    private Drawable marker = null; 
    private OverlayItem inDrag = null; 
    private ImageView dragImage = null; 
    private int xDragImageOffset = 0; 
    private int yDragImageOffset = 0; 
    private int xDragTouchOffset = 0; 
    private int yDragTouchOffset = 0; 
    private MapView location; 
    private boolean pickupOrDrop; 

    public LocationMarker(Activity newAppContext, MapView newLocation, Drawable newMarker, 
      ImageView newPoint, boolean newWhichPoint) { 
     super(newMarker); 
     this.appContext = newAppContext; 
     this.location = newLocation; 
     this.marker = newMarker; 
     this.dragImage = newPoint; 
     this.pickupOrDrop = newWhichPoint; 

     xDragImageOffset = dragImage.getDrawable().getIntrinsicWidth()/2; 
     yDragImageOffset = dragImage.getDrawable().getIntrinsicHeight(); 
     populate(); 
    } 

    public void placeMarker(GeoPoint myPoint) { 
     OverlayItem toDrop = new OverlayItem(myPoint, "", ""); 
     items.add(toDrop); 
     populate(); 
    } 

    @Override 
    protected OverlayItem createItem(int i) { 
     return (items.get(i)); 
    } 

    @Override 
    public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
     super.draw(canvas, mapView, shadow); 
     boundCenterBottom(marker); 
    } 

    @Override 
    public int size() { 
     return (items.size()); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event, MapView mapView) { 
     if (pickupOrDrop != whichPoint) 
      return false; 
     final int action = event.getAction(); 
     final int x = (int) event.getX(); 
     final int y = (int) event.getY(); 
     boolean result = false; 

     // Draw temp image 
     if (action == MotionEvent.ACTION_DOWN) { 
      Log.d("iTaxeeta:Overlay", "Action Down" + marker.toString()); 
      GeoPoint myPoint = null; 
      if (items.isEmpty()) { 
       if (whichPoint == PICKUP) { 
        myPoint = source = location.getProjection().fromPixels(
          x - xDragTouchOffset, y - yDragTouchOffset); 
       } else if (whichPoint == DROP) { 
        myPoint = destination = location.getProjection().fromPixels(
          x - xDragTouchOffset, y - yDragTouchOffset); 
       } 
       OverlayItem toDrop = new OverlayItem(myPoint, "", ""); 
       items.add(toDrop); 
       populate(); 
      } 
      for (OverlayItem item : items) { 
       Point p = new Point(0, 0); 
       Log.d("iTaxeeta:Overlay", item.getTitle()); 
       location.getProjection().toPixels(item.getPoint(), p); 
       if (hitTest(item, marker, x - p.x, y - p.y)) { 
        result = true; 
        inDrag = item; 
        items.remove(inDrag); 
        populate(); 

        xDragTouchOffset = 0; 
        yDragTouchOffset = 0; 
        setDragImagePosition(p.x, p.y); 

        dragImage.setVisibility(View.VISIBLE); 
        xDragTouchOffset = x - p.x; 
        yDragTouchOffset = y - p.y; 

        break; 
       } 
       else { 
        items.clear(); 
        populate(); 
        if (whichPoint == PICKUP) 
         myPoint = source = location.getProjection().fromPixels(
           x - xDragTouchOffset, y - yDragTouchOffset); 
        else if (whichPoint == DROP) 
         myPoint = destination = location.getProjection().fromPixels(
           x - xDragTouchOffset, y - yDragTouchOffset); 
        new GetGeoAddress((IActionBar) appContext, myPoint).execute(); 
        OverlayItem toDrop = new OverlayItem(myPoint, "", ""); 
        items.add(toDrop); 
        populate(); 
        if (source != null && destination != null) { 
         searchCabs.setEnabled(true); 
         // tip.startAnimation(rollUpAnimation); 
         searchCabs.setTextColor(Color.parseColor("#eeeee4")); 
         if (whichPoint == PICKUP) 
          searchCabs.setBackgroundColor(Color.parseColor("#fe000a")); 
         else if (whichPoint == DROP) 
          searchCabs.setBackgroundColor(Color.parseColor("#17ee27")); 
        } 
        break; 
       } 
      } 
     } 
     // Draw temp image while moving finger across the screen 
     else if (action == MotionEvent.ACTION_MOVE && inDrag != null) { 
      Log.d("iTaxeeta:Overlay", "Action Move" + marker.toString()); 
      setDragImagePosition(x, y); 
      result = true; 
     } 
     // Position the selected point now 
     else if (action == MotionEvent.ACTION_UP && inDrag != null) { 
      GeoPoint myPoint = null; 
      Log.d("iTaxeeta:Overlay", "Action Up" + marker.toString()); 
      dragImage.setVisibility(View.VISIBLE); 
      if (whichPoint == PICKUP) 
       myPoint = source = location.getProjection().fromPixels(x - xDragTouchOffset, 
         y - yDragTouchOffset); 
      else if (whichPoint == DROP) 
       myPoint = destination = location.getProjection().fromPixels(
         x - xDragTouchOffset, y - yDragTouchOffset); 
      OverlayItem toDrop = new OverlayItem(myPoint, inDrag.getTitle(), 
        inDrag.getSnippet()); 
      items.add(toDrop); 
      populate(); 
      inDrag = null; 
      new GetGeoAddress((IActionBar) appContext, myPoint).execute(); 
      if (source != null && destination != null) { 
       searchCabs.setEnabled(true); 
       // tip.startAnimation(rollUpAnimation); 
       searchCabs.setTextColor(Color.parseColor("#eeeee4")); 
       if (whichPoint == PICKUP) 
        searchCabs.setBackgroundColor(Color.parseColor("#fe000a")); 
       else if (whichPoint == DROP) 
        searchCabs.setBackgroundColor(Color.parseColor("#17ee27")); 
      } 
      result = true; 

     } 

     return (result || super.onTouchEvent(event, mapView)); 
    } 
+0

Grazie per la risposta, ma in realtà non userò il servizio di localizzazione fornito dal telefono. Poiché non sto usando Wifi o GPS. Ho il mio algoritmo auto-progettato per trovare la posizione. Quindi la domanda è semplicemente come sovrapporre un marcatore alla mia vista personalizzata e spostarlo come necessario. –

Problemi correlati