2012-12-18 25 views
34

से LatLngBounds वहाँ के साथ एंड्रॉयड गूगल मैप्स एपीआई v2 एक CameraPosition से दिखाई नक्शे के LatLngBounds पाने के लिए इतना है कि मैं OnCameraChangeListener का उपयोग मार्करों के लिए नए डेटा लाने जाने के लिए कर सकते हैं एक सरल तरीका है।गूगल मैप्स एपीआई v2: CameraPosition

mMap.setOnCameraChangeListener(new OnCameraChangeListener() { 
      @Override 
      public void onCameraChange(CameraPosition position) { 
       LatLngBounds bounds = ?; 
       fetchNewData(bounds); 
      } 
     }); 

उत्तर

27

अद्यतन अगस्त वर्ष 2016 के बाद से

सारांशसही जवाब अब के लिए इस समस्या को नई onCameraIdle उपयोग करने के लिए है, OnCameraChangeListener के बजाय, जो अब deprecated है। कैसे बोले पढ़ें।

अब आप एंड्रॉइड के लिए Google मानचित्र के नवीनतम संस्करण पर "ड्रैगएंड" जैसी घटनाओं और अन्य घटनाओं को भी सुन सकते हैं।

रूप docs में दिखाया गया है, तो आप कई की समस्या से बच सकते हैं (उर्फ "कई") OnCameraChangeListener के नए श्रोताओं का उपयोग करके कॉल। उदाहरण के लिए, अब आप यह जांचने में सक्षम हैं कि कैमरे की चाल के पीछे क्या कारण है, जो अनुरोध के अनुसार fetchData समस्या वाले जोड़े के लिए आदर्श है। निम्नलिखित कोड सीधे दस्तावेज़ों से लिया जाता है। एक और बात, Google Play Services 9.4 का उपयोग करना आवश्यक है।

