0

我正在尝试使用 OverlayView for Google Maps API 弄清楚如果您已经打开了一个地图标记,并且您尝试打开另一个标记,它会自动关闭打开的标记,因此实际上只有一个标记打开一次,等等。这是我目前已经拥有的js代码:

var GMap = (function() {
  var that = {};
  that.map = null;
  that.center = new google.maps.LatLng(33.7856030000,-84.4090570000);
  that.map_type = google.maps.MapTypeId.ROADMAP;
  that.markers = {};
  that.windows = {};
  that.bounds = new google.maps.LatLngBounds();
  that.use_bounds = false;
  that.watch_click = false;
  that.zoom = 10;
  that.addCityMarker = function(opts) {
    that.markers[opts.id] = that.standardMarker(opts);
    var myLatlng = that.markers[opts.id].getPosition();
    google.maps.event.addListener(that.markers[opts.id], "click", function(e) {
      that.windows[opts.id] = new InfoBox({
        data: opts,
        latlng: myLatlng,
        map: that.map,
        type: 'city'
      });
    });
    google.maps.event.trigger(that.markers[opts.id], "click");
    if(that.use_bounds == true) {
      that.bounds.extend(myLatlng);
    }
  };
  that.addCityMarkers = function(data) {
    for(var i in data) {
      if(data[i]) {
        that.addCityMarker(data[i]);
      }
    }
  };
  that.addCommunityMarker = function(opts) {
    if(!that.markers[opts.data.id]) {
      that.markers[opts.data.id] = that.standardMarker(opts);
      var myLatlng = that.markers[opts.data.id].getPosition();
      google.maps.event.addListener(that.markers[opts.data.id], "click", function(e) {
        that.windows[opts.data.id] = new InfoBox({
          data: opts.data,
          latlng: myLatlng,
          map: that.map,
          type: 'community'
        });
      });
      google.maps.event.trigger(that.markers[opts.data.id], "click");
      if(that.use_bounds == true) {
        that.bounds.extend(myLatlng);
      }
    } else {
      console.log('skipped adding duplicate community window to map');
    }
  };
  that.addCommunityMarkers = function(data) {
    for(var i in data) {
      if(data[i]) {
        GMap.addCommunityMarker(data[i]);
      }
    }
  };
  that.finish = function() {
    if(that.use_bounds == true) {
     that.map.fitBounds(that.bounds); 
    }
  };
  that.standardMarker = function(opts) {
    var icon = new google.maps.MarkerImage(
      '/images/map/trans.png',
      new google.maps.Size(1,1),
      new google.maps.Point(0,0),
      new google.maps.Point(0,0)
    );
    var shadow = new google.maps.MarkerImage(
      '/images/map/trans.png',
      new google.maps.Size(1,1),
      new google.maps.Point(0,0),
      new google.maps.Point(0,0)
    );
    var marker = new google.maps.Marker({
      icon: icon,
      position: new google.maps.LatLng(opts.lat,opts.lng),
      map: that.map,
      shadow: shadow
    });
    return marker;
  }
  that.triggerMarker = function(id) {
    if(that.windows[id]) {
      that.map.setCenter(that.markers[id].getPosition());
      if(!$('#info_window_'+id).hasClass('open')) {
        $('#info_window_'+id+' a.expand').trigger('click'); 
      }
    } else {
      console.log('no marker for: '+id);
    }
  };
  that.resize = function() {
    google.maps.event.trigger(that.map, 'resize');
    if(that.use_bounds == true) {
      that.map.fitBounds(that.bounds);
    } else {
      that.map.setCenter(that.center); 
    }
  };
  that.initialize = function() {
      var latlng = that.center;
    var myOptions = {
      center: latlng,
      navigationControl: true,
      mapTypeControl: false,
      navigationControlOptions: {
        style: google.maps.NavigationControlStyle.LARGE
      },
      mapTypeId: that.map_type,
      panControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM
      },
      scrollwheel: false,
      zoom: that.zoom,
      zoomControlOptions: {
        style: google.maps.ZoomControlStyle.LARGE,
        position: google.maps.ControlPosition.LEFT_BOTTOM
      }
    };
    that.map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  };
  return that;
})();

