[javascript] Google Maps API v3: هل يمكنني تعيين الزوم بعد الحواف؟


10 Answers

لقد قمت بحل مشكلة مماثلة في أحد تطبيقاتي. لقد كنت مرتبكًا قليلاً بسبب وصف المشكلة ، ولكن أعتقد أن لديك نفس الهدف الذي كان لدي ...

في تطبيقي ، رغبت في رسم علامة أو أكثر وتأكد من أن الخريطة كانت تعرضها كلها. كانت المشكلة ، إذا كنت تعتمد فقط على طريقة fitBounds ، عندها سيكون الحد الأقصى لمستوى التكبير عند وجود نقطة واحدة - التي لم تكن جيدة.

كان الحل لاستخدام fitBounds عندما كان هناك العديد من النقاط ، و setCenter + setZoom عندما كان هناك نقطة واحدة فقط.

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}
Question

لدي مجموعة من النقاط التي أرغب في رسم خريطة Google المضمنة بها (API v3). أود أن تستوعب الحدود جميع النقاط ما لم يكن مستوى التكبير منخفضًا جدًا (أي ، التصغير كثيرًا). كان منهجي مثل هذا:

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

هذا لا يعمل. السطر الأخير "gmap.setZoom ()" لا يغير مستوى التكبير في الخريطة إذا تم استدعائه مباشرة بعد fitBounds.

هل هناك طريقة للحصول على مستوى التكبير للحدود دون تطبيقه على الخريطة؟ أفكار أخرى لحل هذا؟




أنا أستعمل:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

سيستخدم هذا أقل من 24 ومستوى التكبير المطلوب وفقًا لرمزك ، إلا أنه من المحتمل أن يغيّر التكبير على أية حال ولا يهمك مقدار التصغير.




لقد أصلحت هذا فقط عن طريق وضع maxZoom مقدما ، ثم إزالته بعد ذلك. فمثلا:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });



لقد عثرت على حل يقوم بالتحقق قبل الاتصال بـ fitBounds حتى لا تقوم بالتكبير والتصغير المفاجئ

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

var minLatSpan = 0.001;
if (bounds.toSpan().lat() > minLatSpan) {
    gmap.fitBounds(bounds); 
} else {
    gmap.setCenter(bounds.getCenter());
    gmap.setZoom(16);
}

سيكون عليك اللعب مع متغير minLatSpan قليلاً للحصول عليه في المكان الذي تريده. سيختلف ذلك استنادًا إلى كل من مستوى التكبير وأبعاد لوحة رسم الخرائط.

يمكنك أيضًا استخدام خطوط الطول بدلاً من خط العرض




google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});



أستخدم هذا لضمان عدم تجاوز مستوى الزوم لمستوى معين حتى أتمكن من معرفة صور الأقمار الصناعية.

أضف مستمعًا إلى الحدث zoom_changed . هذا له فائدة إضافية للتحكم في التحكم في التكبير على واجهة المستخدم أيضا.

فقط قم بتنفيذ setZoom إذا كنت بحاجة إلى ، لذلك فإن العبارة if هي الأفضل من Math.max أو Math.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

لمنع التصغير بعيدًا جدًا:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);



للتناغم مع حل آخر - وجدت أن أسلوب "الاستماع لحدث bounds_changed ثم تعيين تقريب جديد" لم يعمل بشكل صحيح بالنسبة لي. أعتقد أنني كنت أتصل أحيانًا بـ fitBounds قبل أن تتم تهيئة الخريطة بشكل كامل ، وكانت عملية التهيئة تسبب حدثًا خاضعًا للحدود يمكنه استخدام المستمع ، قبل أن يغير fitBounds الحدود ومستوى التكبير / التصغير. انتهى الأمر بهذا الرمز ، والذي يبدو أنه يعمل حتى الآن:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});



مثلي ، إذا كنت لا ترغب في اللعب مع المستمعين ، فهذا هو الحل البسيط الذي توصلت إليه: أضف طريقة على الخريطة تعمل بدقة وفقًا لمتطلباتك مثل هذه:

    map.fitLmtdBounds = function(bounds, min, max){
        if(bounds.isEmpty()) return;
        if(typeof min == "undefined") min = 5;
        if(typeof max == "undefined") max = 15;

        var tMin = this.minZoom, tMax = this.maxZoom;
        this.setOptions({minZoom:min, maxZoom:max});
        this.fitBounds(bounds);
        this.setOptions({minZoom:tMin, maxZoom:tMax});
    }

ثم يمكنك استدعاء map.fitLmtdBounds(bounds) بدلاً من map.fitBounds(bounds) لتعيين الحدود تحت نطاق التكبير المحدد ... أو map.fitLmtdBounds(bounds,3,5) لتجاوز نطاق التكبير / التصغير.




أنا لا أحب أن أقترح ذلك ، ولكن إذا كان يجب عليك محاولة - أول مكالمة

gmap.fitBounds(bounds);

ثم قم بإنشاء مؤشر ترابط / AsyncTask جديد ، اجعله ينام لمدة 20-50ms أو نحو ذلك ثم الاتصال

gmap.setZoom( Math.max(6, gmap.getZoom()) );

من مؤشر ترابط واجهة المستخدم (استخدام معالج أو أسلوب onPostExecute لـ AsyncTask).

لا أعرف ما إذا كان يعمل ، مجرد اقتراح. بخلاف ذلك عليك أن تحسب مستوى التكبير من نقاطك بنفسك ، تحقق مما إذا كانت منخفضة للغاية ، قم gmap.setZoom(correctedZoom) ثم اتصل فقط بـ gmap.setZoom(correctedZoom)




يرجى المحاولة.

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

إذا كان هذا مفيدًا لك.

أتمنى لك كل خير




واجهت نفس المشكلة وتمكنت من حلها باستخدام الشفرة التالية. سيتم تشغيل هذا المستمع ( google.maps.addListenerOnce() ) مرة واحدة فقط ، مباشرة بعد تنفيذ map.fitBounds() . لذلك ، ليست هناك حاجة ل

  1. تتبع وإزالة المستمع يدويا ، أو
  2. انتظر حتى تصبح idle .

فهو يحدد مستوى التكبير المناسب في البداية ويسمح للمستخدم بالتكبير والخروج بعد مستوى التكبير الأولي لأن مستمعي الحدث قد انتهت صلاحيته. على سبيل المثال ، إذا تم استدعاء google.maps.addListener() فقط ، فلن يتمكن المستخدم أبدًا من تكبير مستوى التكبير المحدد (في الحالة 4). بما أننا google.maps.addListenerOnce() ، google.maps.addListenerOnce() المستخدم من التكبير إلى أي مستوى يختاره.

map.fitBounds(bounds);

var zoom_level_for_one_marker = 4;

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){
   if (this.getZoom() >= zoom_level_for_one_marker){  
       this.setZoom(zoom_level_for_one_marker) 
   }
});



Related