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

javascript - add padding to google maps bounds.contains() - Stack Overflow

programmeradmin3浏览0评论

I have a sidebar which shows the names of the markers in the current map view of a google map. The sidebar contents change as the map gets moved:

google.maps.event.addListener(map, 'bounds_changed', function() {
            document.getElementById("list").innerHTML = "";
            var mklen = mkrs.length,
                a = 0,
                bnds = map.getBounds();

            for (a; a < mklen; a++) {
                var themk = mkrs[a];
                if (bnds.contains(themk.getPosition())) {
                    var myli = document.createElement("li");
                    myli.innerHTML = themk.title;
                    document.getElementById("list").appendChild(myli);
                }
            }
        });

That's working OK, but the thing is that the bounds.contains() is very strict - if just the bottom tip of the marker is on the map (ie, you can't see 99% of it) it gets listed on the sidebar. What I'd like is to have just the markers that are completely shown pass that test.

There are a couple of approaches that I can think of and I can't believe that nobody else has come up against this problem, so I'm wondering if there is a preference out of the following:

  1. take the bounds and recalculate them to be smaller than the actual bounds and use those new bounds for the bounds.contains() test
  2. calculate where the edges of the marker icons are (I guess using fromDivPixelToLatLng) then check that both the ne AND sw corners are within the bounds and if so, list the item

Before you ask, I haven't tried either of those - I'm more looking for advice on which would be best or even possible, or if there is another way to do this. Here's a fiddle demonstrating the issue, in case it clarifies

I have a sidebar which shows the names of the markers in the current map view of a google map. The sidebar contents change as the map gets moved:

google.maps.event.addListener(map, 'bounds_changed', function() {
            document.getElementById("list").innerHTML = "";
            var mklen = mkrs.length,
                a = 0,
                bnds = map.getBounds();

            for (a; a < mklen; a++) {
                var themk = mkrs[a];
                if (bnds.contains(themk.getPosition())) {
                    var myli = document.createElement("li");
                    myli.innerHTML = themk.title;
                    document.getElementById("list").appendChild(myli);
                }
            }
        });

That's working OK, but the thing is that the bounds.contains() is very strict - if just the bottom tip of the marker is on the map (ie, you can't see 99% of it) it gets listed on the sidebar. What I'd like is to have just the markers that are completely shown pass that test.

There are a couple of approaches that I can think of and I can't believe that nobody else has come up against this problem, so I'm wondering if there is a preference out of the following:

  1. take the bounds and recalculate them to be smaller than the actual bounds and use those new bounds for the bounds.contains() test
  2. calculate where the edges of the marker icons are (I guess using fromDivPixelToLatLng) then check that both the ne AND sw corners are within the bounds and if so, list the item

Before you ask, I haven't tried either of those - I'm more looking for advice on which would be best or even possible, or if there is another way to do this. Here's a fiddle demonstrating the issue, in case it clarifies

Share Improve this question asked Jan 20, 2016 at 8:14 lucaslucas 1,5051 gold badge13 silver badges23 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 20

In case anybody finds this later, I ended up recalculating the bounds - it seemed to be the approach that involved the least overhead. Here's the function:

function paddedBounds(npad, spad, epad, wpad) {
    var SW = map.getBounds().getSouthWest();
    var NE = map.getBounds().getNorthEast();
    var topRight = map.getProjection().fromLatLngToPoint(NE);
    var bottomLeft = map.getProjection().fromLatLngToPoint(SW);
    var scale = Math.pow(2, map.getZoom());

    var SWtopoint = map.getProjection().fromLatLngToPoint(SW);
    var SWpoint = new google.maps.Point(((SWtopoint.x - bottomLeft.x) * scale) + wpad, ((SWtopoint.y - topRight.y) * scale) - spad);
    var SWworld = new google.maps.Point(SWpoint.x / scale + bottomLeft.x, SWpoint.y / scale + topRight.y);
    var pt1 = map.getProjection().fromPointToLatLng(SWworld);

    var NEtopoint = map.getProjection().fromLatLngToPoint(NE);
    var NEpoint = new google.maps.Point(((NEtopoint.x - bottomLeft.x) * scale) - epad, ((NEtopoint.y - topRight.y) * scale) + npad);
    var NEworld = new google.maps.Point(NEpoint.x / scale + bottomLeft.x, NEpoint.y / scale + topRight.y);
    var pt2 = map.getProjection().fromPointToLatLng(NEworld);

    return new google.maps.LatLngBounds(pt1, pt2);
}

and you call it like this:

var padbnds = paddedBounds(50, 70, 100, 30);

specifying how much padding you want on the north, south, east and west edges of the map respectively

发布评论

评论列表(0)

  1. 暂无评论