@idm-plugin/geo 2.2.5 → 2.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +304 -249
- package/dist/index.umd.cjs +7 -6
- package/dist/lane/src/index.d.ts +10 -0
- package/package.json +1 -1
package/dist/index.umd.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
(function(w,L){typeof exports=="object"&&typeof module<"u"?L(exports,require("@turf/turf"),require("moment"),require("@log4js-node/log4js-api"),require("moment-timezone"),require("tz-lookup"),require("shpjs")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","@log4js-node/log4js-api","moment-timezone","tz-lookup","shpjs"],L):(w=typeof globalThis<"u"?globalThis:w||self,L(w["idm-plugin-rabbitmq"]={},w["@turf/turf"],w.moment,w["@log4js-node/log4js-api"],w["moment-timezone"],w["tz-lookup"],w.shpjs))})(this,function(w,L,b,V,ie,Q,Y){"use strict";function _(M){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(M){for(const t in M)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(M,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>M[t]})}}return e.default=M,Object.freeze(e)}const p=_(L);class d{static guessTimeZoneOffset(e,t){e=d.convertToStdLng(e);const n=Q(t,e),s=b().tz(n).utcOffset();return d.roundPrecision(s/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),n=Math.round((Math.abs(e)-t)*60);return n=n>9?n:`0${n}`,t=t>9?t:`0${t}`,e>0?`+${t}:${n}`:`-${t}:${n}`}static lng2pretty(e,t=6,n="H°M′"){e=d.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,i,r,c,a,l,u;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=d.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,t).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),l=o/3600,n.indexOf("M")!==-1?u=d.roundPrecision(l,t).toString().padStart(3,"0"):u=d.padNumber(l,3,6),Number(r)>=60&&(a=Number(a)+1,r=0),Number(a)>=60&&(u=Number(u)+1,a=0);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(i,t),pretty:h,S:r,M:a,H:u}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let s="N";e<0&&(s="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,i,r,c,a,l,u;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=d.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,t).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),l=o/3600,n.indexOf("M")!==-1?u=d.roundPrecision(l,t).toString().padStart(2,"0"):u=d.padNumber(l,2,6),Number(r)>=60&&(a=Number(a)+1,r=0),Number(a)>=60&&(u=Number(u)+1,a=0);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(i,t),pretty:h,S:r,M:a,H:u}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[i,r,c]=o;if(r=r||0,r=r>60?r/Math.pow(10,String(r).length-2):r,c=c||0,c=c>60?c/Math.pow(10,String(c).length-2):c,i>360&&!r){const a=this.roundPrecision(i/100,0);r=i-a*100,i=a}n=i+r/60+c/3600,s==="W"&&(n=n*-1)}else n=Number(e);return d.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[i,r,c]=o;if(c=c||0,r=r||0,r=r>60?r/Math.pow(10,String(r).length-2):r,c=c>60?c/Math.pow(10,String(c).length-2):c,i>90&&!r){const a=this.roundPrecision(i/100,0);r=i-a*100,i=a}if(n=i+r/60+c/3600,n>90)throw new Error(`latitude out of range: ${e}${s}`);s==="S"&&(n=n*-1)}else n=Number(e);return d.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=d.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:d.str2Lat(e,t)}:{lng:d.str2Lng(e,t)}}static convertToStdLng(e,t=6){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),d.roundPrecision(e,t)}static roundPrecision(e,t=6){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/([0-9]+)-([0-9]+\.[0-9]+)/g,"$1 $2").replace(/°/," ").replace(/(\d+)-(\d?)/g,"$1 $2").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const n=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=e,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${s}E`:o<=-90?e=`${s}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${s}${o>0?"E":"W"}`:e=`${s}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const s=d.roundPrecision(e-Math.trunc(e),n),o=s>=1?Math.trunc(e+1).toString().padStart(t,"0"):Math.trunc(e).toString().padStart(t,"0");return s>=1?o:n>0?`${o}.${Math.trunc(s*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class K{static json2Str(e){const t=e.type?e.type[0].toUpperCase():"A";return`${e.lat}|${e.lng}|${e.positionTime}|${e.sog}|${e.cog}|${e.hdg}|${e.draught}|${t}|${JSON.stringify(e.meteo||{})}|${e.vendor}|${e.deleted}`}static str2Json(e){const[t,n,s,o,i,r,c,a,l,u,h]=e.split("|");return{lat:Number(t),lng:Number(n),positionTime:Number(s),sog:Number(o),cog:Number(i),hdg:Number(r),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:l?JSON.parse(l):void 0,vendor:u,deleted:h==="true"}}static inspectStoppages(e,t=1,n=!0){const s=e.at(0).positionTime<e.at(-1).positionTime;s||e.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let i,r;for(let c=0;c<e.length-1;c++){const a=e[c];if(!(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))){for(let l=c+1;l<e.length;l++){const u=e[l-1],h=e[l];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const f=h.positionTime-u.positionTime;if(S.calculateDistance(h,u,!0,4)/(f/3600)<t)i||(i=a),l===e.length-1&&(r=h,c=l);else{i&&(r=e[l-1],c=l);break}}if((r==null?void 0:r.positionTime)>(i==null?void 0:i.positionTime)&&i){const l={start:{lat:i.lat,lng:i.lng,sog:i.sog,positionTime:i.positionTime,utc:b.unix(i.positionTime).utc().format()},end:{lat:r.lat,lng:r.lng,sog:r.sog,positionTime:r.positionTime,utc:b.unix(r.positionTime).utc().format()},duration:r.positionTime-i.positionTime},u=e.filter(f=>f.positionTime>=l.start.positionTime&&f.positionTime<=l.end.positionTime),h=S.divideAccordingToLng(u);l.distance=S.calculateRouteDistance(h),l.hours=Math.round(l.duration/3600*10)/10,l.avgSog=Math.round(l.distance/l.hours*10)/10,o.push(l)}i=void 0,r=void 0}}return s||e.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(e,t,n){const s=b(t),o=b(n),i=e.filter(l=>l.positionTime>=s.unix()&&l.positionTime<=o.unix());let r=0,c=0;if(i.length>1)for(let l=0;l<i.length-1;l++){const u=i[l],h=i[l+1];r+=S.calculateDistance(u,h,!0,4),c+=Math.abs(h.positionTime-u.positionTime)}r=Math.round(r*100)/100,c=Math.round(c/3600*100)/100;const a=c?Math.round(r/c*100)/100:0;return{distance:r,interval:c,avgSpd:a}}}let z;try{z=V.getLogger("meteo")}catch{}finally{}const H=(()=>{const M=new Uint32Array(256);for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;M[e]=t}return M})();function ee(M){let e=4294967295;for(let t=0;t<M.length;t++)e=H[(e^M[t])&255]^e>>>8;return(e^4294967295)>>>0}function te(M){const e=new TextEncoder,t=[],n=[];let s=0;for(const f of M){const m=e.encode(f.name),g=ee(f.data),T=new Uint8Array(30+m.length),v=new DataView(T.buffer);v.setUint32(0,67324752,!0),v.setUint16(4,20,!0),v.setUint16(8,0,!0),v.setUint32(14,g,!0),v.setUint32(18,f.data.length,!0),v.setUint32(22,f.data.length,!0),v.setUint16(26,m.length,!0),T.set(m,30),t.push({nameBytes:m,data:f.data,crc:g,offset:s}),s+=T.length+f.data.length,n.push(T,f.data)}const o=s,i=[];let r=0;for(const f of t){const m=new Uint8Array(46+f.nameBytes.length),g=new DataView(m.buffer);g.setUint32(0,33639248,!0),g.setUint16(4,20,!0),g.setUint16(6,20,!0),g.setUint16(10,0,!0),g.setUint32(16,f.crc,!0),g.setUint32(20,f.data.length,!0),g.setUint32(24,f.data.length,!0),g.setUint16(28,f.nameBytes.length,!0),g.setUint32(42,f.offset,!0),m.set(f.nameBytes,46),r+=m.length,i.push(m)}const c=new Uint8Array(22),a=new DataView(c.buffer);a.setUint32(0,101010256,!0),a.setUint16(8,t.length,!0),a.setUint16(10,t.length,!0),a.setUint32(12,r,!0),a.setUint32(16,o,!0);const l=n.reduce((f,m)=>f+m.length,0)+r+22,u=new Uint8Array(l);let h=0;for(const f of n)u.set(f,h),h+=f.length;for(const f of i)u.set(f,h),h+=f.length;return u.set(c,h),u}function J(M){let e="",t=M;for(;t>=0;)e=String.fromCharCode(65+t%26)+e,t=Math.floor(t/26)-1;return e}class S{static calculateBearing(e,t,n=!0,s=4){const o=p.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=p.rhumbBearing(o.features[0],o.features[1]):i=p.bearing(o.features[0],o.features[1]),i<0&&(i+=360),d.roundPrecision(i,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=d.convertToStdLng(e.lng,s),t.lng=d.convertToStdLng(t.lng,s);const i=p.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=p.rhumbDistance(i.features[0],i.features[1],{units:o}):r=p.distance(i.features[0],i.features[1],{units:o}),d.roundPrecision(r,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const i of e)for(let r=0;r<i.length-1;r++){const c={lng:i[r][0],lat:i[r][1]};r===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const a={lng:i[r+1][0],lat:i[r+1][1]};s+=this.calculateDistance(c,a,!0,t,n),o=a}return d.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const i=p.point([e.lng,e.lat]);let r;o?r=p.rhumbDestination(i,n,t,{units:s}):r=p.destination(i,n,t,{units:s});const c=r.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,i="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,i);s&&r.push({lng:e.lng,lat:e.lat});let l=0;for(;l<a;)l+=n,l<a&&r.push(this.calculateCoordinate(e,c,l,i,!1));return o&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1,n=!0){if((e==null?void 0:e.length)<2)return[];e=n?this.deduplicateCoordinates(e):e;let s=[];const o=[];let i,r;for(let c=0;c<e.length-1;c++){i=d.convertToStdLng(e[c].lng,8),r=d.convertToStdLng(e[c+1].lng,8),e[c].lat=d.roundPrecision(e[c].lat,8),e[c+1].lat=d.roundPrecision(e[c+1].lat,8),s.push([i,e[c].lat]);const a=i-r;if(Math.abs(a)>180){const l=d.convertToMonotonicLng2([[i,e[c].lat],[r,e[c+1].lat]]);let u,h;t?(u=p.lineString(l),h=p.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(u=p.greatCircle(l[0],l[1]),h=p.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const f=p.lineIntersect(u,h);let m;if(f.features.length){const g=p.getCoord(f.features[0]);m=d.roundPrecision(g[1],8)}else m=e[c].lat;a>0?(s.push([180-1e-6,m]),o.push([...s]),s=[],s.push([-(180-1e-6),m])):(s.push([-(180-1e-6),m]),o.push([...s]),s=[],s.push([180-1e-6,m]))}c===e.length-2&&s.push([r,e[c+1].lat])}return o.push(s),o}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,i)=>(o.findIndex(r=>r[0]===i[0]&&r[1]===i[1])===-1&&o.push(i),o),[]);t.push(s)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)d.roundPrecision(n[s][0],8)===e.lng&&d.roundPrecision(n[s][1],8)===d.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=d.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)d.roundPrecision(t[n].lng,8)===e.lng&&d.roundPrecision(t[n].lat,8)===d.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,i,r;return t.forEach((c,a)=>{for(let l=0;l<c.length-1;l++){const u={lng:c[l][0],lat:c[l][1]},h={lng:c[l+1][0],lat:c[l+1][1]},f=this.calculatePointToLineDistance(e,u,h);n>f&&(n=f,o=l,s=a,i=this.calculateDistance(u,e),r=this.calculateDistance(h,e))}}),i!==0&&r!==0?t[s].splice(o+1,0,[e.lng,e.lat]):i===0?t[s].splice(o,1,[e.lng,e.lat]):r===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);const n=S.convertRouteToCoordinates(t);return n.push(e),S.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=S.convertRouteToCoordinates(t);return n.unshift(e),S.divideAccordingToLng(n)}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(i=>{if(o===2)return;const r=[];for(const c of i){if(d.roundPrecision(t.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([e.lng,e.lat]),o=2;break}o===1?r.push(c):d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&s.push(r)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),i=this.mergeCoordinatesToWaypoints([e,t],o.length?o:s),r=i.findIndex(l=>d.roundPrecision(e.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(l.lat,8)),c=i.findIndex(l=>d.roundPrecision(t.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(l.lat,8));return i.filter((l,u)=>u>=r&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((i,r)=>{for(let c=0;c<i.length-1;c++){const a={lng:i[c][0],lat:i[c][1]},l={lng:i[c+1][0],lat:i[c+1][1]},u=this.calculatePointToLineDistance(e,a,l);n>u&&(n=u,s=c,o=r)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const n=S.convertRouteToCoordinates(t);S.mergeCoordinateToWaypoints(e,n,!0),t=S.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=d.convertToStdLng(e.lng);const i=[];let r=!0;for(let c=s;c<t.length;c++)if(r){const a=[];a.push([e.lng,e.lat]);for(let l=o+1;l<t[c].length;l++)e.lng===t[c][l][0]&&e.lat===t[c][l][1]||a.push(t[c][l]);i.push(a),r=!1}else i.push([...t[c]]);return i}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let i=0;i<t.length-1;i++){const r=t[i],c=t[i+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((l,u)=>u>0);const a=this.calculatePointToLineDistance(e,r,c);n>a&&(n=a,s=i)}e.lng=d.convertToStdLng(e.lng);const o=[e];for(let i=s+1;i<t.length;i++)o.push(t[i]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=d.convertToStdLng(e.lng,8),t={...t},n={...n},t.lng=d.convertToStdLng(t.lng,8),n.lng=d.convertToStdLng(n.lng,8);const o=d.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const i=p.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=p.pointToLineDistance(p.point([e.lng,e.lat]),i,s),c=p.pointToLineDistance(p.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),i,s);return d.roundPrecision(Math.min(r,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const s=e[n],o=e[n+1],i=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(i),o.distanceFromStart=d.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const s of e)this.mergeCoordinateToWaypoints(s,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=d.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,i=0,r=0;if(t.length<2)t.push(e);else{for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},l={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,l);s>=u&&(s=u,o=c,i=this.calculateDistance(a,e,!1,6),r=this.calculateDistance(l,e,!1,6))}i!==0&&r!==0?i<=s&&o===0?t.unshift(e):r<=s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):i===0?n?t.splice(o,1,e):t.splice(o+1,0,e):r===0&&(n?t.splice(o+1,1,e):t.splice(o+1,0,e))}return t.map((c,a)=>{c.lng=d.convertToStdLng(c.lng);const l=t[a+1];if(l&&((c.bearing===null||c.bearing===void 0)&&((c.positionTime||0)>(l.positionTime||0)?c.bearing=this.calculateBearing(l,c,!0):c.bearing=this.calculateBearing(c,l,!0)),c.cog=c.cog||c.bearing,!c.sog&&c.positionTime&&l.positionTime)){const u=this.calculateDistance(c,l,!0),h=Math.abs(l.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(u/h,2)}return c})}static generateRouteAccordingToWaypoints(e,t=!0,n=!0){const s=[];for(let o=1;o<e.length;o++){const i=e[o-1],r=e[o];if(o===1&&s.push(i),r.gcToPrevious){const c=this.interpolateCoordinates(i,r,200,!1,!0,"nauticalmiles");s.push(...c)}else s.push(r)}return this.divideAccordingToLng(s,t,n)}static nearestCoordinateInRoute(e,t){const n=p.point([e.lng,e.lat]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),i=p.lineString(o),r=p.nearestPointOnLine(i,n),c=p.getCoord(r);return{lng:d.roundPrecision(c[0],8),lat:d.roundPrecision(c[1],8)}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],i=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,i)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var h;const o=e.speed||12,i=[];let r=[],c=!1,a=0,l=0,u;if(t&&n.length?(i.push(e),n.forEach((f,m)=>{if(c)r.push(f);else{const g=[];let T;for(let v=0;v<f.length;v++)if(u)g.push(f[v]);else{T={lng:f[v][0],lat:f[v][1]};const x=this.calculateDistance(e,T,!0,8,s);if(a+=x,a<t)l+=x,x&&i.push(T),e=T;else{if(l=t,a===t)u=T,g.push([u.lng,u.lat]);else{const N=a-t,y=this.calculateBearing(T,e);u=this.calculateCoordinate(T,y,N,s),g.push([u.lng,u.lat]),g.push([T.lng,T.lat])}c=!0}}g.length&&r.push(g),m===n.length-1&&!u&&(u=T)}})):(r=n,u={...e}),u)if(i.push(u),u.distanceFromPrevious=Math.round(l*1e4)/1e4,u.hourFromPrevious=Math.round(l/o*1e4)/1e4,((h=r[0])==null?void 0:h.length)>1){const f={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,f)}else u.bearing=0;return{coordinate:u,nextRoute:r,prevRoute:i}}static nearestCoordinateInLine(e,t,n){const s=d.convertToStdLng(e.lng,6),o=p.point([s,e.lat]),i=d.convertToStdLng(t.lng,6),r=d.convertToStdLng(n.lng,6),c=p.lineString([[i,t.lat],[r,n.lat]]),a=p.nearestPointOnLine(c,o),l=p.getCoord(a),u=d.roundPrecision(l[0],6),h=d.roundPrecision(l[1],6);return{lng:u,lat:h,inline:!(u===i&&h===t.lat)&&!(u===r&&h===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(i=>{i.forEach(r=>{const c={lng:d.roundPrecision(r[0],8),lat:d.roundPrecision(r[1],8)};if(!o)n.push(c),o=c;else if(o.bearing===void 0||o.bearing===null)o.bearing=this.calculateBearing(o,c,!0);else{const a=this.calculateDistance(s,c,!0);a&&a>=t&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(e,t,n=1){let s=this.convertRouteToCoordinates(e,n);return s=this.simplifyGCCoordinates(s,t),s}static simplifyGCCoordinates(e,t){t.forEach(s=>{this.mergeCoordinateToWaypoints(s,e,!0)});for(let s=1;s<t.length;s++){const o=t[s-1],i=t[s];if(i.gcToPrevious){const r=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===i.lng&&a.lat===i.lat);for(let a=c-1;a>r;a--)e.splice(a,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],i=e[s];i.gcToPrevious?(o.bearing=this.calculateBearing(o,i,!1),i.distanceFromPrevious=this.calculateDistance(o,i,!1)):(o.bearing=this.calculateBearing(o,i,!0),i.distanceFromPrevious=this.calculateDistance(o,i,!0)),n=d.roundPrecision(n+i.distanceFromPrevious),i.distanceFromStart=n}return e.map(s=>(s.lng=d.convertToStdLng(s.lng),s))}static calculateCenter(e){const t=[];for(const r of e)for(const c of r)t.push(c);const n=p.featureCollection([]),s=d.convertToMonotonicLng2(t);for(const r of s)n.features.push(p.point(r));const i=p.center(n).geometry.coordinates;return{lng:d.convertToStdLng(i[0],8),lat:d.roundPrecision(i[1],8)}}static calculateCenter2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateCenter(t)}static calculateBBox(e){const t=[];for(const o of e)for(const i of o)t.push(i);const n=d.convertToMonotonicLng2(t),s=p.lineString(n);return p.bbox(s)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}static simplifyCoordinates(e,t=1,n=180){const s=[];for(let o=1;o<e.length;o++){const i=e[o-1],r=e[o],c=e[o+1];let a=!1,l=!1;if((i.velocity||i.suspend||i.important||i.pilot||o===1)&&(a=!0,s.push(i)),r.gcToPrevious&&(a||(a=!0,s.push(i)),l=!0,s.push(r),o++),c){const u=S.calculateDistance(i,r,!0),h=S.calculateDistance(r,c,!0),f=S.calculateDistance(i,c,!0),m=(Math.pow(u,2)+Math.pow(h,2)-Math.pow(f,2))/(2*u*h);Math.round(Math.acos(m)*180/Math.PI)<n&&f>t&&!l&&(s.push(r),o++)}if(o>=e.length-1){const u=e.at(-1);u&&s.push(u)}}return s}static nearestTSPointInWaypoints(e,t,n){const s=b.unix(e),o=n.filter(i=>s.clone().subtract(t,"hour").unix()<=(i.positionTime||0)&&s.clone().add(t,"h").unix()>=(i.positionTime||0));return o.sort((i,r)=>(i.positionTime||0)-(r.positionTime||0)),o.at(-1)}static deadReckoning(e,t){var o,i,r,c;e>1e12&&(e=Math.round(e/1e3));const n=b.unix(e);let s=t.find(a=>a.positionTime===n.unix());if(!s){const a=(i=(o=t.filter(u=>(u==null?void 0:u.positionTime)<n.unix()))==null?void 0:o.sort((u,h)=>(u.positionTime||0)-(h.positionTime||0)))==null?void 0:i.at(-1),l=(c=(r=t.filter(u=>(u==null?void 0:u.positionTime)>n.unix()))==null?void 0:r.sort((u,h)=>(u.positionTime||0)-(h.positionTime||0)))==null?void 0:c.at(0);if(a&&l){const u=S.calculateBearing(a,l,!0),h=S.calculateDistance(a,l),f=(n.unix()-a.positionTime)/(l.positionTime-a.positionTime);s=S.calculateCoordinate(a,u,h*f),s.positionTime=n.unix(),s.utc=n.utc().format(),s.cog=u,s.sog=Math.round(h/((l.positionTime-a.positionTime)/3600)*100)/100}else s=a||l,s&&(s.utc=b.unix(s==null?void 0:s.positionTime).utc().format())}return s}static deadReckoningTime(e,t){t=JSON.parse(JSON.stringify(t)),t.sort((a,l)=>(a.positionTime||0)-(l.positionTime||0));let n=Number.MAX_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER;for(let a=0;a<t.length-1;a++){const l=t[a],u=t[a+1],h=S.calculatePointToLineDistance(e,l,u);h<n&&(n=h,s=a)}const o=t[s],i=t[s+1],r=S.calculateDistance(o,e),c=S.calculateDistance(i,e);if(r===0)e=o;else if(c===0)e=i;else{const a=o.positionTime||0,l=i.positionTime||0,u=S.calculateDistance(o,i);e.positionTime=Math.round(a+(l-a)*(r/u))}return e.utc=e.positionTime?b.unix(e.positionTime).utc().format():void 0,e.positionTime?e:void 0}static reverseRoute(e){const t=[];for(const n of e)t.push(n.reverse());return t}static reverseCoordinates(e){return e.reverse()}static xmlEscape(e){return e==null?"":String(e).trim().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static waypoints2RTZ(e,t){const s=[];return s.push('<?xml version="1.0" encoding="UTF-8"?>'),s.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),s.push(` <routeInfo routeName="${S.xmlEscape(e)}"></routeInfo>`),s.push(...S.toRTZWaypoints(t,6)),s.push("</route>"),s.join(`
|
|
2
|
-
`)}static waypoints2RTZ10(e,t,n=!0){const o=[];return o.push('<?xml version="1.0" encoding="UTF-8"?>'),o.push('<route xmlns="http://www.cirm.org/RTZ/1/0" version="1.0">'),o.push(` <routeInfo routeName="${
|
|
3
|
-
`)}static toRTZWaypoints(e,t=6,n=!0){const s=[];s.push(" <waypoints>");for(let o=0;o<e.length;o++){const
|
|
4
|
-
`)}static
|
|
5
|
-
`)||t.
|
|
6
|
-
`)}static coordinatesSummary(e,t=3){if(e.length>1){const n=e[0],s=e[e.length-1],o=(n==null?void 0:n.positionTime)<(s==null?void 0:s.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(s==null?void 0:s.positionTime),i=(n==null?void 0:n.positionTime)>(s==null?void 0:s.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(s==null?void 0:s.positionTime),r=Math.round(i.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(e,!0,!0),a=this.calculateRouteDistance(c),u=K.inspectStoppages(e,t).reduce((f,m)=>(f.duration+=m.duration,f.distance+=m.distance,f),{hours:0,distance:0,spd:0,duration:0});u.hours=Math.round(u.duration/3600*100)/100,u.distance=Math.round(u.distance*100)/100,u.spd=u.hours?Math.round(u.distance/u.hours*100)/100:0;const h=r?Math.round((a-u.distance)/(r-u.hours)*100)/100:0;return{begin:o.utc().format(),end:i.utc().format(),distance:Math.round((a-u.distance)*100)/100,hours:Math.round((r-u.hours)*100)/100,avgSpeed:h,stoppage:u}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(e,t){var l,u,h;if(!((u=(l=t==null?void 0:t.sample)==null?void 0:l.hours)!=null&&u.length))return{routes:[],hour:void 0};const n=t.sample.hours.at(0),s=b.utc(e),o=b.utc(t.eta),i=s.isAfter(o)?o:s;let r=t.sample.all.find(f=>f.eta===i.format());if(!r){const f=t.sample.all.filter(C=>b.utc(C.eta).isBefore(i)).at(-1),m=this.calculateSubRoute(f,t.route);r=(h=this.calculateNextCoordinateAlongRoute(f,f.speed*i.diff(b(f.etd),"hours",!0),m))==null?void 0:h.coordinate;const{cFactor:g,cog:T,wxFactor:v,meteo:x}=f,N=Math.round(r.distanceFromPrevious*1e4)/1e4,y=Math.round((N+f.distanceFromStart)*1e4)/1e4;r={...r,cFactor:g,cog:T,speed:f.speed,wxFactor:v,distanceFromStart:y,distanceFromPrevious:N,meteo:x,eta:i.format(),etd:i.format()}}r.distanceToGo=Math.round((t.distance-r.distanceFromStart)*100)/100,r.timeToGo=Math.round(o.diff(r.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,r,t.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:r}}static pickUTCSampleFromRoute(e,t,n){var f;const s=this.calculateSubRoute(t,n),o=this.calculateRouteDistance(s),i=o/t.speed,r=b.utc(e),c=b(t.etd),a=(f=this.calculateNextCoordinateAlongRoute(t,t.speed*r.diff(b(t.etd),"hours",!0),s))==null?void 0:f.coordinate;a.speed=t.speed;const l=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(l.diff(r,"second"))<2?r.format():l.format(),a.etd=a.eta,a.distanceFromStart=Math.round(a.distanceFromPrevious*100)/100,a.distanceToGo=Math.round((o-a.distanceFromStart)*100)/100,a.timeToGo=Math.round(c.clone().add(i,"hour").diff(b(a.etd),"hour")*100)/100;const u=this.calculateRangeWaypoints(t,a,n);return{routes:this.generateRouteAccordingToWaypoints(u),hour:a}}static includedAngle(e,t){z==null||z.debug("calculate bearing via: %j",{bearing:e,degree:t});let n=Math.abs(e%360-(t%360||0));return n=n>180?360-n:n,n}}let $;try{$=V.getLogger("vessel")}catch{}finally{}class ne{static convert2Geojson(e){var n,s,o;const t=p.featureCollection([]);for(const i of e){const r=(n=i.history)==null?void 0:n[0];if(i.forecasts){r&&r.wind&&(r.wind.kts=r.kts);for(const c of i.forecasts){let a;const l=[],u=[],h=b(c.date).utc(),f=`${i.name}-${c.model}`;for(const g in c==null?void 0:c.hours){const T=c.hours[g];a=a||T;const v=h.clone().add(Number(g),"hour"),x=p.point([T.lng,T.lat],{model:c.model,name:i.name,nameCn:i.nameCn,date:v.format(),hour:Number(g),format:v.format("MMM-DD/HHmm[Z]"),pressure:T.pressure>1e4?d.roundPrecision(T.pressure/100,0):d.roundPrecision(T.pressure,0),gusts:T.gusts,wind:T.wind||{},movement:T.movement,category:f,type:"forecast"});u.push(x),l.push(x.geometry.coordinates)}const m={kts:void 0,deg:void 0};if(r){const g=b(r.updated).utc();if(a){const v=S.calculateDistance(r,a),x=b(a.utc||a.updated).diff(g,"h",!0);m.kts=Math.round(v/x*100)/100,m.deg=S.calculateBearing(r,a,!0,0)}const T=p.point([r.lng,r.lat],{model:c.model,name:i.name,nameCn:i.nameCn,date:g.format(),hour:0,format:g.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?d.roundPrecision((r==null?void 0:r.pressure)/100,0):d.roundPrecision(r.pressure,0),wind:r.wind,movement:m,category:f,type:"forecast",important:!0});u.unshift(T),l.unshift(T.geometry.coordinates)}if(t.features.push(...u),(l==null?void 0:l.length)>1){const g=p.lineString(d.convertToMonotonicLng2(l),{date:(r==null?void 0:r.updated)||(h==null?void 0:h.format()),id:i.id||i.name,model:c.model,name:i.name,category:f,type:"forecast",movement:m});t.features.push(g)}}}if(t.features.sort((c,a)=>c.properties.type==="forecast"&&a.properties.type==="forecast"&&c.geometry.type==="Point"&&a.geometry.type==="Point"?b(c.properties.date).valueOf()-b(a.properties.date).valueOf():0),(s=i.history)!=null&&s.length){const c=[],a=b(r==null?void 0:r.updated).utc(),l=b((o=i.history)==null?void 0:o.at(-1).updated).utc(),u=a.diff(l,"h")%24>2?24:12;for(const h of i.history){const f=b(h.updated).utc(),m=f.isSameOrBefore(a)||f.isSame(l);m&&a.add(-u,"h");const g=p.point([h.lng,h.lat],{name:i.name,nameCn:i.nameCn,date:f.format(),format:f.format("MMM-DD/HHmm[Z]"),pressure:h.pressure>1e4?d.roundPrecision(h.pressure/100,0):d.roundPrecision(h.pressure,0),kts:h.kts,level:h.type,type:"history",category:`${i.name}-history`,wind:h.wind,movement:h.movement,important:m});t.features.push(g),c.push(g.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const h=p.lineString(d.convertToMonotonicLng2(c),{name:i.name,type:"history",updated:r==null?void 0:r.updated,pressure:(r==null?void 0:r.pressure)>1e4?d.roundPrecision((r==null?void 0:r.pressure)/100,0):d.roundPrecision(r==null?void 0:r.pressure,0),kts:r==null?void 0:r.kts,level:r==null?void 0:r.type});t.features.push(h)}}}return t}static interpolate(e,t=3){var o,i,r,c;const n=(o=e==null?void 0:e.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),s=[];for(const a of n){const l=a.properties.name,u=a.properties.model,h=a.properties.showCircle,f=a.properties.disabled,m=b(a.properties.date).utc();let g=t*60;const T=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(N=>N.geometry.type==="Point"&&N.properties.type==="forecast"&&N.properties.category===`${l}-${u}`);let v,x=m.clone().add(g,"minute").set({minute:0,second:0,millisecond:0});for(;v=this.pickIndex(T,x),v<=T.length-1;){if(v>0){const N=T[v],y=v===0?void 0:T[v-1],C=(g/60-((r=y==null?void 0:y.properties)==null?void 0:r.hour))/(N.properties.hour-((c=y==null?void 0:y.properties)==null?void 0:c.hour)),k=this.computeNumber(y==null?void 0:y.geometry.coordinates[0],N.geometry.coordinates[0],C),Z=this.computeNumber(y==null?void 0:y.geometry.coordinates[1],N.geometry.coordinates[1],C),E=p.point([k,Z],{name:l,model:u,category:N==null?void 0:N.properties.category,date:x.format(),format:x.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(y==null?void 0:y.properties.gusts,N.properties.gusts,C),hour:this.computeNumber(y==null?void 0:y.properties.hour,N.properties.hour,C),movement:this.computeNumber(y==null?void 0:y.properties.movement,N.properties.movement,C),pressure:this.computeNumber(y==null?void 0:y.properties.pressure,N.properties.pressure,C),wind:this.computeNumber(y==null?void 0:y.properties.wind,N.properties.wind,C),type:"forecast",disabled:f,showCircle:h});s.push(E)}g+=t*60,x=m.clone().add(g,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(e,t){const{t1:n,t2:s,hr:o,hours:i}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:s,hr:o,hours:i}}static diversionPassageAt(e,t,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&i){if(!s.debug){const m=S.calculateDistance(e,o),g=S.calculateDistance(e,i);if(m>2*n&&g>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,m,g,{from:e,t1:o,t2:i,hr:r}),{}}const a=S.calculateBearing(e,o),l=S.calculateBearing(o,i),u=Math.abs(a-l);let h=0;u<180?h=u+90:u>=180&&(h=u-90);const f=S.calculateCoordinate(o,h,n);return $==null||$.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:i,radius:n,bearing1:a,bearing2:l,right:f}),{at:f,t1:o,t2:i,hr:Number(r),hours:c}}return{}}static driftPassageAt(e,t,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&i){if(!s.debug){const f=S.calculateDistance(e,o),m=S.calculateDistance(e,i);if(f>2*n&&m>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,f,m,{from:e,t1:o,t2:i,hr:r}),{}}const a=S.calculateBearing(e,o),l=S.calculateBearing(o,i),u=S.calculateDistance(e,o);return{at:S.calculateCoordinate(o,a-l+180,n<u?n:u),t1:o,t2:i,hr:Number(r),hours:c}}else return $==null||$.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:i,hr:r}),{}}static tropicalCenterTwin(e,t=24,n={}){var l,u,h,f,m;let s={};(l=e.forecasts)==null||l.forEach(g=>{s={...g.hours,...s}});const o=((u=e==null?void 0:e.history)==null?void 0:u[0])||(s==null?void 0:s[(h=Object.keys(s))==null?void 0:h[0]]);$==null||$.info("[%s] the first tropical center: %j",n.requestId,o);let i=(f=Object.keys(s||{}).filter(g=>Number(g)<=(t<0?24:t)))==null?void 0:f.at(-1);i||(i=(m=Object.keys(s||{}).filter(g=>Number(g)<=(t<0?24:2*t)))==null?void 0:m.at(-1));const r=s==null?void 0:s[i||-1];$==null||$.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,i);const c=Object.keys(s||{}).filter(g=>Number(g)<=Number(i)),a={0:o};for(const g of c)a[g]=s[g];return{t1:o,t2:r,hr:Number(i),hours:a}}static pickIndex(e,t){let n=0;for(const s of e){if(b(s.properties.date).isAfter(t))return n===0?-1:n;n++}return n}static computeNumber(e,t,n){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const s={};for(const o in e)s[o]=this.computeNumber(e[o],t[o],n);return s}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}typeof globalThis<"u"&&typeof globalThis.Buffer>"u"&&(globalThis.Buffer={isBuffer(M){return M instanceof Uint8Array},from(M,e){if(typeof M=="string")return new TextEncoder().encode(M);if(M instanceof ArrayBuffer)return new Uint8Array(M);if(Array.isArray(M))return new Uint8Array(M);throw new TypeError("Buffer.from: unsupported source type")}});let D;try{D=V.getLogger("meteo")}catch{}finally{}function se(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:M}=require("jsdom"),{DOMParser:e}=new M("").window;return new e}class A{static toArrayBuffer(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}static drawCircle(e,t,n,s={}){const o=(s==null?void 0:s.steps)??64,i=(s==null?void 0:s.units)??"nauticalmiles",r=(s==null?void 0:s.properties)??{},c=p.point([e,t]),a=p.destination(c,n,90,{units:i}),l=b.utc();r.id=(s==null?void 0:s.id)||l.valueOf().toString();const u="circle";return r.name=(s==null?void 0:s.name)||`${u}_${l.format()}`,r.radius=n,r.center=[e,t],r.end=a.geometry.coordinates.map(h=>d.roundPrecision(h,9)),r.units=i,r.steps=o,r.shape="circle",D.info("[%s] draw circle with %j",s==null?void 0:s.requestId,r),p.circle(c,n,{steps:o,units:i,properties:r})}static drawRect(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=b.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const i="rect";s.name=(n==null?void 0:n.name)||`${i}_${o.format()}`,s.start=e.map(l=>d.roundPrecision(l,9)),s.end=t.map(l=>d.roundPrecision(l,9)),s.shape="rect",D.info("[%s] draw rect with %j",n==null?void 0:n.requestId,s);const[r,c]=d.convertToMonotonicLng2([e,t]),a=[Math.min(r[0],c[0]),Math.min(r[1],c[1]),Math.max(r[0],c[0]),Math.max(r[1],c[1])];return p.bboxPolygon(a,{properties:s})}static drawLine(e,t={}){const n=(t==null?void 0:t.properties)??{},s=b.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="line";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.shape="line",D.info("[%s] draw line with %j",t==null?void 0:t.requestId,n);const i=d.convertToMonotonicLng2(e);return p.lineString(i,n)}static drawPolygon(e,t={}){const n=(t==null?void 0:t.properties)??{},s=b.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="polygon";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.coordinates=e.map(r=>r.map(c=>d.roundPrecision(c,9))),n.shape="polygon",D.info("[%s] draw polygon with %j",t==null?void 0:t.requestId,n);const i=d.convertToMonotonicLng2(e);return p.polygon([i],n)}static drawPoint(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=b.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const i="point";return s.name=(n==null?void 0:n.name)||`${i}_${o.format()}`,s.shape="point",D.info("[%s] draw point with %j",n==null?void 0:n.requestId,s),p.point([t,e],s)}static parseCircle(e,t={}){var s,o;D.info("[%s] parse circle with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="circle"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const r=n==null?void 0:n.id,c=((s=n==null?void 0:n.center)==null?void 0:s.length)==2?p.point(n.center):p.centroid(e);let a="center";c.properties={id:`${a}_${r}`,parentId:r,name:a};const l=(n==null?void 0:n.units)||"nauticalmiles";let u=n==null?void 0:n.radius;if(!u){const m=p.polygonToLine(e);u=p.pointToLineDistance(c,m,{units:l})}a="end";const h=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?p.point(n.end):p.destination(c,u,90,{units:l});h.properties={id:`${a}_${r}`,parentId:r,name:a,radius:u,units:l};const f=p.lineString([c.geometry.coordinates,h.geometry.coordinates]);return a="edge",f.properties={id:`${a}_${r}`,parentId:r,name:a,radius:u,units:l},p.featureCollection([c,h,f,e])}else return D.warn("[%s] not a orm-std circle, just return the original feature",t==null?void 0:t.requestId),p.featureCollection([e])}static parseRect(e,t={}){D.info("[%s] parse rect with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="rect"){const s=b.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,l)=>{const u=p.point(i[l]);return u.properties={id:`${a}_${o}`,parentId:o,name:a},u});return p.featureCollection([...c,e])}else return D.warn("[%s] not a orm-std rect, just return the original feature",t==null?void 0:t.requestId),p.featureCollection([e])}static parseLine(e,t={}){D.info("[%s] parse line with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="line"){const s=b.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates.map((c,a)=>{const l=`point_${a}`,u=p.point(c);return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return p.featureCollection([...r,e])}else return D.warn("[%s] not a orm-std line, just return the original feature",t==null?void 0:t.requestId),p.featureCollection([e])}static parsePolygon(e,t={}){D.info("[%s] parse polygon with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="polygon"){const s=b.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates[0].map((c,a)=>{const l=p.point(c),u=`corner_${a}`;return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return p.featureCollection([...r,e])}else return D.warn("[%s] not a orm-std polygon, just return the original feature",t==null?void 0:t.requestId),p.featureCollection([e])}static _inflateRawSync(e){var t;if(typeof process<"u"&&((t=process.versions)!=null&&t.node)){const n=require("zlib");return new Uint8Array(n.inflateRawSync(Buffer.from(e)))}throw new Error("Sync inflate is not supported in browser; use the async convertKMZ2GeoJSONAsync / convertZIP2GeoJSONAsync instead")}static async _parseZipEntries(e){var h;const t=new Uint8Array(e),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),s=new DataView(n),o=new Uint8Array(n),i=new Map;let r=-1;for(let f=n.byteLength-22;f>=0;f--)if(s.getUint32(f,!0)===101010256){r=f;break}if(r<0)throw new Error("Invalid ZIP file: EOCD not found");s.getUint16(r+8,!0);const c=s.getUint32(r+12,!0),a=s.getUint32(r+16,!0);let l=a;const u=a+c;for(;l<u;){if(s.getUint32(l,!0)!==33639248)throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);const m=s.getUint16(l+10,!0),g=s.getUint32(l+20,!0),T=s.getUint16(l+28,!0),v=s.getUint16(l+30,!0),x=s.getUint16(l+32,!0),N=s.getUint32(l+42,!0),y=o.slice(l+46,l+46+T),C=new TextDecoder().decode(y),k=s.getUint16(N+26,!0),Z=s.getUint16(N+28,!0),E=N+30+k+Z,X=o.slice(E,E+g);if(m===0)i.set(C,X);else if(m===8){if(typeof DecompressionStream<"u"){const F=new DecompressionStream("deflate-raw"),P=F.writable.getWriter(),I=F.readable.getReader();P.write(X),P.close();const B=[];let j=0;for(;;){const{done:O,value:R}=await I.read();if(O)break;B.push(R),j+=R.length}const G=new Uint8Array(j);let U=0;for(const O of B)G.set(O,U),U+=O.length;i.set(C,G)}else if(typeof process<"u"&&((h=process.versions)!=null&&h.node))try{i.set(C,A._inflateRawSync(X))}catch{}}l+=46+T+v+x}return i}static async convertKML2GeoJSON(e,t={}){var r,c;D.info("[%s] convert kml to geojson",t==null?void 0:t.requestId);const s=se().parseFromString(e,"application/xml"),o=Array.from(s.querySelectorAll("Placemark")),i=[];for(const a of o){const l={},u=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const y of u){const C=y.getAttribute("name"),k=(c=(r=y.querySelector("value"))==null?void 0:r.textContent)==null?void 0:c.trim();C&&k!==void 0&&k!==null&&(l[C]=k)}const h=b.utc(),f=Object.keys(l).find(y=>y.toLowerCase().indexOf("name")!==-1),m=f?l[f]:void 0,g=`${h.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,T=y=>y.trim().split(/[\s\n]+/).filter(C=>C.length>0).map(C=>{const k=C.split(",").map(Number);return[k[0],k[1]]}),v=a.querySelector("LineString > coordinates");if(v){const y=T(v.textContent||"");if(y.length>=2){const C=p.lineString(y,{...l,shape:"line",id:g,name:m});i.push(C)}continue}const x=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(x){const y=T(x.textContent||"");if(y.length>=4){const C=y[0][0]===y[y.length-1][0]&&y[0][1]===y[y.length-1][1]?y:[...y,y[0]],k=p.polygon([C],{...l,shape:"polygon",id:g,name:m});i.push(k)}continue}const N=a.querySelector("Point > coordinates");if(N){const y=T(N.textContent||"");if(y.length>=1){const C=p.point(y[0],{...l,shape:"point",id:g,name:m});i.push(C)}continue}}return p.featureCollection(i)}static async convertKMZ2GeoJSON(e,t={}){var i;D.info("[%s] convert kmz to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=A.toArrayBuffer(e));const n=await A._parseZipEntries(e),s=n.get("doc.kml")??((i=[...n.entries()].find(([r])=>r.toLowerCase().endsWith(".kml")))==null?void 0:i[1]);if(!s)return D.warn("[%s] no .kml file found in kmz",t==null?void 0:t.requestId),p.featureCollection([]);const o=new TextDecoder().decode(s);return A.convertKML2GeoJSON(o,t)}static async convertZIP2GeoJSON(e,t={}){D.info("[%s] convert zip to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=A.toArrayBuffer(e));const n=await A._parseZipEntries(e),s=[];for(const[o,i]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const r=new TextDecoder().decode(i),c=await A.convertKML2GeoJSON(r,t);s.push(...c.features)}return s.length===0?(D.warn("[%s] no .kml files found in zip",t==null?void 0:t.requestId),this.convertSHP2GeoJSON(e,t)):p.featureCollection(s)}static async convertSHP2GeoJSON(e,t={}){D.info("[%s] convert shp zip to geojson",t==null?void 0:t.requestId);try{typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=A.toArrayBuffer(e));const n=await Y(e);if(Array.isArray(n)){const s=n.flatMap(c=>c.features||[]),o=b.utc(),i=(t==null?void 0:t.id)||o.valueOf().toString(),r={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return s.forEach((c,a)=>{var m;const l=((m=c.geometry)==null?void 0:m.type)||"",u=r[l]||l.toLowerCase();c.properties=c.properties||{},c.properties.shape=u,c.properties.parentId=i,c.properties.id=`${i}_${a}`;const h=Object.keys(c.properties).find(g=>g.toLowerCase().indexOf("name")!==-1),f=h?c.properties[h]:void 0;c.properties.name=f||`${u}_${o.format()}_${a}`}),p.featureCollection(s)}return n}catch(n){return D.warn("[%s] failed to convert shp zip: %s",t==null?void 0:t.requestId,n),p.featureCollection([])}}}w.AisHelper=K,w.GeoJsonHelper=A,w.LaneHelper=S,w.LngLatHelper=d,w.TropicalHelper=ne,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(I,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("@turf/turf"),require("moment"),require("@log4js-node/log4js-api"),require("moment-timezone"),require("tz-lookup"),require("shpjs")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","@log4js-node/log4js-api","moment-timezone","tz-lookup","shpjs"],Z):(I=typeof globalThis<"u"?globalThis:I||self,Z(I["idm-plugin-rabbitmq"]={},I["@turf/turf"],I.moment,I["@log4js-node/log4js-api"],I["moment-timezone"],I["tz-lookup"],I.shpjs))})(this,function(I,Z,x,J,re,Y,Q){"use strict";function _(M){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(M){for(const t in M)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(M,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>M[t]})}}return e.default=M,Object.freeze(e)}const T=_(Z);class d{static guessTimeZoneOffset(e,t){e=d.convertToStdLng(e);const n=Y(t,e),s=x().tz(n).utcOffset();return d.roundPrecision(s/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),n=Math.round((Math.abs(e)-t)*60);return n=n>9?n:`0${n}`,t=t>9?t:`0${t}`,e>0?`+${t}:${n}`:`-${t}:${n}`}static lng2pretty(e,t=6,n="H°M′"){e=d.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;r=o%3600%60,n.indexOf("S")!==-1&&(o=o-r,i=d.padNumber(r,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,t).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),l=o/3600,n.indexOf("M")!==-1?u=d.roundPrecision(l,t).toString().padStart(3,"0"):u=d.padNumber(l,3,6),Number(i)>=60&&(a=Number(a)+1,i=0),Number(a)>=60&&(u=Number(u)+1,a=0);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let s="N";e<0&&(s="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;r=o%3600%60,n.indexOf("S")!==-1&&(o=o-r,i=d.padNumber(r,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,t).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),l=o/3600,n.indexOf("M")!==-1?u=d.roundPrecision(l,t).toString().padStart(2,"0"):u=d.padNumber(l,2,6),Number(i)>=60&&(a=Number(a)+1,i=0),Number(a)>=60&&(u=Number(u)+1,a=0);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c||0,c=c>60?c/Math.pow(10,String(c).length-2):c,r>360&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}n=r+i/60+c/3600,s==="W"&&(n=n*-1)}else n=Number(e);return d.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(c=c||0,i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c>60?c/Math.pow(10,String(c).length-2):c,r>90&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}if(n=r+i/60+c/3600,n>90)throw new Error(`latitude out of range: ${e}${s}`);s==="S"&&(n=n*-1)}else n=Number(e);return d.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=d.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:d.str2Lat(e,t)}:{lng:d.str2Lng(e,t)}}static convertToStdLng(e,t=6){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),d.roundPrecision(e,t)}static roundPrecision(e,t=6){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/([0-9]+)-([0-9]+\.[0-9]+)/g,"$1 $2").replace(/°/," ").replace(/(\d+)-(\d?)/g,"$1 $2").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const n=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=e,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${s}E`:o<=-90?e=`${s}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${s}${o>0?"E":"W"}`:e=`${s}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const s=d.roundPrecision(e-Math.trunc(e),n),o=s>=1?Math.trunc(e+1).toString().padStart(t,"0"):Math.trunc(e).toString().padStart(t,"0");return s>=1?o:n>0?`${o}.${Math.trunc(s*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class K{static json2Str(e){const t=e.type?e.type[0].toUpperCase():"A";return`${e.lat}|${e.lng}|${e.positionTime}|${e.sog}|${e.cog}|${e.hdg}|${e.draught}|${t}|${JSON.stringify(e.meteo||{})}|${e.vendor}|${e.deleted}`}static str2Json(e){const[t,n,s,o,r,i,c,a,l,u,g]=e.split("|");return{lat:Number(t),lng:Number(n),positionTime:Number(s),sog:Number(o),cog:Number(r),hdg:Number(i),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:l?JSON.parse(l):void 0,vendor:u,deleted:g==="true"}}static inspectStoppages(e,t=1,n=!0){const s=e.at(0).positionTime<e.at(-1).positionTime;s||e.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let r,i;for(let c=0;c<e.length-1;c++){const a=e[c];if(!(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))){for(let l=c+1;l<e.length;l++){const u=e[l-1],g=e[l];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const h=g.positionTime-u.positionTime;if(b.calculateDistance(g,u,!0,4)/(h/3600)<t)r||(r=a),l===e.length-1&&(i=g,c=l);else{r&&(i=e[l-1],c=l);break}}if((i==null?void 0:i.positionTime)>(r==null?void 0:r.positionTime)&&r){const l={start:{lat:r.lat,lng:r.lng,sog:r.sog,positionTime:r.positionTime,utc:x.unix(r.positionTime).utc().format()},end:{lat:i.lat,lng:i.lng,sog:i.sog,positionTime:i.positionTime,utc:x.unix(i.positionTime).utc().format()},duration:i.positionTime-r.positionTime},u=e.filter(h=>h.positionTime>=l.start.positionTime&&h.positionTime<=l.end.positionTime),g=b.divideAccordingToLng(u);l.distance=b.calculateRouteDistance(g),l.hours=Math.round(l.duration/3600*10)/10,l.avgSog=Math.round(l.distance/l.hours*10)/10,o.push(l)}r=void 0,i=void 0}}return s||e.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(e,t,n){const s=x(t),o=x(n),r=e.filter(l=>l.positionTime>=s.unix()&&l.positionTime<=o.unix());let i=0,c=0;if(r.length>1)for(let l=0;l<r.length-1;l++){const u=r[l],g=r[l+1];i+=b.calculateDistance(u,g,!0,4),c+=Math.abs(g.positionTime-u.positionTime)}i=Math.round(i*100)/100,c=Math.round(c/3600*100)/100;const a=c?Math.round(i/c*100)/100:0;return{distance:i,interval:c,avgSpd:a}}}let X;try{X=J.getLogger("meteo")}catch{}finally{}const H=(()=>{const M=new Uint32Array(256);for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;M[e]=t}return M})();function ee(M){let e=4294967295;for(let t=0;t<M.length;t++)e=H[(e^M[t])&255]^e>>>8;return(e^4294967295)>>>0}function te(M){const e=new TextEncoder,t=[],n=[];let s=0;for(const h of M){const p=e.encode(h.name),f=ee(h.data),m=new Uint8Array(30+p.length),S=new DataView(m.buffer);S.setUint32(0,67324752,!0),S.setUint16(4,20,!0),S.setUint16(8,0,!0),S.setUint32(14,f,!0),S.setUint32(18,h.data.length,!0),S.setUint32(22,h.data.length,!0),S.setUint16(26,p.length,!0),m.set(p,30),t.push({nameBytes:p,data:h.data,crc:f,offset:s}),s+=m.length+h.data.length,n.push(m,h.data)}const o=s,r=[];let i=0;for(const h of t){const p=new Uint8Array(46+h.nameBytes.length),f=new DataView(p.buffer);f.setUint32(0,33639248,!0),f.setUint16(4,20,!0),f.setUint16(6,20,!0),f.setUint16(10,0,!0),f.setUint32(16,h.crc,!0),f.setUint32(20,h.data.length,!0),f.setUint32(24,h.data.length,!0),f.setUint16(28,h.nameBytes.length,!0),f.setUint32(42,h.offset,!0),p.set(h.nameBytes,46),i+=p.length,r.push(p)}const c=new Uint8Array(22),a=new DataView(c.buffer);a.setUint32(0,101010256,!0),a.setUint16(8,t.length,!0),a.setUint16(10,t.length,!0),a.setUint32(12,i,!0),a.setUint32(16,o,!0);const l=n.reduce((h,p)=>h+p.length,0)+i+22,u=new Uint8Array(l);let g=0;for(const h of n)u.set(h,g),g+=h.length;for(const h of r)u.set(h,g),g+=h.length;return u.set(c,g),u}function V(M){let e="",t=M;for(;t>=0;)e=String.fromCharCode(65+t%26)+e,t=Math.floor(t/26)-1;return e}class b{static calculateBearing(e,t,n=!0,s=4){const o=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=T.rhumbBearing(o.features[0],o.features[1]):r=T.bearing(o.features[0],o.features[1]),r<0&&(r+=360),d.roundPrecision(r,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=d.convertToStdLng(e.lng,s),t.lng=d.convertToStdLng(t.lng,s);const r=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=T.rhumbDistance(r.features[0],r.features[1],{units:o}):i=T.distance(r.features[0],r.features[1],{units:o}),d.roundPrecision(i,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const r of e)for(let i=0;i<r.length-1;i++){const c={lng:r[i][0],lat:r[i][1]};i===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const a={lng:r[i+1][0],lat:r[i+1][1]};s+=this.calculateDistance(c,a,!0,t,n),o=a}return d.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const r=T.point([e.lng,e.lat]);let i;o?i=T.rhumbDestination(r,n,t,{units:s}):i=T.destination(r,n,t,{units:s});const c=i.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,r="nauticalmiles"){const i=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,r);s&&i.push({lng:e.lng,lat:e.lat});let l=0;for(;l<a;)l+=n,l<a&&i.push(this.calculateCoordinate(e,c,l,r,!1));return o&&i.push({lng:t.lng,lat:t.lat}),i}static divideAccordingToLng(e,t=!1,n=!0){if((e==null?void 0:e.length)<2)return[];e=n?this.deduplicateCoordinates(e):e;let s=[];const o=[];let r,i;for(let c=0;c<e.length-1;c++){r=d.convertToStdLng(e[c].lng,8),i=d.convertToStdLng(e[c+1].lng,8),e[c].lat=d.roundPrecision(e[c].lat,8),e[c+1].lat=d.roundPrecision(e[c+1].lat,8),s.push([r,e[c].lat]);const a=r-i;if(Math.abs(a)>180){const l=d.convertToMonotonicLng2([[r,e[c].lat],[i,e[c+1].lat]]);let u,g;t?(u=T.lineString(l),g=T.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(u=T.greatCircle(l[0],l[1]),g=T.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const h=T.lineIntersect(u,g);let p;if(h.features.length){const f=T.getCoord(h.features[0]);p=d.roundPrecision(f[1],8)}else p=e[c].lat;a>0?(s.push([180-1e-6,p]),o.push([...s]),s=[],s.push([-(180-1e-6),p])):(s.push([-(180-1e-6),p]),o.push([...s]),s=[],s.push([180-1e-6,p]))}c===e.length-2&&s.push([i,e[c+1].lat])}return o.push(s),o}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,r)=>(o.findIndex(i=>i[0]===r[0]&&i[1]===r[1])===-1&&o.push(r),o),[]);t.push(s)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)d.roundPrecision(n[s][0],8)===e.lng&&d.roundPrecision(n[s][1],8)===d.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=d.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)d.roundPrecision(t[n].lng,8)===e.lng&&d.roundPrecision(t[n].lat,8)===d.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,r,i;return t.forEach((c,a)=>{for(let l=0;l<c.length-1;l++){const u={lng:c[l][0],lat:c[l][1]},g={lng:c[l+1][0],lat:c[l+1][1]},h=this.calculatePointToLineDistance(e,u,g);n>h&&(n=h,o=l,s=a,r=this.calculateDistance(u,e),i=this.calculateDistance(g,e))}}),r!==0&&i!==0?t[s].splice(o+1,0,[e.lng,e.lat]):r===0?t[s].splice(o,1,[e.lng,e.lat]):i===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);const n=b.convertRouteToCoordinates(t);return n.push(e),b.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=b.convertRouteToCoordinates(t);return n.unshift(e),b.divideAccordingToLng(n)}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(r=>{if(o===2)return;const i=[];for(const c of r){if(d.roundPrecision(t.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(c[1],8)){i.push(c),o===0&&i.push([e.lng,e.lat]),o=2;break}o===1?i.push(c):d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)&&(o=1,i.push(c))}i.length&&s.push(i)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),r=this.mergeCoordinatesToWaypoints([e,t],o.length?o:s),i=r.findIndex(l=>d.roundPrecision(e.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(l.lat,8)),c=r.findIndex(l=>d.roundPrecision(t.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(l.lat,8));return r.filter((l,u)=>u>=i&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((r,i)=>{for(let c=0;c<r.length-1;c++){const a={lng:r[c][0],lat:r[c][1]},l={lng:r[c+1][0],lat:r[c+1][1]},u=this.calculatePointToLineDistance(e,a,l);n>u&&(n=u,s=c,o=i)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const n=b.convertRouteToCoordinates(t);b.mergeCoordinateToWaypoints(e,n,!0),t=b.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=d.convertToStdLng(e.lng);const r=[];let i=!0;for(let c=s;c<t.length;c++)if(i){const a=[];a.push([e.lng,e.lat]);for(let l=o+1;l<t[c].length;l++)e.lng===t[c][l][0]&&e.lat===t[c][l][1]||a.push(t[c][l]);r.push(a),i=!1}else r.push([...t[c]]);return r}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let r=0;r<t.length-1;r++){const i=t[r],c=t[r+1];if(this.calculateDistance(e,i)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((l,u)=>u>0);const a=this.calculatePointToLineDistance(e,i,c);n>a&&(n=a,s=r)}e.lng=d.convertToStdLng(e.lng);const o=[e];for(let r=s+1;r<t.length;r++)o.push(t[r]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=d.convertToStdLng(e.lng,8),t={...t},n={...n},t.lng=d.convertToStdLng(t.lng,8),n.lng=d.convertToStdLng(n.lng,8);const o=d.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const r=T.lineString([[t.lng,t.lat],[n.lng,n.lat]]),i=T.pointToLineDistance(T.point([e.lng,e.lat]),r,s),c=T.pointToLineDistance(T.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),r,s);return d.roundPrecision(Math.min(i,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const s=e[n],o=e[n+1],r=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(r),o.distanceFromStart=d.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const s of e)this.mergeCoordinateToWaypoints(s,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=d.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,r=0,i=0;if(t.length<2)t.push(e);else{for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},l={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,l);s>=u&&(s=u,o=c,r=this.calculateDistance(a,e,!1,6),i=this.calculateDistance(l,e,!1,6))}r!==0&&i!==0?r<=s&&o===0?t.unshift(e):i<=s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):r===0?n?t.splice(o,1,e):t.splice(o+1,0,e):i===0&&(n?t.splice(o+1,1,e):t.splice(o+1,0,e))}return t.map((c,a)=>{c.lng=d.convertToStdLng(c.lng);const l=t[a+1];if(l&&((c.bearing===null||c.bearing===void 0)&&((c.positionTime||0)>(l.positionTime||0)?c.bearing=this.calculateBearing(l,c,!0):c.bearing=this.calculateBearing(c,l,!0)),c.cog=c.cog||c.bearing,!c.sog&&c.positionTime&&l.positionTime)){const u=this.calculateDistance(c,l,!0),g=Math.abs(l.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(u/g,2)}return c})}static generateRouteAccordingToWaypoints(e,t=!0,n=!0){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o];if(o===1&&s.push(r),i.gcToPrevious){const c=this.interpolateCoordinates(r,i,200,!1,!0,"nauticalmiles");s.push(...c)}else s.push(i)}return this.divideAccordingToLng(s,t,n)}static nearestCoordinateInRoute(e,t){const n=T.point([e.lng,e.lat]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),r=T.lineString(o),i=T.nearestPointOnLine(r,n),c=T.getCoord(i);return{lng:d.roundPrecision(c[0],8),lat:d.roundPrecision(c[1],8)}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],r=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,r)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var g;const o=e.speed||12,r=[];let i=[],c=!1,a=0,l=0,u;if(t&&n.length?(r.push(e),n.forEach((h,p)=>{if(c)i.push(h);else{const f=[];let m;for(let S=0;S<h.length;S++)if(u)f.push(h[S]);else{m={lng:h[S][0],lat:h[S][1]};const P=this.calculateDistance(e,m,!0,8,s);if(a+=P,a<t)l+=P,P&&r.push(m),e=m;else{if(l=t,a===t)u=m,f.push([u.lng,u.lat]);else{const N=a-t,y=this.calculateBearing(m,e);u=this.calculateCoordinate(m,y,N,s),f.push([u.lng,u.lat]),f.push([m.lng,m.lat])}c=!0}}f.length&&i.push(f),p===n.length-1&&!u&&(u=m)}})):(i=n,u={...e}),u)if(r.push(u),u.distanceFromPrevious=Math.round(l*1e4)/1e4,u.hourFromPrevious=Math.round(l/o*1e4)/1e4,((g=i[0])==null?void 0:g.length)>1){const h={lng:i[0][1][0],lat:i[0][1][1]};u.bearing=this.calculateBearing(u,h)}else u.bearing=0;return{coordinate:u,nextRoute:i,prevRoute:r}}static nearestCoordinateInLine(e,t,n){const s=d.convertToStdLng(e.lng,6),o=T.point([s,e.lat]),r=d.convertToStdLng(t.lng,6),i=d.convertToStdLng(n.lng,6),c=T.lineString([[r,t.lat],[i,n.lat]]),a=T.nearestPointOnLine(c,o),l=T.getCoord(a),u=d.roundPrecision(l[0],6),g=d.roundPrecision(l[1],6);return{lng:u,lat:g,inline:!(u===r&&g===t.lat)&&!(u===i&&g===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(r=>{r.forEach(i=>{const c={lng:d.roundPrecision(i[0],8),lat:d.roundPrecision(i[1],8)};if(!o)n.push(c),o=c;else if(o.bearing===void 0||o.bearing===null)o.bearing=this.calculateBearing(o,c,!0);else{const a=this.calculateDistance(s,c,!0);a&&a>=t&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(e,t,n=1){let s=this.convertRouteToCoordinates(e,n);return s=this.simplifyGCCoordinates(s,t),s}static simplifyGCCoordinates(e,t){t.forEach(s=>{this.mergeCoordinateToWaypoints(s,e,!0)});for(let s=1;s<t.length;s++){const o=t[s-1],r=t[s];if(r.gcToPrevious){const i=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===r.lng&&a.lat===r.lat);for(let a=c-1;a>i;a--)e.splice(a,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],r=e[s];r.gcToPrevious?(o.bearing=this.calculateBearing(o,r,!1),r.distanceFromPrevious=this.calculateDistance(o,r,!1)):(o.bearing=this.calculateBearing(o,r,!0),r.distanceFromPrevious=this.calculateDistance(o,r,!0)),n=d.roundPrecision(n+r.distanceFromPrevious),r.distanceFromStart=n}return e.map(s=>(s.lng=d.convertToStdLng(s.lng),s))}static calculateCenter(e){const t=[];for(const i of e)for(const c of i)t.push(c);const n=T.featureCollection([]),s=d.convertToMonotonicLng2(t);for(const i of s)n.features.push(T.point(i));const r=T.center(n).geometry.coordinates;return{lng:d.convertToStdLng(r[0],8),lat:d.roundPrecision(r[1],8)}}static calculateCenter2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateCenter(t)}static calculateBBox(e){const t=[];for(const o of e)for(const r of o)t.push(r);const n=d.convertToMonotonicLng2(t),s=T.lineString(n);return T.bbox(s)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}static simplifyCoordinates(e,t=1,n=180){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o],c=e[o+1];let a=!1,l=!1;if((r.velocity||r.suspend||r.important||r.pilot||o===1)&&(a=!0,s.push(r)),i.gcToPrevious&&(a||(a=!0,s.push(r)),l=!0,s.push(i),o++),c){const u=b.calculateDistance(r,i,!0),g=b.calculateDistance(i,c,!0),h=b.calculateDistance(r,c,!0),p=(Math.pow(u,2)+Math.pow(g,2)-Math.pow(h,2))/(2*u*g);Math.round(Math.acos(p)*180/Math.PI)<n&&h>t&&!l&&(s.push(i),o++)}if(o>=e.length-1){const u=e.at(-1);u&&s.push(u)}}return s}static nearestTSPointInWaypoints(e,t,n){const s=x.unix(e),o=n.filter(r=>s.clone().subtract(t,"hour").unix()<=(r.positionTime||0)&&s.clone().add(t,"h").unix()>=(r.positionTime||0));return o.sort((r,i)=>(r.positionTime||0)-(i.positionTime||0)),o.at(-1)}static deadReckoning(e,t){var o,r,i,c;e>1e12&&(e=Math.round(e/1e3));const n=x.unix(e);let s=t.find(a=>a.positionTime===n.unix());if(!s){const a=(r=(o=t.filter(u=>(u==null?void 0:u.positionTime)<n.unix()))==null?void 0:o.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:r.at(-1),l=(c=(i=t.filter(u=>(u==null?void 0:u.positionTime)>n.unix()))==null?void 0:i.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:c.at(0);if(a&&l){const u=b.calculateBearing(a,l,!0),g=b.calculateDistance(a,l),h=(n.unix()-a.positionTime)/(l.positionTime-a.positionTime);s=b.calculateCoordinate(a,u,g*h),s.positionTime=n.unix(),s.utc=n.utc().format(),s.cog=u,s.sog=Math.round(g/((l.positionTime-a.positionTime)/3600)*100)/100}else s=a||l,s&&(s.utc=x.unix(s==null?void 0:s.positionTime).utc().format())}return s}static deadReckoningTime(e,t){t=JSON.parse(JSON.stringify(t)),t.sort((a,l)=>(a.positionTime||0)-(l.positionTime||0));let n=Number.MAX_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER;for(let a=0;a<t.length-1;a++){const l=t[a],u=t[a+1],g=b.calculatePointToLineDistance(e,l,u);g<n&&(n=g,s=a)}const o=t[s],r=t[s+1],i=b.calculateDistance(o,e),c=b.calculateDistance(r,e);if(i===0)e=o;else if(c===0)e=r;else{const a=o.positionTime||0,l=r.positionTime||0,u=b.calculateDistance(o,r);e.positionTime=Math.round(a+(l-a)*(i/u))}return e.utc=e.positionTime?x.unix(e.positionTime).utc().format():void 0,e.positionTime?e:void 0}static reverseRoute(e){const t=[];for(const n of e)t.push(n.reverse());return t}static reverseCoordinates(e){return e.reverse()}static xmlEscape(e){return e==null?"":String(e).trim().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static waypoints2RTZ(e,t){const s=[];return s.push('<?xml version="1.0" encoding="UTF-8"?>'),s.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),s.push(` <routeInfo routeName="${b.xmlEscape(e)}"></routeInfo>`),s.push(...b.toRTZWaypoints(t,6)),s.push("</route>"),s.join(`
|
|
2
|
+
`)}static waypoints2RTZ10(e,t,n=!0){const o=[];return o.push('<?xml version="1.0" encoding="UTF-8"?>'),o.push('<route xmlns="http://www.cirm.org/RTZ/1/0" version="1.0">'),o.push(` <routeInfo routeName="${b.xmlEscape(e)}"></routeInfo>`),o.push(...b.toRTZWaypoints(t,6,n)),o.push("</route>"),o.join(`
|
|
3
|
+
`)}static toRTZWaypoints(e,t=6,n=!0){const s=[];s.push(" <waypoints>");for(let o=0;o<e.length;o++){const r=e[o],i=o+1,c=(r.lat??"").toFixed?r.lat.toFixed(t).padEnd(t+2,"0"):r.lat,a=(r.lng??"").toFixed?r.lng.toFixed(t).padEnd(t+2,"0"):r.lng,l=[`id="${i}"`,'revision="0"'];if(r.name&&l.push(`name="${b.xmlEscape(r.name)}"`),s.push(` <waypoint ${l.join(" ")}>`),s.push(` <position lat="${b.xmlEscape(c)}" lon="${b.xmlEscape(a)}" />`),o>0){const u=r.gcToPrevious?"Orthodrome":"Loxodrome";s.push(` <leg geometryType="${u}" />`)}if(n){const u=[];if(r.description&&u.push(` <description>${b.xmlEscape(r.description)}</description>`),r.utc)u.push(` <time>${b.xmlEscape(r.utc)}</time>`);else if(r.positionTime)try{u.push(` <time>${b.xmlEscape(x.unix(r.positionTime).utc().format())}</time>`)}catch{}r.cog!==void 0&&u.push(` <cog>${b.xmlEscape(r.cog)}</cog>`),r.sog!==void 0&&u.push(` <sog>${b.xmlEscape(r.sog)}</sog>`),u.length&&(s.push(" <extensions>"),s.push(...u),s.push(" </extensions>"))}s.push(" </waypoint>")}return s.push(" </waypoints>"),s}static waypoints2CSV(e,t,n){X.debug("keep name for waypoints2CSV for legacy compatibility only",e);const s=(n==null?void 0:n.precision)??6,o=t.some(m=>m.name),r=t.some(m=>m.description),i=t.some(m=>m.port!=null),c=t.some(m=>m.stbd!=null),a=t.some(m=>m.arrRad!=null),l=t.some(m=>m.speed!=null),u=t.some((m,S)=>S>0&&m.gcToPrevious!=null),g=t.some(m=>m.bearing!=null),h=t.some(m=>m.distanceFromPrevious!=null),p=["WPT No.","Latitude","Longitude"];o&&p.push("Name"),r&&p.push("Description"),u&&p.push("Leg"),g&&p.push("Bearing[deg]"),h&&p.push("Distance[NM]"),l&&p.push("Speed[kn]"),i&&p.push("PORT XTD[NM]"),c&&p.push("STBD XTD[NM]"),a&&p.push("Arr.Rad[NM]");const f=[];f.push(p.map(m=>b.csvEscapeField(m)).join(","));for(let m=0;m<t.length;m++){const S=t[m],P=[];P.push((m+1).toString()),P.push(S.lat.toFixed(s)),P.push(S.lng.toFixed(s)),o&&P.push(S.name??""),r&&P.push(S.description??""),u&&P.push(m===0?"":S.gcToPrevious?"GC":"RL"),g&&P.push(S.bearing!=null?String(S.bearing):""),h&&P.push(S.distanceFromPrevious!=null?String(S.distanceFromPrevious):""),l&&P.push(S.speed!=null?String(S.speed):""),i&&P.push(S.port!=null?String(S.port):""),c&&P.push(S.stbd!=null?String(S.stbd):""),a&&P.push(S.arrRad!=null?String(S.arrRad):""),f.push(P.map(N=>b.csvEscapeField(N)).join(","))}return f.join(`
|
|
4
|
+
`)}static waypoints2JRCCSV(e,t,n){const s=(n==null?void 0:n.precision)??3,o=t.some(f=>f.name),r=t.some(f=>f.port!=null),i=t.some(f=>f.stbd!=null),c=t.some(f=>f.arrRad!=null),a=t.some(f=>f.speed!=null),l=t.some((f,m)=>m>0&&f.gcToPrevious!=null),u=t.some(f=>f.rot!=null),g=t.some(f=>f.turnRad!=null),h=["// WPT No.","LAT","","","LON","",""];r&&h.push("PORT[NM]"),i&&h.push("STBD[NM]"),c&&h.push("Arr. Rad[NM]"),a&&h.push("Speed[kn]"),l&&h.push("Sail(RL/GC)"),u&&h.push("ROT[deg/min]"),g&&h.push("Turn Rad[NM]"),o&&h.push("Name");const p=[];p.push("// ROUTE SHEET exported by JRC ECDIS."),p.push("// <<NOTE>>This strings // indicate comment column/cells. You can edit freely."),p.push(`// ${b.xmlEscape(e)}`),p.push(h.join(","));for(let f=0;f<t.length;f++){const m=[],S=t[f],P=String(f).padStart(3,"0");m.push(P);const N=d.lat2pretty(S.lat,6),y=d.lng2pretty(S.lng,6),C=N.H,k=Number(N.minute).toFixed(s),B=N.direction;m.push(C),m.push(k),m.push(B);const U=y.H,j=Number(y.minute).toFixed(s),w=y.direction;if(m.push(U),m.push(j),m.push(w),r){const v=f===0?"***":S.port!=null?String(S.port):"***";m.push(v)}if(i){const v=f===0?"***":S.stbd!=null?String(S.stbd):"***";m.push(v)}if(c){const v=f===0?"***":S.arrRad!=null?String(S.arrRad):"***";m.push(v)}if(a){const v=f===0?"***":S.speed!=null?Number(S.speed).toFixed(1).padStart(5,"0"):"***";m.push(v)}if(l){const v=f===0?"***":S.gcToPrevious?"GC":"RL";m.push(v)}if(u){const v=f===0?"***":S.rot!=null?String(S.rot):"***";m.push(v)}if(g){const v=f===0?"***":S.turnRad!=null?String(S.turnRad):"***";m.push(v)}if(o){const v=f===0?"***":S.name??"";m.push(v)}p.push(m.join(","))}return p.join(`
|
|
5
|
+
`)}static waypoints2XLSX(e,t,n){const s=(n==null?void 0:n.precision)??6,o=e||"Route",r=t.some(v=>v.name),i=t.some(v=>v.description),c=t.some(v=>v.port!=null),a=t.some(v=>v.stbd!=null),l=t.some(v=>v.arrRad!=null),u=t.some(v=>v.speed!=null),g=t.some((v,O)=>O>0&&v.gcToPrevious!=null),h=t.some(v=>v.bearing!=null),p=t.some(v=>v.distanceFromPrevious!=null),f=["WPT No.","Latitude","Longitude"];r&&f.push("Name"),i&&f.push("Description"),g&&f.push("Leg"),h&&f.push("Bearing[deg]"),p&&f.push("Distance[NM]"),u&&f.push("Speed[kn]"),c&&f.push("PORT XTD[NM]"),a&&f.push("STBD XTD[NM]"),l&&f.push("Arr.Rad[NM]");const m=v=>v==null?"":String(v).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");let P=`<row r="1">${f.map((v,O)=>`<c r="${V(O)}1" s="1" t="inlineStr"><is><t>${m(v)}</t></is></c>`).join("")}</row>`;for(let v=0;v<t.length;v++){const O=t[v],q=v+2,W=[],G=(L,z)=>W.push(`<c r="${V(L)}${q}"><v>${z}</v></c>`),E=(L,z)=>W.push(`<c r="${V(L)}${q}" t="inlineStr"><is><t>${m(z)}</t></is></c>`),A=(L,z)=>{z!=null?G(L,z):E(L,"")};G(0,v+1),E(1,d.lat2pretty(O.lat,s).pretty),E(2,d.lng2pretty(O.lng,s).pretty);let R=3;r&&(E(R,O.name??""),R++),i&&(E(R,O.description??""),R++),g&&(E(R,v===0?"":O.gcToPrevious?"GC":"RL"),R++),h&&(A(R,O.bearing),R++),p&&(A(R,O.distanceFromPrevious),R++),u&&(A(R,O.speed),R++),c&&(A(R,O.port),R++),a&&(A(R,O.stbd),R++),l&&(A(R,O.arrRad),R++),P+=`<row r="${q}">${W.join("")}</row>`}const N="0."+"0".repeat(s),y='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>'+P+"</sheetData></worksheet>",C='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/></Types>',k='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>',B='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="'+m(o)+'" sheetId="1" r:id="rId1"/></sheets></workbook>',U='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>',j='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><numFmts count="1"><numFmt numFmtId="164" formatCode="'+N+'"/></numFmts><fonts count="2"><font><sz val="11"/><name val="Arial"/></font><font><b/><sz val="11"/><name val="Arial"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="2"><border><left/><right/><top/><bottom/><diagonal/></border><border><bottom style="thin"><color auto="1"/></bottom></border></borders><cellStyleXfs count="1"><xf/></cellStyleXfs><cellXfs count="3"><xf/><xf fontId="1" fillId="0" borderId="1" applyFont="1" applyBorder="1"/><xf numFmtId="164" fontId="0" applyNumberFormat="1"/></cellXfs></styleSheet>',w=new TextEncoder;return te([{name:"[Content_Types].xml",data:w.encode(C)},{name:"_rels/.rels",data:w.encode(k)},{name:"xl/workbook.xml",data:w.encode(B)},{name:"xl/_rels/workbook.xml.rels",data:w.encode(U)},{name:"xl/worksheets/sheet1.xml",data:w.encode(y)},{name:"xl/styles.xml",data:w.encode(j)}])}static csvEscapeField(e){if(e==null)return"";const t=String(e);return t.includes(",")||t.includes('"')||t.includes(`
|
|
6
|
+
`)||t.includes("\r")?`"${t.replace(/"/g,'""')}"`:t}static decimalToNmeaDm(e,t){const n=Math.abs(e),s=Math.floor(n),o=(n-s)*60,r=t?`${s.toString().padStart(2,"0")}${o.toFixed(2).padStart(5,"0")}`:`${s.toString().padStart(3,"0")}${o.toFixed(2).padStart(5,"0")}`,i=t?e>=0?"N":"S":e>=0?"E":"W";return{dm:r,dir:i}}static nmeaChecksum(e){let t=0;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n);return t.toString(16).toUpperCase().padStart(2,"0")}static waypoints2NMEA(e){const t=[];for(let n=0;n<e.length;n++){const s=e[n],o=b.decimalToNmeaDm(s.lat,!0),r=b.decimalToNmeaDm(s.lng,!1),i=s.name?String(s.name).slice(0,6):`WPT${(n+1).toString().padStart(3,"0")}`,c=`GPWPL,${o.dm},${o.dir},${r.dm},${r.dir},${i}`,a=b.nmeaChecksum(c);t.push(`$${c}*${a}`)}return t.join(`\r
|
|
7
|
+
`)}static coordinatesSummary(e,t=3){if(e.length>1){const n=e[0],s=e[e.length-1],o=(n==null?void 0:n.positionTime)<(s==null?void 0:s.positionTime)?x.unix(n==null?void 0:n.positionTime):x.unix(s==null?void 0:s.positionTime),r=(n==null?void 0:n.positionTime)>(s==null?void 0:s.positionTime)?x.unix(n==null?void 0:n.positionTime):x.unix(s==null?void 0:s.positionTime),i=Math.round(r.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(e,!0,!0),a=this.calculateRouteDistance(c),u=K.inspectStoppages(e,t).reduce((h,p)=>(h.duration+=p.duration,h.distance+=p.distance,h),{hours:0,distance:0,spd:0,duration:0});u.hours=Math.round(u.duration/3600*100)/100,u.distance=Math.round(u.distance*100)/100,u.spd=u.hours?Math.round(u.distance/u.hours*100)/100:0;const g=i?Math.round((a-u.distance)/(i-u.hours)*100)/100:0;return{begin:o.utc().format(),end:r.utc().format(),distance:Math.round((a-u.distance)*100)/100,hours:Math.round((i-u.hours)*100)/100,avgSpeed:g,stoppage:u}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(e,t){var l,u,g;if(!((u=(l=t==null?void 0:t.sample)==null?void 0:l.hours)!=null&&u.length))return{routes:[],hour:void 0};const n=t.sample.hours.at(0),s=x.utc(e),o=x.utc(t.eta),r=s.isAfter(o)?o:s;let i=t.sample.all.find(h=>h.eta===r.format());if(!i){const h=t.sample.all.filter(C=>x.utc(C.eta).isBefore(r)).at(-1),p=this.calculateSubRoute(h,t.route);i=(g=this.calculateNextCoordinateAlongRoute(h,h.speed*r.diff(x(h.etd),"hours",!0),p))==null?void 0:g.coordinate;const{cFactor:f,cog:m,wxFactor:S,meteo:P}=h,N=Math.round(i.distanceFromPrevious*1e4)/1e4,y=Math.round((N+h.distanceFromStart)*1e4)/1e4;i={...i,cFactor:f,cog:m,speed:h.speed,wxFactor:S,distanceFromStart:y,distanceFromPrevious:N,meteo:P,eta:r.format(),etd:r.format()}}i.distanceToGo=Math.round((t.distance-i.distanceFromStart)*100)/100,i.timeToGo=Math.round(o.diff(i.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,i,t.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:i}}static pickUTCSampleFromRoute(e,t,n){var h;const s=this.calculateSubRoute(t,n),o=this.calculateRouteDistance(s),r=o/t.speed,i=x.utc(e),c=x(t.etd),a=(h=this.calculateNextCoordinateAlongRoute(t,t.speed*i.diff(x(t.etd),"hours",!0),s))==null?void 0:h.coordinate;a.speed=t.speed;const l=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(l.diff(i,"second"))<2?i.format():l.format(),a.etd=a.eta,a.distanceFromStart=Math.round(a.distanceFromPrevious*100)/100,a.distanceToGo=Math.round((o-a.distanceFromStart)*100)/100,a.timeToGo=Math.round(c.clone().add(r,"hour").diff(x(a.etd),"hour")*100)/100;const u=this.calculateRangeWaypoints(t,a,n);return{routes:this.generateRouteAccordingToWaypoints(u),hour:a}}static includedAngle(e,t){X==null||X.debug("calculate bearing via: %j",{bearing:e,degree:t});let n=Math.abs(e%360-(t%360||0));return n=n>180?360-n:n,n}}let $;try{$=J.getLogger("vessel")}catch{}finally{}class ne{static convert2Geojson(e){var n,s,o;const t=T.featureCollection([]);for(const r of e){const i=(n=r.history)==null?void 0:n[0];if(r.forecasts){i&&i.wind&&(i.wind.kts=i.kts);for(const c of r.forecasts){let a;const l=[],u=[],g=x(c.date).utc(),h=`${r.name}-${c.model}`;for(const f in c==null?void 0:c.hours){const m=c.hours[f];a=a||m;const S=g.clone().add(Number(f),"hour"),P=T.point([m.lng,m.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:S.format(),hour:Number(f),format:S.format("MMM-DD/HHmm[Z]"),pressure:m.pressure>1e4?d.roundPrecision(m.pressure/100,0):d.roundPrecision(m.pressure,0),gusts:m.gusts,wind:m.wind||{},movement:m.movement,category:h,type:"forecast"});u.push(P),l.push(P.geometry.coordinates)}const p={kts:void 0,deg:void 0};if(i){const f=x(i.updated).utc();if(a){const S=b.calculateDistance(i,a),P=x(a.utc||a.updated).diff(f,"h",!0);p.kts=Math.round(S/P*100)/100,p.deg=b.calculateBearing(i,a,!0,0)}const m=T.point([i.lng,i.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:f.format(),hour:0,format:f.format("MMM-DD/HHmm[Z]"),pressure:i.pressure>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i.pressure,0),wind:i.wind,movement:p,category:h,type:"forecast",important:!0});u.unshift(m),l.unshift(m.geometry.coordinates)}if(t.features.push(...u),(l==null?void 0:l.length)>1){const f=T.lineString(d.convertToMonotonicLng2(l),{date:(i==null?void 0:i.updated)||(g==null?void 0:g.format()),id:r.id||r.name,model:c.model,name:r.name,category:h,type:"forecast",movement:p});t.features.push(f)}}}if(t.features.sort((c,a)=>c.properties.type==="forecast"&&a.properties.type==="forecast"&&c.geometry.type==="Point"&&a.geometry.type==="Point"?x(c.properties.date).valueOf()-x(a.properties.date).valueOf():0),(s=r.history)!=null&&s.length){const c=[],a=x(i==null?void 0:i.updated).utc(),l=x((o=r.history)==null?void 0:o.at(-1).updated).utc(),u=a.diff(l,"h")%24>2?24:12;for(const g of r.history){const h=x(g.updated).utc(),p=h.isSameOrBefore(a)||h.isSame(l);p&&a.add(-u,"h");const f=T.point([g.lng,g.lat],{name:r.name,nameCn:r.nameCn,date:h.format(),format:h.format("MMM-DD/HHmm[Z]"),pressure:g.pressure>1e4?d.roundPrecision(g.pressure/100,0):d.roundPrecision(g.pressure,0),kts:g.kts,level:g.type,type:"history",category:`${r.name}-history`,wind:g.wind,movement:g.movement,important:p});t.features.push(f),c.push(f.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const g=T.lineString(d.convertToMonotonicLng2(c),{name:r.name,type:"history",updated:i==null?void 0:i.updated,pressure:(i==null?void 0:i.pressure)>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i==null?void 0:i.pressure,0),kts:i==null?void 0:i.kts,level:i==null?void 0:i.type});t.features.push(g)}}}return t}static interpolate(e,t=3){var o,r,i,c;const n=(o=e==null?void 0:e.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),s=[];for(const a of n){const l=a.properties.name,u=a.properties.model,g=a.properties.showCircle,h=a.properties.disabled,p=x(a.properties.date).utc();let f=t*60;const m=(r=e==null?void 0:e.data)==null?void 0:r.features.filter(N=>N.geometry.type==="Point"&&N.properties.type==="forecast"&&N.properties.category===`${l}-${u}`);let S,P=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0});for(;S=this.pickIndex(m,P),S<=m.length-1;){if(S>0){const N=m[S],y=S===0?void 0:m[S-1],C=(f/60-((i=y==null?void 0:y.properties)==null?void 0:i.hour))/(N.properties.hour-((c=y==null?void 0:y.properties)==null?void 0:c.hour)),k=this.computeNumber(y==null?void 0:y.geometry.coordinates[0],N.geometry.coordinates[0],C),B=this.computeNumber(y==null?void 0:y.geometry.coordinates[1],N.geometry.coordinates[1],C),U=T.point([k,B],{name:l,model:u,category:N==null?void 0:N.properties.category,date:P.format(),format:P.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(y==null?void 0:y.properties.gusts,N.properties.gusts,C),hour:this.computeNumber(y==null?void 0:y.properties.hour,N.properties.hour,C),movement:this.computeNumber(y==null?void 0:y.properties.movement,N.properties.movement,C),pressure:this.computeNumber(y==null?void 0:y.properties.pressure,N.properties.pressure,C),wind:this.computeNumber(y==null?void 0:y.properties.wind,N.properties.wind,C),type:"forecast",disabled:h,showCircle:g});s.push(U)}f+=t*60,P=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(e,t){const{t1:n,t2:s,hr:o,hours:r}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:s,hr:o,hours:r}}static diversionPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const p=b.calculateDistance(e,o),f=b.calculateDistance(e,r);if(p>2*n&&f>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,p,f,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=Math.abs(a-l);let g=0;u<180?g=u+90:u>=180&&(g=u-90);const h=b.calculateCoordinate(o,g,n);return $==null||$.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:r,radius:n,bearing1:a,bearing2:l,right:h}),{at:h,t1:o,t2:r,hr:Number(i),hours:c}}return{}}static driftPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const h=b.calculateDistance(e,o),p=b.calculateDistance(e,r);if(h>2*n&&p>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,h,p,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=b.calculateDistance(e,o);return{at:b.calculateCoordinate(o,a-l+180,n<u?n:u),t1:o,t2:r,hr:Number(i),hours:c}}else return $==null||$.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:r,hr:i}),{}}static tropicalCenterTwin(e,t=24,n={}){var l,u,g,h,p;let s={};(l=e.forecasts)==null||l.forEach(f=>{s={...f.hours,...s}});const o=((u=e==null?void 0:e.history)==null?void 0:u[0])||(s==null?void 0:s[(g=Object.keys(s))==null?void 0:g[0]]);$==null||$.info("[%s] the first tropical center: %j",n.requestId,o);let r=(h=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:t)))==null?void 0:h.at(-1);r||(r=(p=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:2*t)))==null?void 0:p.at(-1));const i=s==null?void 0:s[r||-1];$==null||$.info("[%s] the second tropical center: %j in %d hrs",n.requestId,i,r);const c=Object.keys(s||{}).filter(f=>Number(f)<=Number(r)),a={0:o};for(const f of c)a[f]=s[f];return{t1:o,t2:i,hr:Number(r),hours:a}}static pickIndex(e,t){let n=0;for(const s of e){if(x(s.properties.date).isAfter(t))return n===0?-1:n;n++}return n}static computeNumber(e,t,n){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const s={};for(const o in e)s[o]=this.computeNumber(e[o],t[o],n);return s}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}typeof globalThis<"u"&&typeof globalThis.Buffer>"u"&&(globalThis.Buffer={isBuffer(M){return M instanceof Uint8Array},from(M,e){if(typeof M=="string")return new TextEncoder().encode(M);if(M instanceof ArrayBuffer)return new Uint8Array(M);if(Array.isArray(M))return new Uint8Array(M);throw new TypeError("Buffer.from: unsupported source type")}});let D;try{D=J.getLogger("meteo")}catch{}finally{}function se(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:M}=require("jsdom"),{DOMParser:e}=new M("").window;return new e}class F{static toArrayBuffer(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}static drawCircle(e,t,n,s={}){const o=(s==null?void 0:s.steps)??64,r=(s==null?void 0:s.units)??"nauticalmiles",i=(s==null?void 0:s.properties)??{},c=T.point([e,t]),a=T.destination(c,n,90,{units:r}),l=x.utc();i.id=(s==null?void 0:s.id)||l.valueOf().toString();const u="circle";return i.name=(s==null?void 0:s.name)||`${u}_${l.format()}`,i.radius=n,i.center=[e,t],i.end=a.geometry.coordinates.map(g=>d.roundPrecision(g,9)),i.units=r,i.steps=o,i.shape="circle",D.info("[%s] draw circle with %j",s==null?void 0:s.requestId,i),T.circle(c,n,{steps:o,units:r,properties:i})}static drawRect(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=x.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="rect";s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.start=e.map(l=>d.roundPrecision(l,9)),s.end=t.map(l=>d.roundPrecision(l,9)),s.shape="rect",D.info("[%s] draw rect with %j",n==null?void 0:n.requestId,s);const[i,c]=d.convertToMonotonicLng2([e,t]),a=[Math.min(i[0],c[0]),Math.min(i[1],c[1]),Math.max(i[0],c[0]),Math.max(i[1],c[1])];return T.bboxPolygon(a,{properties:s})}static drawLine(e,t={}){const n=(t==null?void 0:t.properties)??{},s=x.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="line";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.shape="line",D.info("[%s] draw line with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.lineString(r,n)}static drawPolygon(e,t={}){const n=(t==null?void 0:t.properties)??{},s=x.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="polygon";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.coordinates=e.map(i=>i.map(c=>d.roundPrecision(c,9))),n.shape="polygon",D.info("[%s] draw polygon with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.polygon([r],n)}static drawPoint(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=x.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="point";return s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.shape="point",D.info("[%s] draw point with %j",n==null?void 0:n.requestId,s),T.point([t,e],s)}static parseCircle(e,t={}){var s,o;D.info("[%s] parse circle with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="circle"){const r=x.utc();n.id=(n==null?void 0:n.id)||r.valueOf().toString();const i=n==null?void 0:n.id,c=((s=n==null?void 0:n.center)==null?void 0:s.length)==2?T.point(n.center):T.centroid(e);let a="center";c.properties={id:`${a}_${i}`,parentId:i,name:a};const l=(n==null?void 0:n.units)||"nauticalmiles";let u=n==null?void 0:n.radius;if(!u){const p=T.polygonToLine(e);u=T.pointToLineDistance(c,p,{units:l})}a="end";const g=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?T.point(n.end):T.destination(c,u,90,{units:l});g.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l};const h=T.lineString([c.geometry.coordinates,g.geometry.coordinates]);return a="edge",h.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l},T.featureCollection([c,g,h,e])}else return D.warn("[%s] not a orm-std circle, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseRect(e,t={}){D.info("[%s] parse rect with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="rect"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,l)=>{const u=T.point(r[l]);return u.properties={id:`${a}_${o}`,parentId:o,name:a},u});return T.featureCollection([...c,e])}else return D.warn("[%s] not a orm-std rect, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseLine(e,t={}){D.info("[%s] parse line with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="line"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates.map((c,a)=>{const l=`point_${a}`,u=T.point(c);return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std line, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parsePolygon(e,t={}){D.info("[%s] parse polygon with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="polygon"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates[0].map((c,a)=>{const l=T.point(c),u=`corner_${a}`;return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std polygon, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static _inflateRawSync(e){var t;if(typeof process<"u"&&((t=process.versions)!=null&&t.node)){const n=require("zlib");return new Uint8Array(n.inflateRawSync(Buffer.from(e)))}throw new Error("Sync inflate is not supported in browser; use the async convertKMZ2GeoJSONAsync / convertZIP2GeoJSONAsync instead")}static async _parseZipEntries(e){var g;const t=new Uint8Array(e),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),s=new DataView(n),o=new Uint8Array(n),r=new Map;let i=-1;for(let h=n.byteLength-22;h>=0;h--)if(s.getUint32(h,!0)===101010256){i=h;break}if(i<0)throw new Error("Invalid ZIP file: EOCD not found");s.getUint16(i+8,!0);const c=s.getUint32(i+12,!0),a=s.getUint32(i+16,!0);let l=a;const u=a+c;for(;l<u;){if(s.getUint32(l,!0)!==33639248)throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);const p=s.getUint16(l+10,!0),f=s.getUint32(l+20,!0),m=s.getUint16(l+28,!0),S=s.getUint16(l+30,!0),P=s.getUint16(l+32,!0),N=s.getUint32(l+42,!0),y=o.slice(l+46,l+46+m),C=new TextDecoder().decode(y),k=s.getUint16(N+26,!0),B=s.getUint16(N+28,!0),U=N+30+k+B,j=o.slice(U,U+f);if(p===0)r.set(C,j);else if(p===8){if(typeof DecompressionStream<"u"){const w=new DecompressionStream("deflate-raw"),v=w.writable.getWriter(),O=w.readable.getReader();v.write(j),v.close();const q=[];let W=0;for(;;){const{done:A,value:R}=await O.read();if(A)break;q.push(R),W+=R.length}const G=new Uint8Array(W);let E=0;for(const A of q)G.set(A,E),E+=A.length;r.set(C,G)}else if(typeof process<"u"&&((g=process.versions)!=null&&g.node))try{r.set(C,F._inflateRawSync(j))}catch{}}l+=46+m+S+P}return r}static async convertKML2GeoJSON(e,t={}){var i,c;D.info("[%s] convert kml to geojson",t==null?void 0:t.requestId);const s=se().parseFromString(e,"application/xml"),o=Array.from(s.querySelectorAll("Placemark")),r=[];for(const a of o){const l={},u=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const y of u){const C=y.getAttribute("name"),k=(c=(i=y.querySelector("value"))==null?void 0:i.textContent)==null?void 0:c.trim();C&&k!==void 0&&k!==null&&(l[C]=k)}const g=x.utc(),h=Object.keys(l).find(y=>y.toLowerCase().indexOf("name")!==-1),p=h?l[h]:void 0,f=`${g.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,m=y=>y.trim().split(/[\s\n]+/).filter(C=>C.length>0).map(C=>{const k=C.split(",").map(Number);return[k[0],k[1]]}),S=a.querySelector("LineString > coordinates");if(S){const y=m(S.textContent||"");if(y.length>=2){const C=T.lineString(y,{...l,shape:"line",id:f,name:p});r.push(C)}continue}const P=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(P){const y=m(P.textContent||"");if(y.length>=4){const C=y[0][0]===y[y.length-1][0]&&y[0][1]===y[y.length-1][1]?y:[...y,y[0]],k=T.polygon([C],{...l,shape:"polygon",id:f,name:p});r.push(k)}continue}const N=a.querySelector("Point > coordinates");if(N){const y=m(N.textContent||"");if(y.length>=1){const C=T.point(y[0],{...l,shape:"point",id:f,name:p});r.push(C)}continue}}return T.featureCollection(r)}static async convertKMZ2GeoJSON(e,t={}){var r;D.info("[%s] convert kmz to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=n.get("doc.kml")??((r=[...n.entries()].find(([i])=>i.toLowerCase().endsWith(".kml")))==null?void 0:r[1]);if(!s)return D.warn("[%s] no .kml file found in kmz",t==null?void 0:t.requestId),T.featureCollection([]);const o=new TextDecoder().decode(s);return F.convertKML2GeoJSON(o,t)}static async convertZIP2GeoJSON(e,t={}){D.info("[%s] convert zip to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=[];for(const[o,r]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const i=new TextDecoder().decode(r),c=await F.convertKML2GeoJSON(i,t);s.push(...c.features)}return s.length===0?(D.warn("[%s] no .kml files found in zip",t==null?void 0:t.requestId),this.convertSHP2GeoJSON(e,t)):T.featureCollection(s)}static async convertSHP2GeoJSON(e,t={}){D.info("[%s] convert shp zip to geojson",t==null?void 0:t.requestId);try{typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await Q(e);if(Array.isArray(n)){const s=n.flatMap(c=>c.features||[]),o=x.utc(),r=(t==null?void 0:t.id)||o.valueOf().toString(),i={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return s.forEach((c,a)=>{var p;const l=((p=c.geometry)==null?void 0:p.type)||"",u=i[l]||l.toLowerCase();c.properties=c.properties||{},c.properties.shape=u,c.properties.parentId=r,c.properties.id=`${r}_${a}`;const g=Object.keys(c.properties).find(f=>f.toLowerCase().indexOf("name")!==-1),h=g?c.properties[g]:void 0;c.properties.name=h||`${u}_${o.format()}_${a}`}),T.featureCollection(s)}return n}catch(n){return D.warn("[%s] failed to convert shp zip: %s",t==null?void 0:t.requestId,n),T.featureCollection([])}}}I.AisHelper=K,I.GeoJsonHelper=F,I.LaneHelper=b,I.LngLatHelper=d,I.TropicalHelper=ne,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})});
|
package/dist/lane/src/index.d.ts
CHANGED
|
@@ -379,6 +379,16 @@ export declare class LaneHelper {
|
|
|
379
379
|
static waypoints2CSV(name: string, waypoints: Coordinate[], options?: {
|
|
380
380
|
precision?: number;
|
|
381
381
|
}): string;
|
|
382
|
+
/**
|
|
383
|
+
* 路径导出为 JRC ECDIS CSV 格式
|
|
384
|
+
* 符合 JRC ECDIS 路由表导入/导出规范
|
|
385
|
+
* @param name 航线名称
|
|
386
|
+
* @param waypoints 途径点
|
|
387
|
+
* @param options.precision 经纬度分钟小数位数,默认3
|
|
388
|
+
*/
|
|
389
|
+
static waypoints2JRCCSV(name: string, waypoints: Coordinate[], options?: {
|
|
390
|
+
precision?: number;
|
|
391
|
+
}): string;
|
|
382
392
|
/**
|
|
383
393
|
* 路径导出为 XLSX (Office Open XML 格式,无需第三方依赖)
|
|
384
394
|
* 兼容 Excel 2007+、LibreOffice、Google Sheets、WPS、macOS Numbers 等所有现代表格软件
|