23

Cách tốt nhất để tạo hiệu ứng đánh dấu trên Google Maps bằng cách sử dụng API v2 là gì?Điểm đánh dấu hoạt ảnh trên Google Maps v2

Tôi đang làm việc trên một trò chơi tập trung vào bản đồ, nơi tôi theo dõi vị trí của mọi người và hiển thị chúng trên bản đồ cho nhau để xem. Khi mọi người di chuyển, tôi muốn tạo hiệu ứng đánh dấu từ vị trí hiện tại của anh ấy đến vị trí mới nhất của anh ấy. Mỗi người có một hướng, vì vậy tôi cần phải xoay điểm đánh dấu một cách thích hợp.

Cách tốt nhất để làm điều đó bằng API Google Maps mới là gì?

+0

Có thể [trùng lặp] (http://stackoverflow.com/questions/13972401/google-map-v2-marker-animation)? Nếu trong giải pháp bạn chọn, bạn sẽ cần phải nội suy các kinh độ, chú ý đến dấu hiệu lật ở kinh tuyến thứ 180. – hleinone

+0

@hleinone không hoàn toàn. Một trong những bạn đã đề cập có giải pháp cho a) di chuyển máy ảnh b) di chuyển một điểm đánh dấu đến một vị trí khác nhau. Tôi cần b) và nó có thể được thực hiện đơn giản chỉ bằng cách thực hiện Marker.setPosition(). Tuy nhiên, việc thay đổi một biểu tượng của điểm đánh dấu (tôi sẽ hiển thị hình ảnh xoay theo hướng chuyển động) không hoạt động. Có vẻ như, người ta cần xóa tất cả các điểm đánh dấu trên bản đồ để thay đổi biểu tượng. –

+0

Để tạo hoạt ảnh cho các tuyến đường polyline https://github.com/amalChandran/google-maps-route-animation – amalBit

Trả lời

47

Một số kỹ sư của Google đã cung cấp một video giới thiệu tốt đẹp với một số mẫu mã thanh lịch về làm thế nào để động đánh dấu từ một điểm khởi đầu đến điểm kết thúc, cho tất cả các phiên bản khác nhau của Android:

Mã liên quan là ở đây:

https://gist.github.com/broady/6314689

Và một video giới thiệu tuyệt đẹp về tất cả hành động.

http://youtu.be/WKfZsCKSXVQ

OLD ĐÁP NỮA DƯỚI

Trong tài liệu, nó được đề cập rằng Marker Icons không thể thay đổi:

Biểu tượng

Một bitmap đó được hiển thị cho điểm đánh dấu. Nếu biểu tượng không được đặt, biểu tượng mặc định sẽ hiển thị. Bạn có thể chỉ định màu thay thế của biểu tượng mặc định bằng cách sử dụng defaultMarker (float). Bạn không thể thay đổi biểu tượng khi bạn đã tạo điểm đánh dấu.

Google Maps API v2 Documentation

Bạn sẽ phải theo dõi các dấu hiệu cụ thể, có lẽ sử dụng một phương pháp tương tự như mô tả ở đây: Link a Marker to an Object, sau đó tìm ra những dấu hiệu bạn cần cập nhật. Hãy gọi .remove() trên điểm đánh dấu, sau đó tạo hình ảnh được xoay tùy thuộc vào "hướng" bạn muốn, tạo Marker mới với hình ảnh đó và thêm Marker mới vào bản đồ.

Bạn không cần phải "xóa" bản đồ, chỉ cần xóa điểm đánh dấu bạn muốn sửa đổi, tạo một điểm đánh dấu mới, sau đó thêm nó trở lại bản đồ.

Thật không may, API Maps mới chưa thật linh hoạt. Hy vọng rằng Google tiếp tục cải thiện nó.

+1

Câu trả lời này như thế nào? Tôi không thực sự nhìn thấy nó như thế nào trả lời làm thế nào để animate các phong trào đánh dấu ... – Ted

+0

Đó là một câu trả lời bởi vì không có cách nào để animate các dấu hiệu tại thời điểm câu hỏi đã được hỏi. Nếu bạn có thể cung cấp một cách để tạo hiệu ứng cho các điểm đánh dấu, vui lòng tự trả lời câu hỏi. – DiscDev

+0

@Ted - Tôi đã thực hiện một số tìm kiếm xung quanh và tìm thấy câu trả lời "thực" và cập nhật bài đăng của tôi. Kiểm tra nó ở trên, nó khá gọn gàng và dễ hiểu. – DiscDev

5

Điểm đánh dấu có chức năng mới được thêm vào như rev.7 của API v2. Marker.setIcon, vì vậy bạn có thể sử dụng nhiều biểu tượng để hiển thị hướng.

+2

Bạn đã bao giờ thử hoạt ảnh với setIcon chưa? Trong trường hợp của tôi, đôi khi chớp mắt là xấu (quá nhanh hoặc chậm) ... – mrroboaat

+0

@aat Tôi biết vẫn còn vấn đề với nó. Đó là cuộc gọi IPC sau khi tất cả. Có thể nhân viên Google có thể thêm hỗ trợ hoạt ảnh thực như họ đã làm cho iOS. –

+0

Chắc chắn đã đồng ý – mrroboaat

3

Cách sử dụng Ví dụ cho DiscDev's ansrwer (Trên):

