Here's my workaround. The attached file is also hosted at:
In the nutshell, the fix detects origin change and dispatches an event called "origin_changed". Using it:
map.setCenter(new google.maps.LatLng(40.75013, -73.987974));
google.maps.event.addListener(map, 'origin_changed', on_origin_changed);
new OriginDetector(map);
function OriginDetector(map) {
this.setMap(map);
this.map = map;
this.reset_();
var self = this;
google.maps.event.addListener(map, 'bounds_changed', function(){ self.detect_() });
google.maps.event.addListener(map, 'zoom_changed', function(){ self.reset_() });
}
OriginDetector.prototype = new google.maps.OverlayView();
OriginDetector.prototype.onAdd = function() { }
OriginDetector.prototype.onRemove = function() { }
OriginDetector.prototype.draw = function() {
this.detected = false;
}
OriginDetector.prototype.reset_ = function(){
this.testpoint = null;
this.pos = null;
this.dispatched = false;
}
OriginDetector.prototype.detect_ = function(){
if (this.detected)
return;
if (!this.testpoint) this.testpoint = this.map.getCenter();
var pos = this.getProjection().fromLatLngToDivPixel(this.testpoint);
if (!this.pos) this.pos = pos;
if (this.pos.x != pos.x || this.pos.y != pos.y){
this.testpoint = this.map.getCenter();
this.pos = this.getProjection().fromLatLngToDivPixel(this.testpoint);
this.detected = true;
google.maps.event.trigger(map, "origin_changed");
}
}
Then, the rest of the hack is to react on the "origin_changed" event as follows: repeat for all custom overlays (markers) and hide them if they are not in current viewport. They will be shown on the next call to draw() that will follow after a split second.