سؤال

لدي مجموعة من النقاط وأريد مؤامرة على خريطة جوجل مضمنة (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 ()" لا يغير مستوى التكبير / التصغير من الخريطة إذا دعا مباشرة بعد تنوير.

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

هل كانت مفيدة؟

المحلول

يحرر: انظر تعليق مات الماس أدناه.

فهمتك! جرب هذا:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

تعديل لاحتياجاتك.

نصائح أخرى

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

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

كان الحل استخدام مهبس عند وجود العديد من النقاط، و SetCenter + SetZoom عندما كانت هناك نقطة واحدة فقط.

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

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

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

في الأساس، وجدت أن حدث "Zoom_Changed" منع واجهة المستخدم من "تخطي" الذي حدث عندما انتظرت حدث "الخمول".

آمل أن يساعد هذا شخص ما!

لقد قمت بالضبط هذا من خلال إعداد Maxzoom مقدما، ثم إزالة ذلك بعد ذلك. علي سبيل المثال:

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

إذا لم أكن مخطئا، فأنا أفترض أنك تريد أن تكون نقاطك مرئية على الخريطة بأعلى مستوى التكبير الممكن. لقد أنجزت هذا عن طريق تهيئة مستوى تكبير الخريطة ل 16(لست متأكدا مما إذا كان أعلى مستوى التكبير الممكن على V3).

var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 16,
  center: marker_point,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

ثم بعد ذلك فعلت الاشياء حدود:

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

// You can have a loop here of all you marker points
// Begin loop
bounds.extend(marker_point);
// End loop

map.fitBounds(bounds);

النتيجة: النجاح!

أنا أستعمل:

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

سيستخدم هذا أصغر من 24 ومستوى التكبير الضروري وفقا لرمزك، ومع ذلك ربما يغير التكبير على أي حال ولا يهتم بكم

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

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

يحدد مستوى التكبير المناسب في البداية ويسمح للمستخدم بالتكبير والتكبير عبر مستوى التكبير الأولي لأن مستمع الأحداث قد انتهت صلاحيته. على سبيل المثال، إذا فقط google.maps.addListener() كان يسمى، ثم المستخدم سوف أبدا تكون قادرة على التكبير / الماضي مستوى التكبير المعلن (في الحالة، 4). منذ نفذنا 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) 
   }
});

كان له نفس المشكلة، اللازمة لتناسب العديد من العلامات على الخريطة. هذا حل حالتي:

  1. إعلان الحدود
  2. استخدام المخطط المقدم من koderoid (لكل مجموعة علامة bounds.extend(objLatLng))
  3. اكتمال تنفيذ Fitbounds بعد الانتهاء من الخريطة:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });
    

لقد وجدت حلا يقوم بالتحقق قبل الاتصال 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 قليلا للحصول عليها حيث تريد. سوف تختلف بناء على كل من مستوى التكبير والأبعاد من قماش الخرائط.

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

يرجى محاولة هذا:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);

رأيت العديد من الحلول غير الصحيحة أو المعقدة، لذلك قررت نشر العمل، الحل الأنيق.

السبب setZoom() لا يعمل كما تتوقع هو ذلك fitBounds() غير متزامن، لذلك لا يعطي أي ضمان أنه سيقوم على الفور بتحديث التكبير، ولكن مكالمتك setZoom() يعتمد على ذلك.

ما قد تنظر فيه هو وضع minZoom خيار الخريطة قبل الاتصال fitBounds() ثم قم بإلغاء تحديده بعد اكتماله (حتى لا يزال بإمكان المستخدمين التصغير يدويا إذا كانوا يريدون):

var bounds = new google.maps.LatLngBounds();
// ... (extend bounds with all points you want to fit)

// Ensure the map does not get too zoomed out when fitting the bounds.
gmap.setOptions({minZoom: 6});
// Clear the minZoom only after the map fits the bounds (note that
// fitBounds() is asynchronous). The 'idle' event fires when the map
// becomes idle after panning or zooming.
google.maps.event.addListenerOnce(gmap, 'idle', function() {
  gmap.setOptions({minZoom: null});
});

gmap.fitBounds(bounds);

بالإضافة إلى ذلك، إذا كنت ترغب في الحد الأقصى أيضا من التكبير / التصغير، فيمكنك تطبيق نفس الخدعة مع maxZoom خاصية.

انظر مستندات mapoop.

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

إضافة مستمع إلى zoom_changed حدث. هذا لديه فائدة إضافية للتحكم في التحكم في التكبير / التصغير على UI أيضا.

تنفيذ فقط 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);

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

"fitgeomondies" هي وظيفة JSON تمتد كائن خريطة.

"Geometries" هي صفيف جافا سكريبت عام وليس mvcarray ().

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},

هذا العمل بالنسبة لي مع API V3 ولكن مع تحديد التكبير الثابت:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );

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

    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) لتجاوز نطاق التكبير / التصغير ..

يرجى تجربة هذا.

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

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

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

بعد حساب الحدود، يمكنك التحقق من المسافة بين العلوي الأيسر والزاوية اليمنى؛ ثم يمكنك فهم مستوى التكبير بالتكبير عن طريق اختبار المسافة (إذا كان المسافة مستوى التكبير أكثر من ذلك سيكون منخفضا) ثم يمكنك اختيار Whiteter باستخدام طريقة SETBOUND أو SetZoom ..

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

gmap.fitBounds(bounds);

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

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

من مؤشر ترابط UI (استخدم معالج أو onPostExecute طريقة ASYNCTASK).

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

إذا كان "Bounds_Changed" لا يطلق النار بشكل صحيح (في بعض الأحيان لا يبدو أن Google قبول الإحداثيات تماما)، ففكر في استخدام "Center_Changed" بدلا من ذلك.

يتم استدعاء أحداث الأحداث "Center_Changed" في كل مرة يتم استدعاء المستقل ()، على الرغم من أنه يعمل على الفور وليس بالضرورة بعد أن انتقلت الخريطة.

في الحالات العادية، لا يزال "الخمول" هو أفضل مستمع حدث، ولكن هذا قد يساعد بضع أشخاص يركضون إلى مشكلات غريبة مع مكالماتهم المحملة ().

يرى خرائط جوجل Fitbound Callback

للتناغم مع حل آخر - لقد وجدت أن "الاستماع للحصول على الحدث 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.fitBounds(bounds);

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

كل ما فعلته هو:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

ويعمل على V3 API.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top