Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm looking for advice on how to display vector markers on both sides of the dateline. I'm using a GeoRSS feed.

Currently only one OpenLayer's "globe" worth of data shows at a time. You have to pan east/west of dateline to get that "globe's" data.

I've read about some tricky hacks that might work -- though they'd be expensive to do depending on the size of your dataset. So i'm wondering what other hacks people here have come up with. Please share your ideas.

share|improve this question
add comment

1 Answer

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

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.