Google maps V3 custom marker images and fitBounds()

后端 未结 2 1490
清酒与你
清酒与你 2021-01-24 10:57

I am trying to get my custom markers to show up on my map after i have used the fitBounds() method to fit the boundaries of the map to the markers themselves.

I have don

相关标签:
2条回答
  • 2021-01-24 11:42

    The cheap answer is to always zoom out one level after fitBounds(). But we can do a bit better.

    I like writing hacks. Here I am making the assumption that the size of your marker will never be larger than 36x57. I tested a while back to find that fitBounds() leaves a margin of around 42 px between the edge and the closest marker (maybe not on mobiles), and I'm also assuming you are not repositioning the marker, that is, it will always be displayed above the given coordinate position. If icons run off to the other sides, adjustments are needed.

    My hack takes advantage of a function that measures the pixel position of a LatLng (using the container version, I read here that the div version is not reliable with bounds changes).

    Since we know the height of the icon, and where the topmost marker is, we can pan the map south a bit if it's determined to be offscreen. In case there's not enough margin below, the only option is to zoom out. My only concern is it will be jerky because it calls for two events: fitBounds and the custom panning/zooming. The only answer then would be to rewrite a custom fitBounds. When I tested manually the events ran smoothly.

    http://jsfiddle.net/sZJjY/

    Click to add cat icons, right-click to trigger the resize/panning.

    Example: place 3-4 kitties, right-click, then purposely place another that goes off the top, right-click again.

      function fitIcons() {
        var left = 180.0;
        var right = -180.0;
        var top = -90.0;
        var bottom = 90.0;
    
        for (var i = 0; i < markers.length; i++) {
          curlat = markers[i].getPosition().lat();
          curlng = markers[i].getPosition().lng();
          if(curlat > top)    { top = curlat; }
          if(curlat < bottom) { bottom = curlat; }
          if(curlng > right)  { right = curlng; }
          if(curlng < left)   { left = curlng; }
        }
    
        var overlay = new google.maps.OverlayView();
        overlay.draw = function() {};
        overlay.setMap(map);
    
        map.fitBounds(new google.maps.LatLngBounds(
          new google.maps.LatLng(bottom, left),
          new google.maps.LatLng(top, right)));
    
        topPixels = overlay.getProjection().fromLatLngToContainerPixel(
                      new google.maps.LatLng(top, right));
    
        bottomPixels = overlay.getProjection().fromLatLngToContainerPixel(
                      new google.maps.LatLng(bottom, left));
    
        topGap = topPixels.y;
        bottomGap = $("#map_canvas").height() - bottomPixels.y;
    
        if(topGap < iconHeight) {
          if(bottomGap > iconHeight) {
            map.panBy(0, topGap);
          }
          else {
            map.setZoom(map.getZoom() - 1);
          }
        }
      }
    
    0 讨论(0)
  • 2021-01-24 11:44

    Since you already have calculated the bounds, you may just need to extend the bounds to add enough buffer area to include the large images. The formula you can use to calculate or extend a bounds this way is called a convex hull; the Computational Geometry Algorithms Library has a section on 2D Convex Hull Algorithms or there is a JavaScript Quickhull Article that also includes a nifty online example near the bottom of the page. Hope this is helpful -

    0 讨论(0)
提交回复
热议问题