repl.it
@gpantic/

OpenLayersSplitRouteOverPacific

ES6

This solution solves a problem in OpenLayers with routes going over Pacific. It splits a route to routes before and after Pacific.

fork
loading
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const route = [
  [0,0],
  [40,10],
  [80,20],
  [120,30],
  [160,40],
  
  [-160,30],
  [-120,20],
  [-80,10],
  [-40,0],
  [-80,-10],
  [-120,-20],
  [-160,-30],
  
  [160,-40],
  [120,-30],
  [80,-20],
  [40,-10]
];

function getSplitPoints(prev, curr) {
  const initialDiff = prev[0] > curr[0] ? prev[0] - curr[0] : curr[0] - prev[0];
  const altCurr = curr[0] < 0 ? curr[0] + 360 : curr[0] - 360;
  const altDiff = prev[0] > altCurr ? prev[0] - altCurr : altCurr - prev[0];
  if (initialDiff > altDiff) {
    const xDiff = altDiff;
    const xEndDiff = 180 - Math.abs(prev[0]);
    const yDiff = Math.abs(Math.abs(curr[1]) - Math.abs(prev[1]));
    const yResDiff = (yDiff * xEndDiff)/xDiff;
    const yRes = prev[1] > curr[1] ? prev[1] - yResDiff : prev[1] + yResDiff;
    return {
      endPoint: prev[0] > curr[0] ? [180, yRes] : [-180, yRes],
      startPoint: prev[0] > curr[0] ? [-180, yRes] : [180, yRes]
    };
  }
  return null;
}

function splitRoute180(route) {
  const newRoutes = [];
  let index = 0;
  let prevPoint;
  route.forEach((point) => {
    if (!newRoutes[index]) {
      newRoutes[index] = [];
    }
    if (!prevPoint) {
      prevPoint = point;
    } else {
      const splitPoints = getSplitPoints(prevPoint, point);
      if (splitPoints) {
        newRoutes[index].push(splitPoints.endPoint);
        index++;
        newRoutes[index] = [];
        newRoutes[index].push(splitPoints.startPoint);
        prevPoint = null;
      } else {
        prevPoint = point;
      }
    }
    newRoutes[index].push(point);
  });
  return newRoutes;
}

console.log(splitRoute180(route));
Babel Compiler v6.4.4 Copyright (c) 2014-2015 Sebastian McKenzie