function InfoBox(opts) {
  google.maps.OverlayView.call(this);
  this.data_ = opts.data;
  this.type_ = opts.type;
  this.latlng_ = opts.latlng;
  this.map_ = opts.map;
  var me = this;
  this.setMap(this.map_);
}

InfoBox.prototype = new google.maps.OverlayView();

InfoBox.prototype.draw = function() {
  // Creates the element if it doesn't exist already.
  if(this.type_ == 'community') {
    this.createElement();
    if (!this.div_) return;

    var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
    if (!pixPosition) return;

    // Now position our DIV based on the DIV coordinates of our bounds
    if(this.div_.hasClass('open')) {
      this.div_.css('left', (pixPosition.x + -36) + "px");
      this.div_.css('top', (pixPosition.y + -158) + "px");
    } else {
      this.div_.css('left', (pixPosition.x + -36) + "px");
      this.div_.css('top', (pixPosition.y + -85) + "px");
    }
    this.div_.css('display', 'block'); 
  } else if(this.type_ == 'city') {
    this.createCityElement();
    if (!this.div_) return;

    var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
    if (!pixPosition) return;

    // Now position our DIV based on the DIV coordinates of our bounds
    this.div_.css('left', (pixPosition.x + -38) + "px");
    this.div_.css('top', (pixPosition.y + -38) + "px");
    this.div_.css('display', 'block'); 
  }
};

InfoBox.prototype.createElement = function() {
  var me = this;
  var panes = this.getPanes();
  var div = this.div_;
  var data = this.data_;
  if (!div) {
    div = this.div_ = $('<div class="map_info_window" id="info_window_'+data.id+'">'
      +'<a href="#" class="expand">Expand</a>'
      +'<div class="info_window_content">'
        +'<div class="thumb"><img src="'+data.image+'" title="'+data.title+'" /></div>'
        +'<div class="info_window_data">'
          +'<p class="title">'+data.title+'</p>'
          +'<p class="desc">'+data.propInfo+'</p>'
          +'<a href="http://'+data.link+'" target="_blank" class="view">View Community</a>'
        +'</div>'
      +'</div>'
    +'</div>');
    $('a.expand, .thumb', div).click(function(e) {
      e.preventDefault();
      var pixPosition = me.getProjection().fromLatLngToDivPixel(me.latlng_);
      div.toggleClass('open');
      if(div.hasClass('open')) {
        div.css('top', (pixPosition.y + -158) + "px");
        div.css('z-index', 20);
        setTimeout(function() {
          $('.info_window_data', div).show('slide', {direction: 'left'}, 300);
        }, 100);
      } else {
        div.css('top', (pixPosition.y + -85) + "px");
        div.css('z-index', 10);
        $('.info_window_data', div).hide();
      }
    });

    div.css('display', 'none');
    $(panes.floatPane).append(div);
  }
}

InfoBox.prototype.createCityElement = function() {
  var me = this;
  var panes = this.getPanes();
  var div = this.div_;
  var data = this.data_;
  if (!div) {
    div = this.div_ = $('<div class="map_city_window">'
      +'<a href="/find/where?query='+data.name+'">'+data.name+'</a>'
      +'<div class="arrow">arrow</div>'
    +'</div>');
    div.css('display', 'none');
    $(panes.floatPane).append(div);
  }
};

我不确定如何将该功能集成到此代码中,但如果有人能给我一些指示,我将不胜感激。我正在使用的地图的一个非常相似的例子是这样的,如果它可以作为参考点:

http://gables.com/find/where?query=Washington%20DC

在此先感谢您的帮助。

4

1 回答 1

0

标准的设计模式是:

  1. 将对窗口的单个引用放置在范围内更高的位置(而不是像现在这样在每个标记处)并将窗口视为 Singleton。
  2. 当收到标记单击事件时,关闭窗口并清空其内容。
  3. 在窗口中放置任何合适的新内容并将其移动到适合当前标记单击的位置。
  4. 显示窗口,然后在收到另一个标记单击事件时等待重复这些步骤。

检查此问题以获取有关将此模式与以下内容一起使用的更多详细信息InfoWindow在 Google Maps API v3 中仅打开一个 InfoWindow

于 2012-05-17T18:33:06.770 回答