Solution 1
As mentioned here. This solution creates three copies of a feature geometry and shifts the X (Longitude) value:
- first geometry has X < -180
- second geometry has normal X > -180 and < 180
- third geometry has X > 180
The code below is a snippet from a class that sublcasses the OpenLayers.Layer.GeoRSS class (particularly the parseData function). We do the X-value shifts while looping through the features that were parsed from the XML document and add them to the GeoRSS layer.features array. Anything below that references this refers to GeoRSS class.
Important Point: my MAP.projection below is 900913. I had to transform each geometry to MAP.displayProjection (4326) and then do the math and transform it back. For some reason OpenLayers wouldn't let me shift X values of 900913 points beyond the dateline (i would like to find out why). Another thing to note is that each feature has to have it's own OpenLayers.Icon instantiated or only the last of the three points with show on the map b/c the ids will be the same.
var doc = ajaxRequest.responseXML;
if (!doc || !doc.documentElement)
doc = OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);
var format = new OpenLayers.Format.GeoRSS({
externalProjection: new OpenLayers.Projection("EPSG:4326"),
internalProjection: this.map.getProjectionObject()
});
var features = format.read(doc)
for (var i=0, len=features.length; i<len; i++) {
var f = features[i];
f.attributes.icon = new OpenLayers.Icon(this.globalCfg.marker);
// maybe do a f.geometry QC here
/*
**
** create multiple features for each georss
**
*/
var addFeatureAddMarker = function( thisRef, ftr ){
thisRef.features.push(feature);
var marker = feature.createMarker();
if (f.attributes.title)
marker.icon.imageDiv.title = f.attributes.title;
marker.icon.imageDiv.style.cursor = 'pointer';
marker.events.register('click', feature, thisRef.markerClick);
thisRef.addMarker(marker);
}
var origGeom = f.geometry.clone();
origGeom.transform(MAP.projection,MAP.displayProjection);
var offset = 360;
// create features where X(LNG) > -180 and < 180 (NORMAL BOUNDS)
var lngLat = f.geometry.getBounds().getCenterLonLat();
var feature = new OpenLayers.Feature(this, lngLat, f.attributes);
addFeatureAddMarker( this, feature);
// create features where X(LNG) < -180
f.attributes.icon = new OpenLayers.Icon(this.globalCfg.marker);
var lessNeg180 = origGeom.clone();
lessNeg180.x = lessNeg180.x + (-offset);
var x = lessNeg180.transform(MAP.displayProjection, MAP.projection);
var lngLat = x.getBounds().getCenterLonLat();
var feature = new OpenLayers.Feature(this, lngLat, f.attributes);
addFeatureAddMarker( this, feature);
// create features where X(LNG) > 180
f.attributes.icon = new OpenLayers.Icon(this.globalCfg.marker);
var greater180 = origGeom.clone();
greater180.x = greater180.x + offset;
var x = greater180.transform(MAP.displayProjection, MAP.projection);
var lngLat = x.getBounds().getCenterLonLat();
var feature = new OpenLayers.Feature(this, lngLat, f.attributes);
addFeatureAddMarker( this, feature);
}
this.events.triggerEvent("loadend");
I hope there are more ways to do this since we are tripling our points