Google Maps API - (使用OverlayView)一次只打开一个地图标记?

时间:2012-05-17 16:52:01

标签: jquery ajax google-maps google-maps-api-3 google-api

我正在尝试使用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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

标准设计模式是:

  1. 将一个引用放置在范围中较高位置的窗口(而不是现在的每个标记处),并将窗口视为单例。
  2. 当收到标记点击事件时,关闭窗口并清空其内容。
  3. 在窗口中放置适当的新内容,并将其移动到适合当前标记点击的位置。
  4. 显示窗口,如果收到另一个标记点​​击事件,请等待重复这些步骤。
  5. 检查此问题,了解有关将此模式与InfoWindow Have just one InfoWindow open in Google Maps API v3一起使用的详细信息。