2013-07-05 13 views
11

Tôi hiện đang phát triển một hệ thống theo dõi để vạch ra quỹ đạo chuyển động của người dùng bên trong một căn phòng hoặc điều gì đó.Làm thế nào để vẽ một hình ảnh đánh dấu nhỏ và tiếp tục làm mới vị trí của nó trên hình ảnh bản đồ TÙY CHỈNH của tôi? - Android

Bây giờ tôi đã quản lý để nhập bản đồ của mình vào ứng dụng và bản đồ được phóng to và di chuyển miễn phí. Bước tiếp theo là đặt điểm đánh dấu để cho biết vị trí của người dùng trên bản đồ và di chuyển điểm đánh dấu xung quanh bản đồ. (như nổi trên bản đồ)

Tôi đọc nó ở đâu đó và nghĩ rằng điều này có thể được thực hiện với MyLocationOverlay, nhưng hầu hết các ví dụ trực tuyến là tất cả để áp dụng nó vào google map. Tuy nhiên, trong trường hợp của tôi, bản đồ của tôi không phải là google map, nó là bản đồ OWN của tôi. (Bản đồ có thể là bản đồ của căn phòng của tôi hoặc thậm chí là bản đồ mà tôi vẽ bản thân mình!)

Tôi đã thực hiện thuật toán theo dõi, tức là Tôi biết vị trí đặt hình ảnh đánh dấu là.

Vì vậy, câu hỏi duy nhất vẫn là cách trình bày hình ảnh điểm đánh dấu ở trên cùng của hình ảnh bản đồ.

Cụ thể, tôi có một cái nhìn tự xác định, MapView, như sau:

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

} 

Lên đến đây, bản đồ là thành công đầu vào vào ứng dụng, và nó là cả di chuyển và Zoomable.

Và sau đó, tôi chèn giao diện tùy chỉnh này vào tệp XML bố trí như sau:

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

Dựa trên tất cả thông tin này, làm thế nào có thể tôi vẽ một dấu chấm và liên tục cập nhật vị trí của nó trên bản đồ của tôi?

Cập nhật:

Câu hỏi đặt ra chỉ đơn giản về việc đưa một hình ảnh nhỏ trên đầu trang của một giao diện tùy chỉnh và di chuyển nó xung quanh là.

Tôi cũng đính kèm ảnh chụp màn hình vào đây để bạn tham khảo:

enter image description here

Diện tích trên các nút và TextView là tôi MapView

+1

Kiểm tra nguồn gốc của Redpin. Nó thực hiện chính xác rằng – Reno

Trả lời

1

Đây là một phần mã của tôi đã làm những gì bạn yêu cầu (nhưng chỉ dành cho cử chỉ kéo), thu phóng hơi phức tạp. Tôi cần biết điểm phóng to của bạn dựa vào đâu, ví dụ như giữa hai ngón tay hoặc (0.0) trên màn hình

Đầu tiên ban đầu chấm nhưng vô hình

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

cho thêm dấu chấm với vị trí liên quan đến bản đồ

dotImageWidth/Chiều cao có thể nhận được từ 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); 

trong onTouchEvent trước khi chuyển đổi

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

trường hợp 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; 

trường hợp 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

Tôi nghĩ rằng bạn đã hiểu sai câu hỏi của tôi một chút. Câu hỏi của tôi không thực sự là về bản đồ. Đơn giản chỉ cần đặt: làm thế nào tôi có thể đặt một hình ảnh trên đầu trang của một hình ảnh? Bạn có thể vui lòng sửa đổi câu trả lời của bạn cho phù hợp? Cảm ơn. –

+0

Tôi trả lời câu hỏi của bạn chỉ cần thay đổi ImageButton thành ImageView và thêm id vào RelativeLayout của bạn và thêm Hình ảnh trên Bố cục. Tôi không thể ràng buộc bản đồ và dấu chấm để tôi viết khi bạn di chuyển bản đồ của bạn như thế nào để thay đổi dấu chấm của bạn với nó – Gina

2

Để bắt đầu, sử dụng LocationClient API (thay vì LocationManager) kể từ khi họ làm việc thực sự tốt với các nhà cung cấp gps hỗn hợp wifi và mạng. Họ cũng sử dụng cảm biến để nhận ra một chuyển động để chúng có thể tiết kiệm pin.

Tôi sử dụng codrô LocationOverlay sau đây đặt các biểu tượng của tôi lên bản đồ. Tùy chỉnh nó cho nhu cầu của bạn. Hơi thô ráp nhưng hiệu quả.

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

Cảm ơn câu trả lời, nhưng tôi thực sự sẽ không sử dụng dịch vụ định vị được cung cấp bởi điện thoại. Vì tôi không sử dụng Wifi hoặc GPS. Tôi có thuật toán tự thiết kế để tìm vị trí. Vì vậy, câu hỏi đơn giản là cách che phủ điểm đánh dấu trên chế độ xem tùy chỉnh của tôi và di chuyển nó xung quanh khi cần. –

Các vấn đề liên quan