public class MyCameraActivity extends FragmentActivity implements 
     OnCameraMoveStartedListener, 
     OnCameraMoveListener, 
     OnCameraMoveCanceledListener, 
     OnCameraIdleListener, 
     OnMapReadyCallback { 

    private GoogleMap mMap; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_my_camera); 

     SupportMapFragment mapFragment = 
      (SupportMapFragment) getSupportFragmentManager() 
        .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
    } 

    @Override 
    public void onMapReady(GoogleMap map) { 
     mMap = map; 

     mMap.setOnCameraIdleListener(this); 
     mMap.setOnCameraMoveStartedListener(this); 
     mMap.setOnCameraMoveListener(this); 
     mMap.setOnCameraMoveCanceledListener(this); 

     // Show Sydney on the map. 
     mMap.moveCamera(CameraUpdateFactory 
       .newLatLngZoom(new LatLng(-33.87365, 151.20689), 10)); 
    } 

    @Override 
    public void onCameraMoveStarted(int reason) { 

     if (reason == OnCameraMoveStartedListener.REASON_GESTURE) { 
      Toast.makeText(this, "The user gestured on the map.", 
          Toast.LENGTH_SHORT).show(); 
     } else if (reason == OnCameraMoveStartedListener 
           .REASON_API_ANIMATION) { 
      Toast.makeText(this, "The user tapped something on the map.", 
          Toast.LENGTH_SHORT).show(); 
     } else if (reason == OnCameraMoveStartedListener 
           .REASON_DEVELOPER_ANIMATION) { 
      Toast.makeText(this, "The app moved the camera.", 
          Toast.LENGTH_SHORT).show(); 
     } 
    } 

    @Override 
    public void onCameraMove() { 
     Toast.makeText(this, "The camera is moving.", 
         Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onCameraMoveCanceled() { 
     Toast.makeText(this, "Camera movement canceled.", 
         Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onCameraIdle() { 
     Toast.makeText(this, "The camera has stopped moving. Fetch the data from the server!", Toast.LENGTH_SHORT).show(); 
     LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds; 
     fetchData(bounds) 
    } 
} 

एक कुशल समाधान के लिए युक्ति अगस्त वर्ष 2016

पहले की तरह सवाल ठीक से जवाब है, मैं अगले अंक होने के लिए एक संभावना पर उस पर जोड़ना चाहते हैं।

इस विधि को ट्रिगर करने की आवृत्ति के कारण सर्वर से डेटा लाने के लिए OnCameraChangeListener का उपयोग करते समय समस्या उत्पन्न होती है।

वहाँ एक issue कैसे पागलपन से बार-बार इस विधि trigged है जब प्रश्न के उदाहरण में इस प्रकार सरल मानचित्र कर रपट, पर सूचना दी है, तो यह और भी कोई कैमरा परिवर्तन के लिए, बहुत कम कैमरा परिवर्तन के लिए fetchData अनेक अनुक्रमिक बार ट्रिगर करेगा , हाँ, ऐसा होता है कि कैमरा सीमाएं नहीं बदली हैं, लेकिन विधि ट्रिगर हो गई है।

यह सर्वर साइड प्रदर्शन पर प्रभाव डाल सकता है और सर्वर से अनुक्रमिक रूप से दस बार डेटा प्राप्त करके कई उपकरणों के संसाधनों को बर्बाद कर देगा।

आप इस समस्या के लिए उस लिंक के कामकाज में पा सकते हैं, लेकिन अभी तक ऐसा करने का आधिकारिक तरीका नहीं है, उदाहरण के लिए, एक वांछित dragEnd, या cameraChangeEnd कॉलबैक का उपयोग करना।

वहां से मौजूद लोगों के आधार पर एक उदाहरण है, मैं कॉल के समय अंतराल के साथ खेलकर और समान सीमाओं के साथ कॉल को छोड़कर उपर्युक्त समस्या से कैसे बचता हूं।

// Keep the current camera bounds 
private LatLngBounds currentCameraBounds; 

new GoogleMap.OnCameraChangeListener() { 
    private static int CAMERA_MOVE_REACT_THRESHOLD_MS = 500; 
    private long lastCallMs = Long.MIN_VALUE; 

    @Override 
    public void onCameraChange(CameraPosition cameraPosition) { 
     LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; 
     // Check whether the camera changes report the same boundaries (?!), yes, it happens 
     if (currentCameraBounds.northeast.latitude == bounds.northeast.latitude 
     && currentCameraBounds.northeast.longitude == bounds.northeast.longitude 
     && currentCameraBounds.southwest.latitude == bounds.southwest.latitude 
     && currentCameraBounds.southwest.longitude == bounds.southwest.longitude) { 
     return; 
     } 

     final long snap = System.currentTimeMillis(); 
     if (lastCallMs + CAMERA_MOVE_REACT_THRESHOLD_MS > snap) { 
     lastCallMs = snap; 
     return; 
     } 

     fetchData(bounds); 

     lastCallMs = snap; 
     currentCameraBounds = bounds; 

} 
+0

बहुत अच्छा! शायद मुझे कई घंटे की समझ समझने और फिर इस समस्या को हल करने में बचाया। धन्यवाद! – EZDsIt

+0

@EZDs आपका स्वागत है! – Eduardo

+0

आपको फ़ील्ड 'CurrentCameraBounds' फ़ील्ड के लिए 'शून्य' की भी जांच करनी चाहिए। –

74

आप कैमरापॉशन से लैट्लिंगबाउंड नहीं प्राप्त कर सकते हैं, लेकिन आप उन्हें GoogleMap से आसानी से प्राप्त कर सकते हैं।

private GoogleMap mMap; 

mMap.setOnCameraChangeListener(new OnCameraChangeListener() { 
      @Override 
      public void onCameraChange(CameraPosition position) { 
       LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds; 
       fetchData(bounds); 
      } 
     }); 
+0

मुझे आश्चर्य है कि उन्होंने इसे इस तरह क्यों स्थापित किया है। दृश्य क्षेत्र में नक्शा प्रक्षेपण के साथ कुछ भी नहीं होना चाहिए। – capdragon

+4

@ कैपड्रैगन रुको, क्या?नक्शा प्रक्षेपण ठीक है जो 4 समन्वय को परिभाषित करता है जो दृश्य क्षेत्र – h4lc0n

+1

को परिभाषित करता है मुझे लगता है कि मैं जो कह रहा हूं वह यह है कि उन्हें इस तरह जोड़ा नहीं जाना चाहिए। दृश्य क्षेत्र केवल सीमाओं से जुड़ा हुआ है, इससे कोई फर्क नहीं पड़ता कि इसमें क्या प्रक्षेपण है। इससे कोई फर्क नहीं पड़ता कि प्रक्षेपण ईपीएसजी है: 4326 या ईपीएसजी: 9 00 9 13, दृश्य वही है चाहे वह लेट/लोन निर्देशांक या मीटर x/y में है। तो एक को 'mMap.getProjection() 'या' mMap.getVisibleRegion()' एक-दूसरे से स्वतंत्र करने में सक्षम होना चाहिए। – capdragon

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