开发者

how to get the real bounds with google maps when fully zoomed out

I have a map th开发者_如何学JAVAat shows location points based on the gbounds of the map. For example, any time the map is moved/zoomed, i find the bounds and query for locations that fall within those bounds. Unfortunately I'm unable to display all my locations when fully zoomed out. Reason being, gmaps reports the min/max long as whatever is at the edge of the map, but if you zoom out enough, you can get a longitudinal range that excludes visible locations.

For instance, if you zoom your map so that you see NorthAmerica twice, on the far left and far right. The min/max long are around: -36.5625 to 170.15625. But this almost completely excludes NorthAmerica which lies in the -180 to -60 range. Obviously this is bothersome as you can actually see the continent NorthAmerica (twice), but when I query my for locations in the range from google maps, NorthAmerica isn't returned.

My code for finding the min/max long is:

bounds = gmap.getBounds();
min_lat = bounds.getSouthWest().lat()
max_lat = bounds.getNorthEast().lat()

Has anyone encountered this and can anyone suggest a workaround? Off the top of my head I can only thing of a hack: to check the zoom level and hardcode the min/max lats to -180/180 if necessary, which is definitely unacceptable.


This isn't the most elegant solution, but I tested it and it does work. Check to see if the current bounds contains the bounds of the full map. Google doesn't actually include the north and south pole, so I had to tweak it to go almost all the way north and south.

bounds = gmap.getBounds();
var fullEarth = new GLatLngBounds(new GLatLng(-85, 180), new GLatLng(85, -180)))
var isFull = bounds.containsBounds(fullEarth);
min_lat = isFull ? -90 : bounds.getSouthWest().lat()
max_lat = isFull ? 90 : bounds.getNorthEast().lat()

min_lng = isFull ? 180 : bounds.getSouthWest().lng()
max_lng = isFull ? -180 : bounds.getNorthEast().lng()


Can not even imagine how this HUGE bug is still there !!! isFullLng and toSpan functions are buggy and you can not rely on them.
My bug workaround for this:

var zoom = map.getZoom();
var bounds = map.getBounds();    
var span = bounds.toSpan();
var isFull = span.lng() > 277 || zoom < 2;


Here is my solution, I only need isFullLng() which was apparently removed from API v3:

isFullLng: function() {
        var scale = Math.pow(2, map.getZoom()),
            bounds = map.getBounds(),
            ne = bounds.getNorthEast(),
            sw = bounds.getSouthWest(),
            lat = (ne.lat() <= 0 && sw.lat() >= 0) || (ne.lat() >= 0 && sw.lat() <= 0) ? 0 : Math.min(Math.abs(ne.lat()), Math.abs(sw.lat())), // closest latitude to equator
            deg1 = new google.maps.LatLng(lat, 0),
            deg2 = new google.maps.LatLng(lat, 1),
            coord1 = map.getProjection().fromLatLngToPoint(deg1),
            coord2 = map.getProjection().fromLatLngToPoint(deg2);
        // distance for one long degree in pixels for this zoom level
        var pixelsPerLonDegree = (coord2.x - coord1.x) * scale;
        // width of map's holder should be <= 360 (deg) * pixelsPerLonDegree if full map is displayed
        var width = $this.width(); // width of map's holder div
        return pixelsPerLonDegree * 360 <= width;

    },
isFullLat: function() {
        var bounds = map.getBounds(),
            ne = bounds.getNorthEast(),
            sw = bounds.getSouthWest(),
            maxLat = 85; // max lat degree
        return ne.lat() >= maxLat && sw.lat() <= -maxLat;
    },

So isFull could then be:

isFullLng() && isFullLat()

Note that in isFullLng() the width of map's placeholder is needed, I'm using jQuery and map is rendered in div referenced by $this, so I only call

$this.width()

You should should change that to apply it to your problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