Cómo dibujar una imagen de marcador pequeño y mantener la actualización de su posición en mi imagen de mapa PERSONALIZADO? – Android

Actualmente estoy desarrollando un sistema de seguimiento para trazar la trayectoria del movimiento del usuario dentro de una habitación o lo que sea.

Ahora he conseguido importar mi mapa en la aplicación y el mapa es libre de ser ampliado y movido. El siguiente paso es colocar un marcador para indicar la ubicación del usuario en el mapa y mover la marca alrededor del mapa. (Como flotando en el mapa)

Lo he leído en alguna parte y creo que esto se puede hacer con MyLocationOverlay , pero la mayoría de los ejemplos en línea son todos para aplicarlo en el google map . Sin embargo, en mi caso, mi mapa no es google map , es mi propio mapa . (El mapa puede ser el mapa de mi habitación o incluso un mapa que me dibujo!)

He hecho el algoritmo de seguimiento, es decir , sé dónde colocar mi imagen de marcador .

Así que la única pregunta que queda es cómo presentar la imagen del marcador en la parte superior de la imagen del mapa.

En los detalles, tengo una vista autodefinida, MapView, como sigue:

 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; } } } 

Hasta aquí, el mapa se introduce con éxito en la aplicación, y es movible y zoomable.

Y luego, inserto esta vista personalizada en el archivo XML de diseño de la siguiente manera:

 <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> 

Basándome en toda esta información, ¿cómo puedo dibujar un punto y actualizar constantemente su posición en mi mapa?

Actualizar:

La pregunta es simplemente poner otra imagen pequeña encima de una vista personalizada y moverla alrededor.

También adjunto la captura de pantalla aquí para su referencia:

Introduzca aquí la descripción de la imagen

El área sobre los botones y las vistas de texto es mi MapView

Aquí es parte de mi código que hizo lo que pides (pero sólo para el gesto de arrastre), el zoom es un poco complicado. Necesito saber en qué punto se basa el zoom, por ejemplo, el centro de dos dedos o el (0,0) en la pantalla

Primera inicial del punto pero invisible

 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); 

Para añadir punto con la posición relacionada para asignar

DotImageWidth / Height puede llegar desde 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 antes del interruptor

 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(); 

Case 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); 

Para empezar, use la API de LocationClient (en lugar de LocationManager) ya que funcionan muy bien con los proveedores de gps mezclados wifi y red. También utilizan sensores para reconocer un movimiento para que puedan ahorrar en la batería.

Utilizo el siguiente codigo LocationOverlay colocando mis iconos en el mapa. Modifiqúelo para requisitos particulares para su necesidad. Es un poco peligroso, pero funciona.

 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 - px, y - py)) { result = true; inDrag = item; items.remove(inDrag); populate(); xDragTouchOffset = 0; yDragTouchOffset = 0; setDragImagePosition(px, py); dragImage.setVisibility(View.VISIBLE); xDragTouchOffset = x - px; yDragTouchOffset = y - py; 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)); } 
  • Android getFromLocationName devuelve resultados fuera del cuadro delimitador
  • ¿Cómo añadir un lugar erróneo en mapview?
  • Añadir crosshair overlay a google map v2
  • No haga clic en el marcador después de hacer clic en android map v2
  • Superposiciones de mapa más eficientes en Android
  • ¿Dónde puedo obtener el gráfico de flecha "android" predeterminado para MapView?
  • Uso de Google MapView v2 en Live Wallpaper
  • Requerido com.google.android.gms.GoogleMap encontrado vacío
  • Android MapView: ajusta el zoom automáticamente hasta que se visualicen todas las opciones de ItemizedOverlay
  • onDoupleTap no se dispara
  • ¿Cómo mostrar un mapa en una mapactividad de Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.