Splitting Linestrings on dateline with OpenLayers

The problem is that your feature doesn't cross the date line from OpenLayers perspective, so your split line doesn't intersect your feature. Example from your data:

..., -178.475596 -81.673196, 156.248392 -81.611421,...

You go from -178 to 156, and this doesn't cross the date line from the OpenLayers perspective. Instead of splitting on the date line, you should split on your minimum X value.

// Build the splitting line based on the min and max coordinates of the vector to split
var minX = 999999999;
var minY = -20037508.34 // minimum value of the spherical mercator projection
var maxY = 20037508.34  // maximum value of the spherical mercator projection
//Extract the minimum X from the data as bounds seems to be rounded.
for(var i=0; i<satTrack.geometry.components.length; i++) {
    if(satTrack.geometry.components[i].x < minX)
        minX = satTrack.geometry.components[i].x;
}
var pointList = [
    new OpenLayers.Geometry.Point(minX, minY),
    new OpenLayers.Geometry.Point(minX, maxY)
];
var featDateLine = new OpenLayers.Feature.Vector(
    new OpenLayers.Geometry.LineString(pointList)
);

I've built an example here that successfully split your satellite track in 2 features: http://jsfiddle.net/6XJ5A/

Now to use the WKT with multiple line in your update, instead of using a straight line, you must go through the whole dataset and build your split line with all the coordinates that go across the dateline. By building small line inside a multiline, you can split on all the coordinates that should go across the dateline. Here's the updated example: http://jsfiddle.net/Jc274/

And the code:

// Build the splitting line based on the min and max coordinates of the vector to split
var pointList = [];
var lastPoint = satTrack.geometry.components[0];
//Extract the minimum X from the data as bounds seems to be rounded.
for (var i = 1; i < satTrack.geometry.components.length; i++) {
    if (Math.abs(satTrack.geometry.components[i].x - lastPoint.x) > 10000000) {
        pointList.push(satTrack.geometry.components[i]);
    }
    lastPoint = satTrack.geometry.components[i];
}

var lineList = [];
for(var i=0; i<pointList.length; i++) {
    lineList.push(new OpenLayers.Geometry.LineString([
        new OpenLayers.Geometry.Point(pointList[i].x, pointList[i].y-0.00001), 
        new OpenLayers.Geometry.Point(pointList[i].x, pointList[i].y+0.00001)
    ]));
}

var featDateLine = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.MultiLineString(lineList), null, split_style);

This will return you a splitted line on all the points that "cross" the dateline

Note that I also loop through the coordinates to remove the line that goes across the map to connect the 2 coordinates:

for (var i = 0; i < resultsDateLine.length; i++) {
    // Remove the first (or last) point of the line, the one that cross the dateline
    if (Math.abs(resultsDateLine[i].components[0].x - resultsDateLine[i].components[1].x) > 10000000) {
        resultsDateLine[i].removeComponent(resultsDateLine[i].components[0]);
    }
    if (Math.abs(resultsDateLine[i].components[resultsDateLine[i].components.length - 1].x - resultsDateLine[i].components[resultsDateLine[i].components.length - 2].x) > 10000000) {
        resultsDateLine[i].removeComponent(resultsDateLine[i].components[resultsDateLine[i].components.length - 1]);
    }
    features.push(new OpenLayers.Feature.Vector(resultsDateLine[i], null, style_array[i]));
}

Update: I updated the first example to only add the line that were split. I also updated the explanation accordingly. This approach is not bullet proof with the 24h satellite track you provided, but I'm working on it.

Update 2: I updated the second example. By using a multiline to split and looping through the result to remove extra coordinates added by the split, we get a set of features that never go across the dateline.


I found a great solution on @Dane 's github. It's called Arc.js and it's for calculating Great circle routes. Not only that, it will also split the line on the dateline and provide you with two linestrings that meet at the dateline, which OpenLayers can easily map. I hope he comes forward to claim the bounty.

Here are my results:

enter image description here enter image description here