最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Setting a Google Maps viewport to automatically fit pane for locations of (n) markers of various locations - Stack

programmeradmin3浏览0评论

The approach I took thus far has been:

function addMarker( query ) {
    var geocoder = new google.maps.Geocoder();
    var afterGeocode = $.Deferred();

    // Geocode 'query' which is the address of a location.
    geocoder.geocode( 
            { address: query }, 
            function( results, status ){

                    if( status === 'OK' ){
                        afterGeocode.resolve( results ); // Activate deferred.
                    }
            }
    );

    afterGeocode.then( function( results ){
        var mOptions = {
            position: results[0].geometry.location,
            map: map
        }

        // Create and drop in marker.
        var marker = new google.maps.Marker( mOptions );
        marker.setAnimation( google.maps.Animation.DROP );      

        var current_bounds = map.getBounds(); // Get current bounds of map
        // use the extend() function of the latlngbounds object
        // to incorporate the location of the marker
        var new_bounds = current_bounds.extend( results[0].geometry.location );
        map.fitBounds( new_bounds ); // fit the map to those bounds
    }); 
}

The problem I'm running into is that the map inexplicably zooms out by some amount, no matter if the new marker fits within the current viewport or not.

What am I doing wrong?

ADDENDUM

I added logs and an additional variable to capture the map bounds after the transition was made (new_new_bounds)

current_bounds = // Map bounds before anything is done.
    {-112.39575760000002, 33.60691883366427},
    {-112.39295444655761, 33.639099}

new_bounds = // From after the extend
    {-112.39295444655761, 33.60691883366427}, 
    {-112.39575760000002, 33.639099}

new_new_bounds = // From after the fitbounds
    {-112.33942438265382, 33.588697452015374},
    {-112.44928766390382, 33.657309727063996}

The approach I took thus far has been:

function addMarker( query ) {
    var geocoder = new google.maps.Geocoder();
    var afterGeocode = $.Deferred();

    // Geocode 'query' which is the address of a location.
    geocoder.geocode( 
            { address: query }, 
            function( results, status ){

                    if( status === 'OK' ){
                        afterGeocode.resolve( results ); // Activate deferred.
                    }
            }
    );

    afterGeocode.then( function( results ){
        var mOptions = {
            position: results[0].geometry.location,
            map: map
        }

        // Create and drop in marker.
        var marker = new google.maps.Marker( mOptions );
        marker.setAnimation( google.maps.Animation.DROP );      

        var current_bounds = map.getBounds(); // Get current bounds of map
        // use the extend() function of the latlngbounds object
        // to incorporate the location of the marker
        var new_bounds = current_bounds.extend( results[0].geometry.location );
        map.fitBounds( new_bounds ); // fit the map to those bounds
    }); 
}

The problem I'm running into is that the map inexplicably zooms out by some amount, no matter if the new marker fits within the current viewport or not.

What am I doing wrong?

ADDENDUM

I added logs and an additional variable to capture the map bounds after the transition was made (new_new_bounds)

current_bounds = // Map bounds before anything is done.
    {-112.39575760000002, 33.60691883366427},
    {-112.39295444655761, 33.639099}

new_bounds = // From after the extend
    {-112.39295444655761, 33.60691883366427}, 
    {-112.39575760000002, 33.639099}

new_new_bounds = // From after the fitbounds
    {-112.33942438265382, 33.588697452015374},
    {-112.44928766390382, 33.657309727063996}
Share Improve this question edited May 13, 2011 at 21:25 dclowd9901 asked May 13, 2011 at 20:50 dclowd9901dclowd9901 6,8369 gold badges46 silver badges64 bronze badges 3
  • What is new_bounds saying it's bounds are after the extend? – Ryan Olds Commented May 13, 2011 at 21:09
  • It looks like the change in bounds from (x1,y1),(x2,y2) -> (x2,y1),(x1,y2) is causing a problem. I'm not 100%, but that is where I would start. – Ryan Olds Commented May 13, 2011 at 23:43
  • First thing, make sure this isn't a bug by passing current_bounds to fitBounds and seeing if the view moves. – Ryan Olds Commented May 13, 2011 at 23:47
Add a ment  | 

2 Answers 2

Reset to default 11

OK, so after much wrangling, it turns out that the problem was a map's bounds are not the same as a map's bounds after fitBounds(). What happens (I presume), is Google takes the bounds you give it in the fitBounds() method, and then pads them. Every time you send the current bounds to fitBounds(), You're not going to fit bounds(x,y), you're going to fit bounds(x+m,y+m) where m = the arbitrary margin.

That said, the best approach was this:

var current_bounds = map.getBounds();
var marker_pos = marker.getPosition();

if( !current_bounds.contains( marker_pos ) ){

    var new_bounds = current_bounds.extend( marker_pos );
    map.fitBounds( new_bounds );
}

So, the map will only fit bounds if a marker placed falls outside the current map bounds. Hope this helps anyone else who hits this problem.

A possible explanation is that you randomly placed your new marker into the gap of the z-curve. A z-curve recursivley subdivide the map into 4 smaller tiles but that's also the reason why there are gaps between the tiles. A better way would be to use a hilbert curve or a moore curve for map applications. There is a patented search algorithm covering this issue, I think it is called multidimensional range query in quadtrees. You want to look for Nick's hilbert curce quadtree spatial index blog.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论