具有动态自动定位功能的 Google 地图 V3 工具提示弹出窗口

发布于 2024-12-23 23:00:53 字数 197 浏览 1 评论 0原文

我正在寻找一个可与 Google Maps V3 配合使用的弹出窗口,该弹出窗口支持相对于标记自动定位弹出窗口,以便整个弹出窗口始终在地图视口中可见。我正在尝试破解 InfoBox 库来完成这项工作,但事实证明这是一个很大的麻烦。我还研究了 QTip2,它显示了一些希望,但也有一些缺点,例如具有定位,但必须手动设置。

编辑:解决方案需要不平移地图以显示弹出窗口。

I'm looking for a popup that will work with Google Maps V3 that supports auto-positioning the popup in relation to the marker such that the whole popup window is always visible within the map viewport. I'm trying to hack the InfoBox library to make this work but it's proving to be a big hassle. I've also looked at QTip2 which shows some promise but also has some shortcomings such as having positioning, but it must be set manually.

EDIT: The solution needs to to not pan the map to show the popup window.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2024-12-30 23:00:53

我在 SmartInfoWindow 的快速搜索中找到了 V3 演示库。看起来它就像你想要的那样。这是 Google 代码项目

I found SmartInfoWindow in a quick search at the V3 Demo Gallery. It seems like it does just what you want. Here's the google code project.

野心澎湃 2024-12-30 23:00:53

在 SmartInfoWindow 的帮助下,我能够添加到 InfoBox 中,让它执行我想要的操作。这是一个部分定制的解决方案,因此您可能需要调整定位。您只需获取 InfoBox 每个角的 div 位置,将这些角转换回纬度/经度,然后获取地图边界并查看角是否在边界内。如果不是,那么您可以根据哪些角落不在地图上相应地调整信息框位置。

InfoBox.prototype.maybePanMap = function() {
  // if we go beyond map, pan map
  var map = this.getMap();
  var projection = this.getProjection();
  var bounds = map.getBounds();
  if (!bounds) return;

  // The dimension of the infowindow
  var iwWidth = this.div_.offsetWidth;
  var iwHeight = this.div_.offsetHeight;

  // The offset position of the infowindow
  var iwOffsetX = this.pixelOffset_.width;
  var iwOffsetY = this.pixelOffset_.height;

  var anchorPixel = projection.fromLatLngToDivPixel(this.getPosition());
  var bl = new google.maps.Point(anchorPixel.x + iwOffsetX,
      anchorPixel.y + iwOffsetY);
  var br = new google.maps.Point(anchorPixel.x + iwOffsetX + iwWidth,
      anchorPixel.y + iwOffsetY);
  var tl = new google.maps.Point(anchorPixel.x + iwOffsetX,
      anchorPixel.y + iwOffsetY - iwHeight + 100);
  var tr = new google.maps.Point(anchorPixel.x + iwOffsetX + iwWidth,
      anchorPixel.y + iwOffsetY - iwHeight + 100);

  var sw = projection.fromDivPixelToLatLng(bl);
  var se = projection.fromDivPixelToLatLng(br);
  var nw = projection.fromDivPixelToLatLng(tl);
  var ne = projection.fromDivPixelToLatLng(tr);


  if (!map.getBounds().contains(nw) && !map.getBounds().contains(sw)) {        
    this.div_.style.left = (anchorPixel.x + 10) + 'px';
    if (!map.getBounds().contains(ne)) {
      this.div_.style.top = (anchorPixel.y - 100) + 'px';
    }
  } else if (!map.getBounds().contains(nw) && !map.getBounds().contains(ne)) {
    this.div_.style.top = (anchorPixel.y - 100) + 'px';
    if (!map.getBounds().contains(se)) {
      this.div_.style.left = (anchorPixel.x - iwWidth - 10) + 'px';
    }
  } else if (!map.getBounds().contains(ne) && !map.getBounds().contains(se)) {
    this.div_.style.left = (anchorPixel.x - iwWidth - 10) + 'px';        
    if (!map.getBounds().contains(sw)) {
      this.div_.style.top = (anchorPixel.y - iwHeight - 100) + 'px';
    }        
  }


};

I was able to add on to InfoBox to get it to do what I wanted with a little help from SmartInfoWindow. This is a partially customized solution so you may need to tweak the positioning. You just grab the div position of each corner of the InfoBox, convert those corners back to lat/lng and then grab the maps bounds and see if the corners are within the bounds. If they aren't then you adjust the InfoBox position accordingly depending on which corners are off the map.

InfoBox.prototype.maybePanMap = function() {
  // if we go beyond map, pan map
  var map = this.getMap();
  var projection = this.getProjection();
  var bounds = map.getBounds();
  if (!bounds) return;

  // The dimension of the infowindow
  var iwWidth = this.div_.offsetWidth;
  var iwHeight = this.div_.offsetHeight;

  // The offset position of the infowindow
  var iwOffsetX = this.pixelOffset_.width;
  var iwOffsetY = this.pixelOffset_.height;

  var anchorPixel = projection.fromLatLngToDivPixel(this.getPosition());
  var bl = new google.maps.Point(anchorPixel.x + iwOffsetX,
      anchorPixel.y + iwOffsetY);
  var br = new google.maps.Point(anchorPixel.x + iwOffsetX + iwWidth,
      anchorPixel.y + iwOffsetY);
  var tl = new google.maps.Point(anchorPixel.x + iwOffsetX,
      anchorPixel.y + iwOffsetY - iwHeight + 100);
  var tr = new google.maps.Point(anchorPixel.x + iwOffsetX + iwWidth,
      anchorPixel.y + iwOffsetY - iwHeight + 100);

  var sw = projection.fromDivPixelToLatLng(bl);
  var se = projection.fromDivPixelToLatLng(br);
  var nw = projection.fromDivPixelToLatLng(tl);
  var ne = projection.fromDivPixelToLatLng(tr);


  if (!map.getBounds().contains(nw) && !map.getBounds().contains(sw)) {        
    this.div_.style.left = (anchorPixel.x + 10) + 'px';
    if (!map.getBounds().contains(ne)) {
      this.div_.style.top = (anchorPixel.y - 100) + 'px';
    }
  } else if (!map.getBounds().contains(nw) && !map.getBounds().contains(ne)) {
    this.div_.style.top = (anchorPixel.y - 100) + 'px';
    if (!map.getBounds().contains(se)) {
      this.div_.style.left = (anchorPixel.x - iwWidth - 10) + 'px';
    }
  } else if (!map.getBounds().contains(ne) && !map.getBounds().contains(se)) {
    this.div_.style.left = (anchorPixel.x - iwWidth - 10) + 'px';        
    if (!map.getBounds().contains(sw)) {
      this.div_.style.top = (anchorPixel.y - iwHeight - 100) + 'px';
    }        
  }


};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文