23

v2 API का उपयोग करके Google मानचित्र पर मार्कर को एनिमेट करने का सबसे अच्छा तरीका क्या है?Google मानचित्र पर एनिमेटिंग मार्कर v2

मैं मानचित्र-केंद्रित गेम पर काम कर रहा हूं जहां मैं लोगों के स्थानों को ट्रैक करता हूं और उन्हें देखने के लिए मानचित्र पर प्रदर्शित करता हूं। जैसे-जैसे लोग आगे बढ़ते हैं, मैं अपने वर्तमान से अपनी नवीनतम स्थिति में मार्कर को एनिमेट करना चाहता हूं। प्रत्येक व्यक्ति की दिशा होती है, इसलिए मुझे मार्कर को उचित रूप से घुमाने की आवश्यकता है।

नए Google मानचित्र API का उपयोग करके इसे करने का सबसे अच्छा तरीका क्या है?

प्रासंगिक कोड यहाँ है:

+0

संभावित [डुप्लिकेट] (http://stackoverflow.com/questions/13972401/google-map-v2-marker-animation)? यदि आपके द्वारा चुने गए समाधान में, आपको लंबी अवधि में अंतरण करने की आवश्यकता होगी, 180 वें मेरिडियन में साइन फ़्लिपिंग पर ध्यान दें। – hleinone

+0

@ हेलिनोन काफी नहीं है। जिस व्यक्ति का आपने उल्लेख किया है उसके लिए समाधान है) कैमरे को ले जाना बी) एक मार्कर को एक अलग स्थिति में ले जाना। मुझे बी की आवश्यकता है) और यह बस Marker.setPosition() कर कर किया जा सकता है। हालांकि, मार्कर का एक आइकन बदलना (मैं आंदोलन की दिशा के साथ घूर्णन छवि दिखाऊंगा) काम नहीं करता है। ऐसा लगता है कि आइकन बदलने के लिए मानचित्र से सभी मार्करों को साफ़ करने की आवश्यकता है। –

+0

पॉलीलाइन मार्गों को एनिमेट करने के लिए https://github.com/amalChandran/google-maps-route-animation – amalBit

उत्तर

47

कुछ गूगल इंजीनियरों कैसे, एक अंत बिंदु करने के लिए एक प्रारंभिक बिंदु से मार्करों चेतन करने के लिए एंड्रॉयड के सभी विभिन्न संस्करणों के लिए के बारे में कुछ सुरुचिपूर्ण नमूना कोड के साथ एक अच्छा डेमो वीडियो प्रदान की है

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

और कार्रवाई में यह सभी का एक अच्छा डेमो वीडियो।

चिह्न एक बिटमैप दिखाया गया:

http://youtu.be/WKfZsCKSXVQ

नीचे

प्रलेखन में पुराने बहिष्कृत किया गया उत्तर, यह उल्लेख किया गया है कि मार्कर प्रतीक नहीं बदला जा सकता मार्कर के लिए। यदि आइकन सेट नहीं किया गया है, तो एक डिफ़ॉल्ट आइकन प्रदर्शित होता है। आप डिफ़ॉल्ट मार्कर (फ्लोट) का उपयोग कर डिफ़ॉल्ट आइकन का वैकल्पिक रंग निर्दिष्ट कर सकते हैं। मार्कर बनाने के बाद आप आइकन को नहीं बदल सकते हैं। तो बाहर जो मार्कर आपको अपडेट करने की आवश्यकता समझ Link a Marker to an Object,:

Google Maps API v2 Documentation

आप शायद एक विधि यहाँ वर्णित के समान का उपयोग कर विशिष्ट मार्कर का ट्रैक रखने के करने जा रहे हैं,। मार्कर पर .remove() पर कॉल करें, फिर अपनी इच्छित "दिशा" के आधार पर एक घुमावदार छवि बनाएं, उस छवि के साथ एक नया मार्कर बनाएं, और मानचित्र पर नया मार्कर जोड़ें।

आपको मानचित्र को "साफ़" करने की आवश्यकता नहीं है, बस उस मार्कर को हटाएं जिसे आप संशोधित करना चाहते हैं, एक नया बनाएं, फिर इसे मानचित्र पर वापस जोड़ें।

दुर्भाग्य से, नया मैप्स एपीआई अभी तक बहुत लचीला नहीं है। उम्मीद है कि Google इस पर सुधार जारी रखेगा।

+1

यह एक उत्तर कैसे है? मैं वास्तव में नहीं देखता कि यह कैसे मार्कर आंदोलन को एनिमेट करने का जवाब देता है ... – Ted

+0

यह एक उत्तर है क्योंकि सवाल पूछे जाने पर मार्करों को एनिमेट करने का कोई तरीका नहीं था। यदि आप मार्करों को एनिमेट करने का कोई तरीका प्रदान कर सकते हैं, तो कृपया स्वयं प्रश्न का उत्तर दें। – DiscDev

+0

@Ted - मैंने कुछ खोज किया और एक "असली" जवाब पाया और मेरी पोस्ट अपडेट की। इसे ऊपर देखें, यह बहुत साफ और समझने में आसान है। – DiscDev

5

मार्कर का एपीआई v2 के rev.7 के रूप में एक नया फ़ंक्शन जोड़ा गया है। Marker.setIcon, ताकि आप दिशा दिखाने के लिए एकाधिक आइकन का उपयोग कर सकें।

+2

क्या आपने कभी सेट आइकन के साथ एनीमेशन की कोशिश की है? मेरे मामले में, कभी-कभी झपकी खराब होती है (बहुत तेज या धीमी) ... – mrroboaat

+0

@ एट मुझे पता है कि अभी भी इसमें समस्याएं हैं। यह सब के बाद आईपीसी कॉल है। हो सकता है कि Googlers वास्तविक एनीमेशन समर्थन जोड़ सकें जैसे उन्होंने आईओएस के लिए किया था। –

+0

निश्चित रूप से सहमत – mrroboaat

3

प्रयोग DiscDev's ansrwer के लिए उदाहरण (ऊपर):

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

और आप के उन लोगों के लिए जो जीपीएस/या किसी भी स्थिति प्रदाता उस स्थान अपडेट प्राप्त उपयोग करता है:

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

महत्वपूर्ण:

1MarkerAnimation.java के भीतर यदि एनीमेशन durat आयन एक्स, पर सेट है और आप एक्स के बाद छोटी दर में स्थान अपडेट प्राप्त कर रहे हैं, एकाधिक एनिमेशन चलेंगे, और आप मार्कर फ़्लिकर देख सकते हैं।

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

आनंद लें:

इससे बचने के लिए, animationMarkerToICS विधि (मैं यहाँ उदाहरण के लिए animationMarkerToICS लिया), कुछ इस तरह,

पूर्ण विधि कार्यान्वयन दिखना चाहिए।

+0

हम ज़ूम स्तर कैसे सेट कर सकते हैं? – Sophie

+0

ज़ूम इस प्रश्न के लिए प्रासंगिक नहीं है, कृपया ज़ूम के लिए [यहां] देखें (https://stackoverflow.com/questions/13932441/android-google-maps-v2-set-zoom-level-for-mylocation) – 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); 
        } 
       } 
      } 
     }); 

    } 
संबंधित मुद्दे