meridian180.js (2008B)
1 import L from "leaflet"; 2 3 function getSegmentSplitPointLat(latLng1, latLng2, lng) { 4 const deltaLat = latLng2.lat - latLng1.lat; 5 const deltaLng = latLng2.lng - latLng1.lng; 6 return latLng1.lat + deltaLat / deltaLng * (lng - latLng1.lng); 7 } 8 9 function splitLineAt180Meridian(latLngs) { 10 // this function also creates new LatLng object for all elements 11 const wrappedLatLngs = latLngs.map((ll) => ll.wrap()); 12 const newLines = []; 13 if (latLngs.length < 2) { 14 return newLines; 15 } 16 17 let newLine = [wrappedLatLngs[0]]; 18 newLines.push(newLine); 19 for (let i = 1; i < wrappedLatLngs.length; i++) { 20 let latLng = wrappedLatLngs[i]; 21 let prevLatLng = wrappedLatLngs[i - 1]; 22 if (Math.abs(latLng.lng - prevLatLng.lng) <= 180) { 23 newLine.push(latLng); 24 } else { 25 let positiveLng = L.Util.wrapNum(latLng.lng, [0, 360]); 26 let positivePrevLng = L.Util.wrapNum(prevLatLng.lng, [0, 360]); 27 let splitLng = 180 - 0.000001 * Math.sign(latLng.lng); 28 let splitPrevLng = 180 - 0.000001 * Math.sign(prevLatLng.lng); 29 let splitLat = getSegmentSplitPointLat( 30 L.latLng(prevLatLng.lat, positivePrevLng), 31 L.latLng(latLng.lat, positiveLng), 32 splitLng 33 ); 34 let splitPrevLat = getSegmentSplitPointLat( 35 L.latLng(prevLatLng.lat, positivePrevLng), 36 L.latLng(latLng.lat, positiveLng), 37 splitPrevLng 38 ); 39 newLine.push(L.latLng(splitPrevLat, splitPrevLng).wrap()); 40 newLine = [L.latLng(splitLat, splitLng).wrap(), latLng]; 41 newLines.push(newLine); 42 } 43 } 44 return newLines; 45 } 46 47 function splitLinesAt180Meridian(lines) { 48 return (lines || []) 49 .map((segment) => splitLineAt180Meridian(segment)) 50 .reduce((acc, cur) => { 51 acc.push(...cur); 52 return acc; 53 }, []); 54 } 55 56 export {splitLinesAt180Meridian};