LatLng fromLocation = new LatLng(38.5, -100.4); // Whatever origin coordinates 
LatLng toLocation = new LatLng(37.7, -107.7); // Whatever destination coordinates 
Marker marker = mMap.addMarker(new MarkerOptions().position(firstLocation)); 
MarkerAnimation.animateMarkerToICS(marker, toLocation, new LatLngInterpolator.Spherical()); 

Và đối với những ai sử dụng GPS/hoặc bất kỳ nhà cung cấp vị trí đó nhận cập nhật vị trí:

Marker ourGlobalMarker; 
// We've got a location from some provider of ours, now we can call: 
private void updateMarkerPosition(Location newLocation) { 

    LatLng newLatLng = new LatLng(newLocation.getLatitude(), newLocation.getLongitude()); 

    if(ourGlobalMarker == null) { // First time adding marker to map 
     ourGlobalMarker = mMap.addMarker(new MarkerOptions().position(newLatLng)); 
    } 
    else { 
     MarkerAnimation.animateMarkerToICS(ourGlobalMarker, newLatLng, new LatLngInterpolator.Spherical()); 
    }   
} 

QUAN TRỌNG:

Trong vòng 1MarkerAnimation.java Nếu hoạt ảnh durat ion được đặt thành X, và bạn đang nhận cập nhật vị trí với tốc độ nhỏ hơn X, nhiều hoạt ảnh sẽ chạy và bạn có thể thấy các điểm đánh dấu nhấp nháy.

Để tránh điều này, các phương pháp animationMarkerToICS (Tôi đã ở đây animationMarkerToICS ví dụ), nên giống như thế này,

đầy đủ phương pháp thực hiện:

private static Animator animator; // MAKING ANIMATOR GLOBAL INSTEAD OF LOCAL TO THE STATIC FUNCTION 

... 

// Ice Cream Sandwich compatible 
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
public static void animateMarkerToICS(Marker marker, LatLng finalPosition, final LatLngInterpolator latLngInterpolator) { 

    TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() { 
     @Override 
     public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { 
      return latLngInterpolator.interpolate(fraction, startValue, endValue); 
     } 
    }; 
    Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position"); 

    // ADD THIS TO STOP ANIMATION IF ALREADY ANIMATING TO AN OBSOLETE LOCATION 
    if(animator != null && animator.isRunning()) { 
     animator.cancel(); 
     animator = null; 
    } 
    animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition); 
    animator.setDuration((long) ANIMATION_DURATION); 
    animator.start(); 
} 

Thưởng thức.

+0

cách chúng tôi có thể đặt mức thu phóng? – Sophie

+0

Thu phóng không liên quan đến câu hỏi này, vui lòng xem [tại đây] (https://stackoverflow.com/questions/13932441/android-google-maps-v2-set-zoom-level-for-mylocation) để thu phóng – Mercury

0
//Your code   
    double bearing = 0.0; 
      bearing = getBearing(new LatLng(
               currentPosition.latitude 
               ,currentPosition.longitude), 
             new LatLng(
               nextPosition.latitude, 
               nextPosition.longitude)); 

      bearing -= 90; 
          CameraPosition cameraPosition = new CameraPosition 
            .Builder() 
            .target(new LatLng(nextPosition.latitude, nextPosition.longitude)) 
            .bearing((float) bearing) 
            .zoom(ZOOM_LEVEL).build(); 


          mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000, null); 

       animatedMarker(currentPosition,nextPosition,busMarker); 



       //Method for finding bearing between two points 
        private float getBearing(LatLng begin, LatLng end) { 
         double lat = Math.abs(begin.latitude - end.latitude); 
         double lng = Math.abs(begin.longitude - end.longitude); 
         if (begin.latitude < end.latitude && begin.longitude < end.longitude) 
          return (float) (Math.toDegrees(Math.atan(lng/lat))); 
         else if (begin.latitude >= end.latitude && begin.longitude < end.longitude) 
          return (float) ((90 - Math.toDegrees(Math.atan(lng/lat))) + 90); 
         else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude) 
          return (float) (Math.toDegrees(Math.atan(lng/lat)) + 180); 
         else if (begin.latitude < end.latitude && begin.longitude >= end.longitude) 
          return (float) ((90 - Math.toDegrees(Math.atan(lng/lat))) + 270); 
         return -1; 
        } 

    private void animatedMarker(final LatLng startPosition,final LatLng nextPosition,final Marker mMarker) 
    { 

     final Handler handler = new Handler(); 
     final long start = SystemClock.uptimeMillis(); 
     final Interpolator interpolator = new AccelerateDecelerateInterpolator(); 
     final float durationInMs = 3000; 
     final boolean hideMarker = false; 

     handler.post(new Runnable() { 
      long elapsed; 
      float t; 
      float v; 

      @Override 
      public void run() { 
       // Calculate progress using interpolator 
       elapsed = SystemClock.uptimeMillis() - start; 
       t = elapsed/durationInMs; 
       v = interpolator.getInterpolation(t); 

       LatLng currentPosition = new LatLng(
         startPosition.latitude * (1 - t) + nextPosition.latitude * t, 
         startPosition.longitude * (1 - t) + nextPosition.longitude * t); 

       mMarker.setPosition(currentPosition); 

       // Repeat till progress is complete. 
       if (t < 1) { 
        // Post again 16ms later. 
        handler.postDelayed(this, 16); 
       } else { 
        if (hideMarker) { 
         mMarker.setVisible(false); 
        } else { 
         mMarker.setVisible(true); 
        } 
       } 
      } 
     }); 

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