@idm-plugin/geo 2.1.8 → 2.2.1
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 +467 -440
- package/dist/index.umd.cjs +6 -6
- package/package.json +1 -1
package/dist/index.umd.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(D,I){typeof exports=="object"&&typeof module<"u"?I(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"],I):(D=typeof globalThis<"u"?globalThis:D||self,I(D["idm-plugin-rabbitmq"]={},D["@turf/turf"],D.moment,D["@log4js-node/log4js-api"],D["moment-timezone"],D["tz-lookup"],D.shpjs))})(this,function(D,I,b,w,Z,q,W){"use strict";function U(R){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(R){for(const e in R)if(e!=="default"){const n=Object.getOwnPropertyDescriptor(R,e);Object.defineProperty(t,e,n.get?n:{enumerable:!0,get:()=>R[e]})}}return t.default=R,Object.freeze(t)}const h=U(I);class d{static guessTimeZoneOffset(t,e){t=d.convertToStdLng(t);const n=q(e,t),i=b().tz(n).utcOffset();return d.roundPrecision(i/60,1)}static prettyTimeZoneOffset(t){let e=Math.floor(Math.abs(t)),n=Math.round((Math.abs(t)-e)*60);return n=n>9?n:`0${n}`,e=e>9?e:`0${e}`,t>0?`+${e}:${n}`:`-${e}:${n}`}static lng2pretty(t,e=6,n="H°M′"){t=d.convertToStdLng(t,e);let i="E";t<0&&(i="W"),t=Math.abs(t),n=n.toUpperCase();let o=t*3600,s,r,c,a,u,l;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=d.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,e).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),u=o/3600,n.indexOf("M")!==-1?l=d.roundPrecision(u,e).toString().padStart(3,"0"):l=d.padNumber(u,3,6),Number(r)>=60&&(a=Number(a)+1,r=0),Number(a)>=60&&(l=Number(l)+1,a=0);const g=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,l)}${i}`;return{direction:i,degree:d.roundPrecision(u,e),minute:d.roundPrecision(c,e),second:d.roundPrecision(s,e),pretty:g,S:r,M:a,H:l}}static lat2pretty(t,e=6,n="H°M′"){t=t%180;let i="N";t<0&&(i="S"),t=Math.abs(t),n=n.toUpperCase();let o=t*3600,s,r,c,a,u,l;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=d.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=d.roundPrecision(c,e).toString().padStart(2,"0"):a=d.padNumber(c,2,3),o=o-c*60),u=o/3600,n.indexOf("M")!==-1?l=d.roundPrecision(u,e).toString().padStart(2,"0"):l=d.padNumber(u,2,6),Number(r)>=60&&(a=Number(a)+1,r=0),Number(a)>=60&&(l=Number(l)+1,a=0);const g=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,l)}${i}`;return{direction:i,degree:d.roundPrecision(u,e),minute:d.roundPrecision(c,e),second:d.roundPrecision(s,e),pretty:g,S:r,M:a,H:l}}static str2Lng(t,e=6){let n;if(isNaN(t)){t=d.strReplace(t,"LNG");const i=t[t.length-1].toUpperCase();t=t.substring(0,t.length-1).trim();const o=t.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[s,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,s>360&&!r){const a=this.roundPrecision(s/100,0);r=s-a*100,s=a}n=s+r/60+c/3600,i==="W"&&(n=n*-1)}else n=Number(t);return d.convertToStdLng(n,e)}static str2Lat(t,e=6){let n;if(isNaN(t)){t=d.strReplace(t,"LAT");const i=t[t.length-1].toUpperCase();t=t.substring(0,t.length-1).trim();const o=t.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[s,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,s>90&&!r){const a=this.roundPrecision(s/100,0);r=s-a*100,s=a}if(n=s+r/60+c/3600,n>90)throw new Error(`latitude out of range: ${t}${i}`);i==="S"&&(n=n*-1)}else n=Number(t);return d.roundPrecision(n,e)}static str2LngOrLat(t,e=6,n="LAT"){t=d.strReplace(t,n);const i=t[t.length-1].toUpperCase();return["N","S"].includes(i)?{lat:d.str2Lat(t,e)}:{lng:d.str2Lng(t,e)}}static convertToStdLng(t,e=6){return t>180?(t=t%360,t=t>180?t-360:t):t<-180&&(t=t%360,t=t<-180?t+360:t),d.roundPrecision(t,e)}static roundPrecision(t,e=6){const n=Number("1".padEnd(e+1,"0"));return Math.round(t*n)/n}static convertToMonotonicLng2(t){for(let e=1;e<t.length;e++)t[e][0]+=Math.round((t[e-1][0]-t[e][0])/360)*360;return t}static convertToMonotonicLng(t){for(let e=1;e<t.length;e++)t[e].lng+=Math.round((t[e-1].lng-t[e].lng)/360)*360;return t}static strReplace(t,e="LAT"){t=t.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=t[t.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const i=t,o=Number(i.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${t}`);o>=90?t=`${i}E`:o<=-90?t=`${i}W`:["LAN","LNG"].includes(e==null?void 0:e.toUpperCase())?t=`${i}${o>0?"E":"W"}`:t=`${i}${o>0?"N":"S"}`}return t}static padNumber(t,e=2,n=2){const i=d.roundPrecision(t-Math.trunc(t),n),o=i>=1?Math.trunc(t+1).toString().padStart(e,"0"):Math.trunc(t).toString().padStart(e,"0");return i>=1?o:n>0?`${o}.${Math.trunc(i*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class j{static json2Str(t){const e=t.type?t.type[0].toUpperCase():"A";return`${t.lat}|${t.lng}|${t.positionTime}|${t.sog}|${t.cog}|${t.hdg}|${t.draught}|${e}|${JSON.stringify(t.meteo||{})}|${t.vendor}|${t.deleted}`}static str2Json(t){const[e,n,i,o,s,r,c,a,u,l,g]=t.split("|");return{lat:Number(e),lng:Number(n),positionTime:Number(i),sog:Number(o),cog:Number(s),hdg:Number(r),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:u?JSON.parse(u):void 0,vendor:l,deleted:g==="true"}}static inspectStoppages(t,e=1,n=!0){const i=t.at(0).positionTime<t.at(-1).positionTime;i||t.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let s,r;for(let c=0;c<t.length-1;c++){const a=t[c];if(!(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))){for(let u=c+1;u<t.length;u++){const l=t[u-1],g=t[u];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const f=g.positionTime-l.positionTime;if(v.calculateDistance(g,l,!0,4)/(f/3600)<e)s||(s=a),u===t.length-1&&(r=g,c=u);else{s&&(r=t[u-1],c=u);break}}if((r==null?void 0:r.positionTime)>(s==null?void 0:s.positionTime)&&s){const u={start:{lat:s.lat,lng:s.lng,sog:s.sog,positionTime:s.positionTime,utc:b.unix(s.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-s.positionTime},l=t.filter(f=>f.positionTime>=u.start.positionTime&&f.positionTime<=u.end.positionTime),g=v.divideAccordingToLng(l);u.distance=v.calculateRouteDistance(g),u.hours=Math.round(u.duration/3600*10)/10,u.avgSog=Math.round(u.distance/u.hours*10)/10,o.push(u)}s=void 0,r=void 0}}return i||t.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(t,e,n){const i=b(e),o=b(n),s=t.filter(u=>u.positionTime>=i.unix()&&u.positionTime<=o.unix());let r=0,c=0;if(s.length>1)for(let u=0;u<s.length-1;u++){const l=s[u],g=s[u+1];r+=v.calculateDistance(l,g,!0,4),c+=Math.abs(g.positionTime-l.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 A;try{A=w.getLogger("meteo")}catch{}finally{}class v{static calculateBearing(t,e,n=!0,i=4){const o=h.points([[t.lng,t.lat],[e.lng,e.lat]]);let s;return n?s=h.rhumbBearing(o.features[0],o.features[1]):s=h.bearing(o.features[0],o.features[1]),s<0&&(s+=360),d.roundPrecision(s,i)}static calculateDistance(t,e,n=!0,i=4,o="nauticalmiles"){t={...t},e={...e},t.lng=d.convertToStdLng(t.lng,i),e.lng=d.convertToStdLng(e.lng,i);const s=h.points([[t.lng,t.lat],[e.lng,e.lat]]);let r;return n?r=h.rhumbDistance(s.features[0],s.features[1],{units:o}):r=h.distance(s.features[0],s.features[1],{units:o}),d.roundPrecision(r,i)}static calculateRouteDistance(t,e=4,n="nauticalmiles"){let i=0,o;for(const s of t)for(let r=0;r<s.length-1;r++){const c={lng:s[r][0],lat:s[r][1]};r===0&&o&&(i+=this.calculateDistance(o,c,!0,e,n));const a={lng:s[r+1][0],lat:s[r+1][1]};i+=this.calculateDistance(c,a,!0,e,n),o=a}return d.roundPrecision(i,e)}static calculateCoordinate(t,e,n,i="nauticalmiles",o=!0){const s=h.point([t.lng,t.lat]);let r;o?r=h.rhumbDestination(s,n,e,{units:i}):r=h.destination(s,n,e,{units:i});const c=r.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(t,e,n,i=!0,o=!0,s="nauticalmiles"){const r=[],c=this.calculateBearing(t,e,!1),a=this.calculateDistance(t,e,!1,8,s);i&&r.push({lng:t.lng,lat:t.lat});let u=0;for(;u<a;)u+=n,u<a&&r.push(this.calculateCoordinate(t,c,u,s,!1));return o&&r.push({lng:e.lng,lat:e.lat}),r}static divideAccordingToLng(t,e=!1,n=!0){if((t==null?void 0:t.length)<2)return[];t=n?this.deduplicateCoordinates(t):t;let i=[];const o=[];let s,r;for(let c=0;c<t.length-1;c++){s=d.convertToStdLng(t[c].lng,8),r=d.convertToStdLng(t[c+1].lng,8),t[c].lat=d.roundPrecision(t[c].lat,8),t[c+1].lat=d.roundPrecision(t[c+1].lat,8),i.push([s,t[c].lat]);const a=s-r;if(Math.abs(a)>180){const u=d.convertToMonotonicLng2([[s,t[c].lat],[r,t[c+1].lat]]);let l,g;e?(l=h.lineString(u),g=h.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(l=h.greatCircle(u[0],u[1]),g=h.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const f=h.lineIntersect(l,g);let m;if(f.features.length){const T=h.getCoord(f.features[0]);m=d.roundPrecision(T[1],8)}else m=t[c].lat;a>0?(i.push([180-1e-6,m]),o.push([...i]),i=[],i.push([-(180-1e-6),m])):(i.push([-(180-1e-6),m]),o.push([...i]),i=[],i.push([180-1e-6,m]))}c===t.length-2&&i.push([r,t[c+1].lat])}return o.push(i),o}static deduplicateRoute(t){const e=[];for(const n of t){const i=n.reduce((o,s)=>(o.findIndex(r=>r[0]===s[0]&&r[1]===s[1])===-1&&o.push(s),o),[]);e.push(i)}return e}static deduplicateCoordinates(t){return t.reduce((e,n)=>(e.findIndex(i=>i.lat===n.lat&&i.lng===n.lng)===-1&&e.push(n),e),[])}static removeCoordinateFromRoute(t,e){t.lng=d.convertToStdLng(t.lng,8);for(const n of e)for(let i=n.length-1;i>=0;i--)d.roundPrecision(n[i][0],8)===t.lng&&d.roundPrecision(n[i][1],8)===d.roundPrecision(t.lat,8)&&n.splice(i,1);return e}static removeCoordinateFromWaypoints(t,e){t.lng=d.convertToStdLng(t.lng,8);for(let n=e.length-1;n>=0;n--)d.roundPrecision(e[n].lng,8)===t.lng&&d.roundPrecision(e[n].lat,8)===d.roundPrecision(t.lat,8)&&e.splice(n,1);return e}static mergeCoordinateToRoute(t,e){t.lng=d.convertToStdLng(t.lng,8);let n=Number.MAX_VALUE,i=0,o=0,s,r;return e.forEach((c,a)=>{for(let u=0;u<c.length-1;u++){const l={lng:c[u][0],lat:c[u][1]},g={lng:c[u+1][0],lat:c[u+1][1]},f=this.calculatePointToLineDistance(t,l,g);n>f&&(n=f,o=u,i=a,s=this.calculateDistance(l,t),r=this.calculateDistance(g,t))}}),s!==0&&r!==0?e[i].splice(o+1,0,[t.lng,t.lat]):s===0?e[i].splice(o,1,[t.lng,t.lat]):r===0&&e[i].splice(o+1,1,[t.lng,t.lat]),e}static appendCoordinateToRoute(t,e){t.lng=d.convertToStdLng(t.lng,8);const n=v.convertRouteToCoordinates(e);return n.push(t),v.divideAccordingToLng(n)}static unshiftCoordinateToRoute(t,e){const n=v.convertRouteToCoordinates(e);return n.unshift(t),v.divideAccordingToLng(n)}static mergeWaypointsToRoute(t,e){for(const n of t)e=this.mergeCoordinateToRoute(n,e);return e}static calculateRangeRoute(t,e,n){n=this.mergeWaypointsToRoute([t,e],n);const i=[];let o=0;return n.forEach(s=>{if(o===2)return;const r=[];for(const c of s){if(d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([t.lng,t.lat]),o=2;break}o===1?r.push(c):d.roundPrecision(t.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&i.push(r)}),i}static calculateRangeWaypoints(t,e,n,i=[]){const o=this.convertRouteToCoordinates(n,0),s=this.mergeCoordinatesToWaypoints([t,e],o.length?o:i),r=s.findIndex(u=>d.roundPrecision(t.lng,8)===d.roundPrecision(u.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(u.lat,8)),c=s.findIndex(u=>d.roundPrecision(e.lng,8)===d.roundPrecision(u.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(u.lat,8));return s.filter((u,l)=>l>=r&&l<=c)}static calculateMinDistanceToRoute(t,e){let n=Number.MAX_VALUE,i=0,o=0;return e.forEach((s,r)=>{for(let c=0;c<s.length-1;c++){const a={lng:s[c][0],lat:s[c][1]},u={lng:s[c+1][0],lat:s[c+1][1]},l=this.calculatePointToLineDistance(t,a,u);n>l&&(n=l,i=c,o=r)}}),{minDist:n,segIndex:o,minIndex:i}}static calculateSubRoute(t,e){const n=v.convertRouteToCoordinates(e);v.mergeCoordinateToWaypoints(t,n,!0),e=v.divideAccordingToLng(n);const{segIndex:i,minIndex:o}=this.calculateMinDistanceToRoute({...t},e);t.lng=d.convertToStdLng(t.lng);const s=[];let r=!0;for(let c=i;c<e.length;c++)if(r){const a=[];a.push([t.lng,t.lat]);for(let u=o+1;u<e[c].length;u++)t.lng===e[c][u][0]&&t.lat===e[c][u][1]||a.push(e[c][u]);s.push(a),r=!1}else s.push([...e[c]]);return s}static calculateSubWaypoints(t,e){let n=Number.MAX_VALUE,i=0;for(let s=0;s<e.length-1;s++){const r=e[s],c=e[s+1];if(this.calculateDistance(t,r)===0)return e;if(this.calculateDistance(t,c)===0)return e.filter((u,l)=>l>0);const a=this.calculatePointToLineDistance(t,r,c);n>a&&(n=a,i=s)}t.lng=d.convertToStdLng(t.lng);const o=[t];for(let s=i+1;s<e.length;s++)o.push(e[s]);return o}static calculatePointToLineDistance(t,e,n,i={units:"nauticalmiles",method:"geodesic"}){t.lng=d.convertToStdLng(t.lng,8),e={...e},n={...n},e.lng=d.convertToStdLng(e.lng,8),n.lng=d.convertToStdLng(n.lng,8);const o=d.convertToMonotonicLng([e,n]);e=o[0],n=o[1];const s=h.lineString([[e.lng,e.lat],[n.lng,n.lat]]),r=h.pointToLineDistance(h.point([t.lng,t.lat]),s,i),c=h.pointToLineDistance(h.point([t.lng>0?t.lng-360:t.lng+360,t.lat]),s,i);return d.roundPrecision(Math.min(r,c),6)}static calculateWaypointsPropInRoute(t,e){e=this.mergeWaypointsToRoute(t,e);for(let n=0;n<t.length-1;n++){const i=t[n],o=t[n+1],s=this.calculateRangeRoute(i,o,e);n===0&&(i.distanceFromPrevious=0,i.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(s),o.distanceFromStart=d.roundPrecision((i.distanceFromStart||0)+o.distanceFromPrevious)}return t}static mergeCoordinatesToWaypoints(t,e,n=!0){for(const i of t)this.mergeCoordinateToWaypoints(i,e,n);return e}static mergeCoordinateToWaypoints(t,e,n=!0){t.lng=d.convertToStdLng(t.lng,8);let i=Number.MAX_VALUE,o=0,s=0,r=0;if(e.length<2)e.push(t);else{for(let c=0;c<e.length-1;c++){const a={lng:e[c].lng,lat:e[c].lat},u={lng:e[c+1].lng,lat:e[c+1].lat},l=this.calculatePointToLineDistance(t,a,u);i>=l&&(i=l,o=c,s=this.calculateDistance(a,t,!1,6),r=this.calculateDistance(u,t,!1,6))}s!==0&&r!==0?s<=i&&o===0?e.unshift(t):r<=i&&o===e.length-2?e.push(t):e.splice(o+1,0,t):s===0?n?e.splice(o,1,t):e.splice(o+1,0,t):r===0&&(n?e.splice(o+1,1,t):e.splice(o+1,0,t))}return e.map((c,a)=>{c.lng=d.convertToStdLng(c.lng);const u=e[a+1];if(u&&((c.bearing===null||c.bearing===void 0)&&((c.positionTime||0)>(u.positionTime||0)?c.bearing=this.calculateBearing(u,c,!0):c.bearing=this.calculateBearing(c,u,!0)),c.cog=c.cog||c.bearing,!c.sog&&c.positionTime&&u.positionTime)){const l=this.calculateDistance(c,u,!0),g=Math.abs(u.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(l/g,2)}return c})}static generateRouteAccordingToWaypoints(t,e=!0,n=!0){const i=[];for(let o=1;o<t.length;o++){const s=t[o-1],r=t[o];if(o===1&&i.push(s),r.gcToPrevious){const c=this.interpolateCoordinates(s,r,200,!1,!0,"nauticalmiles");i.push(...c)}else i.push(r)}return this.divideAccordingToLng(i,e,n)}static nearestCoordinateInRoute(t,e){const n=h.point([t.lng,t.lat]),o=this.convertRouteToCoordinates(e).map(a=>[a.lng,a.lat]),s=h.lineString(o),r=h.nearestPointOnLine(s,n),c=h.getCoord(r);return{lng:d.roundPrecision(c[0],8),lat:d.roundPrecision(c[1],8)}}static calculatePrevWaypoint(t,e){let n=0;this.mergeCoordinateToWaypoints(t,e);for(let i=0;i<e.length-1;i++){const o=e[i],s=e[i+1];if(this.calculateDistance(t,o)===0){n=i;break}if(this.calculateDistance(t,s)===0){n=i+1;break}}return e[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(t,e,n,i="nauticalmiles"){var g;const o=t.speed||12,s=[];let r=[],c=!1,a=0,u=0,l;if(e&&n.length?(s.push(t),n.forEach((f,m)=>{if(c)r.push(f);else{const T=[];let p;for(let y=0;y<f.length;y++)if(l)T.push(f[y]);else{p={lng:f[y][0],lat:f[y][1]};const P=this.calculateDistance(t,p,!0,8,i);if(a+=P,a<e)u+=P,P&&s.push(p),t=p;else{if(u=e,a===e)l=p,T.push([l.lng,l.lat]);else{const M=a-e,S=this.calculateBearing(p,t);l=this.calculateCoordinate(p,S,M,i),T.push([l.lng,l.lat]),T.push([p.lng,p.lat])}c=!0}}T.length&&r.push(T),m===n.length-1&&!l&&(l=p)}})):(r=n,l={...t}),l)if(s.push(l),l.distanceFromPrevious=Math.round(u*1e4)/1e4,l.hourFromPrevious=Math.round(u/o*1e4)/1e4,((g=r[0])==null?void 0:g.length)>1){const f={lng:r[0][1][0],lat:r[0][1][1]};l.bearing=this.calculateBearing(l,f)}else l.bearing=0;return{coordinate:l,nextRoute:r,prevRoute:s}}static nearestCoordinateInLine(t,e,n){const i=d.convertToStdLng(t.lng,6),o=h.point([i,t.lat]),s=d.convertToStdLng(e.lng,6),r=d.convertToStdLng(n.lng,6),c=h.lineString([[s,e.lat],[r,n.lat]]),a=h.nearestPointOnLine(c,o),u=h.getCoord(a),l=d.roundPrecision(u[0],6),g=d.roundPrecision(u[1],6);return{lng:l,lat:g,inline:!(l===s&&g===e.lat)&&!(l===r&&g===n.lat)}}static convertRouteToCoordinates(t,e=0){const n=[];let i,o;return t.forEach(s=>{s.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(i,c,!0);a&&a>=e&&(i.bearing=this.calculateBearing(i,c,!0),n.push(i),o=i)}i=c})}),i&&n.push(i),n}static simplifyRouteToCoordinates(t,e,n=1){let i=this.convertRouteToCoordinates(t,n);return i=this.simplifyGCCoordinates(i,e),i}static simplifyGCCoordinates(t,e){e.forEach(i=>{this.mergeCoordinateToWaypoints(i,t,!0)});for(let i=1;i<e.length;i++){const o=e[i-1],s=e[i];if(s.gcToPrevious){const r=t.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=t.findIndex(a=>a.lng===s.lng&&a.lat===s.lat);for(let a=c-1;a>r;a--)t.splice(a,1)}}let n=0;for(let i=1;i<t.length;i++){const o=t[i-1],s=t[i];s.gcToPrevious?(o.bearing=this.calculateBearing(o,s,!1),s.distanceFromPrevious=this.calculateDistance(o,s,!1)):(o.bearing=this.calculateBearing(o,s,!0),s.distanceFromPrevious=this.calculateDistance(o,s,!0)),n=d.roundPrecision(n+s.distanceFromPrevious),s.distanceFromStart=n}return t.map(i=>(i.lng=d.convertToStdLng(i.lng),i))}static calculateCenter(t){const e=[];for(const r of t)for(const c of r)e.push(c);const n=h.featureCollection([]),i=d.convertToMonotonicLng2(e);for(const r of i)n.features.push(h.point(r));const s=h.center(n).geometry.coordinates;return{lng:d.convertToStdLng(s[0],8),lat:d.roundPrecision(s[1],8)}}static calculateCenter2(t){const e=this.generateRouteAccordingToWaypoints(t);return this.calculateCenter(e)}static calculateBBox(t){const e=[];for(const o of t)for(const s of o)e.push(s);const n=d.convertToMonotonicLng2(e),i=h.lineString(n);return h.bbox(i)}static calculateBBox2(t){const e=this.generateRouteAccordingToWaypoints(t);return this.calculateBBox(e)}static simplifyCoordinates(t,e=1,n=180){const i=[];for(let o=1;o<t.length;o++){const s=t[o-1],r=t[o],c=t[o+1];let a=!1,u=!1;if((s.velocity||s.suspend||s.important||s.pilot||o===1)&&(a=!0,i.push(s)),r.gcToPrevious&&(a||(a=!0,i.push(s)),u=!0,i.push(r),o++),c){const l=v.calculateDistance(s,r,!0),g=v.calculateDistance(r,c,!0),f=v.calculateDistance(s,c,!0),m=(Math.pow(l,2)+Math.pow(g,2)-Math.pow(f,2))/(2*l*g);Math.round(Math.acos(m)*180/Math.PI)<n&&f>e&&!u&&(i.push(r),o++)}if(o>=t.length-1){const l=t.at(-1);l&&i.push(l)}}return i}static nearestTSPointInWaypoints(t,e,n){const i=b.unix(t),o=n.filter(s=>i.clone().subtract(e,"hour").unix()<=(s.positionTime||0)&&i.clone().add(e,"h").unix()>=(s.positionTime||0));return o.sort((s,r)=>(s.positionTime||0)-(r.positionTime||0)),o.at(-1)}static deadReckoning(t,e){var o,s,r,c;t>1e12&&(t=Math.round(t/1e3));const n=b.unix(t);let i=e.find(a=>a.positionTime===n.unix());if(!i){const a=(s=(o=e.filter(l=>(l==null?void 0:l.positionTime)<n.unix()))==null?void 0:o.sort((l,g)=>(l.positionTime||0)-(g.positionTime||0)))==null?void 0:s.at(-1),u=(c=(r=e.filter(l=>(l==null?void 0:l.positionTime)>n.unix()))==null?void 0:r.sort((l,g)=>(l.positionTime||0)-(g.positionTime||0)))==null?void 0:c.at(0);if(a&&u){const l=v.calculateBearing(a,u,!0),g=v.calculateDistance(a,u),f=(n.unix()-a.positionTime)/(u.positionTime-a.positionTime);i=v.calculateCoordinate(a,l,g*f),i.positionTime=n.unix(),i.utc=n.utc().format(),i.cog=l,i.sog=Math.round(g/((u.positionTime-a.positionTime)/3600)*100)/100}else i=a||u,i&&(i.utc=b.unix(i==null?void 0:i.positionTime).utc().format())}return i}static deadReckoningTime(t,e){e=JSON.parse(JSON.stringify(e)),e.sort((a,u)=>(a.positionTime||0)-(u.positionTime||0));let n=Number.MAX_SAFE_INTEGER,i=Number.MAX_SAFE_INTEGER;for(let a=0;a<e.length-1;a++){const u=e[a],l=e[a+1],g=v.calculatePointToLineDistance(t,u,l);g<n&&(n=g,i=a)}const o=e[i],s=e[i+1],r=v.calculateDistance(o,t),c=v.calculateDistance(s,t);if(r===0)t=o;else if(c===0)t=s;else{const a=o.positionTime||0,u=s.positionTime||0,l=v.calculateDistance(o,s);t.positionTime=Math.round(a+(u-a)*(r/l))}return t.utc=t.positionTime?b.unix(t.positionTime).utc().format():void 0,t.positionTime?t:void 0}static reverseRoute(t){const e=[];for(const n of t)e.push(n.reverse());return e}static reverseCoordinates(t){return t.reverse()}static xmlEscape(t){return t==null?"":String(t).trim().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static waypoints2RTZ(t,e){const i=[];return i.push('<?xml version="1.0" encoding="UTF-8"?>'),i.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),i.push(` <routeInfo routeName="${v.xmlEscape(t)}"></routeInfo>`),i.push(...v.toRTZWaypoints(e,6)),i.push("</route>"),i.join(`
|
|
2
|
-
`)}static waypoints2RTZ10(t,
|
|
3
|
-
`)}static toRTZWaypoints(t
|
|
4
|
-
`)}static csvEscapeField(
|
|
5
|
-
`)||
|
|
6
|
-
`)}static coordinatesSummary(t,e=3){if(t.length>1){const n=t[0],i=t[t.length-1],o=(n==null?void 0:n.positionTime)<(i==null?void 0:i.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(i==null?void 0:i.positionTime),s=(n==null?void 0:n.positionTime)>(i==null?void 0:i.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(i==null?void 0:i.positionTime),r=Math.round(s.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(t,!0,!0),a=this.calculateRouteDistance(c),l=j.inspectStoppages(t,e).reduce((f,m)=>(f.duration+=m.duration,f.distance+=m.distance,f),{hours:0,distance:0,spd:0,duration:0});l.hours=Math.round(l.duration/3600*100)/100,l.distance=Math.round(l.distance*100)/100,l.spd=l.hours?Math.round(l.distance/l.hours*100)/100:0;const g=r?Math.round((a-l.distance)/(r-l.hours)*100)/100:0;return{begin:o.utc().format(),end:s.utc().format(),distance:Math.round((a-l.distance)*100)/100,hours:Math.round((r-l.hours)*100)/100,avgSpeed:g,stoppage:l}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(t,e){var u,l,g;if(!((l=(u=e==null?void 0:e.sample)==null?void 0:u.hours)!=null&&l.length))return{routes:[],hour:void 0};const n=e.sample.hours.at(0),i=b.utc(t),o=b.utc(e.eta),s=i.isAfter(o)?o:i;let r=e.sample.all.find(f=>f.eta===s.format());if(!r){const f=e.sample.all.filter(N=>b.utc(N.eta).isBefore(s)).at(-1),m=this.calculateSubRoute(f,e.route);r=(g=this.calculateNextCoordinateAlongRoute(f,f.speed*s.diff(b(f.etd),"hours",!0),m))==null?void 0:g.coordinate;const{cFactor:T,cog:p,wxFactor:y,meteo:P}=f,M=Math.round(r.distanceFromPrevious*1e4)/1e4,S=Math.round((M+f.distanceFromStart)*1e4)/1e4;r={...r,cFactor:T,cog:p,speed:f.speed,wxFactor:y,distanceFromStart:S,distanceFromPrevious:M,meteo:P,eta:s.format(),etd:s.format()}}r.distanceToGo=Math.round((e.distance-r.distanceFromStart)*100)/100,r.timeToGo=Math.round(o.diff(r.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,r,e.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:r}}static pickUTCSampleFromRoute(t,e,n){var f;const i=this.calculateSubRoute(e,n),o=this.calculateRouteDistance(i),s=o/e.speed,r=b.utc(t),c=b(e.etd),a=(f=this.calculateNextCoordinateAlongRoute(e,e.speed*r.diff(b(e.etd),"hours",!0),i))==null?void 0:f.coordinate;a.speed=e.speed;const u=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(u.diff(r,"second"))<2?r.format():u.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(s,"hour").diff(b(a.etd),"hour")*100)/100;const l=this.calculateRangeWaypoints(e,a,n);return{routes:this.generateRouteAccordingToWaypoints(l),hour:a}}static includedAngle(t,e){A==null||A.debug("calculate bearing via: %j",{bearing:t,degree:e});let n=Math.abs(t%360-(e%360||0));return n=n>180?360-n:n,n}}let C;try{C=w.getLogger("vessel")}catch{}finally{}class L{static convert2Geojson(t){var n,i,o;const e=h.featureCollection([]);for(const s of t){const r=(n=s.history)==null?void 0:n[0];if(s.forecasts){r&&r.wind&&(r.wind.kts=r.kts);for(const c of s.forecasts){let a;const u=[],l=[],g=b(c.date).utc(),f=`${s.name}-${c.model}`;for(const T in c==null?void 0:c.hours){const p=c.hours[T];a=a||p;const y=g.clone().add(Number(T),"hour"),P=h.point([p.lng,p.lat],{model:c.model,name:s.name,nameCn:s.nameCn,date:y.format(),hour:Number(T),format:y.format("MMM-DD/HHmm[Z]"),pressure:p.pressure>1e4?d.roundPrecision(p.pressure/100,0):d.roundPrecision(p.pressure,0),gusts:p.gusts,wind:p.wind||{},movement:p.movement,category:f,type:"forecast"});l.push(P),u.push(P.geometry.coordinates)}const m={kts:void 0,deg:void 0};if(r){const T=b(r.updated).utc();if(a){const y=v.calculateDistance(r,a),P=b(a.utc||a.updated).diff(T,"h",!0);m.kts=Math.round(y/P*100)/100,m.deg=v.calculateBearing(r,a,!0,0)}const p=h.point([r.lng,r.lat],{model:c.model,name:s.name,nameCn:s.nameCn,date:T.format(),hour:0,format:T.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});l.unshift(p),u.unshift(p.geometry.coordinates)}if(e.features.push(...l),(u==null?void 0:u.length)>1){const T=h.lineString(d.convertToMonotonicLng2(u),{date:(r==null?void 0:r.updated)||(g==null?void 0:g.format()),id:s.id||s.name,model:c.model,name:s.name,category:f,type:"forecast",movement:m});e.features.push(T)}}}if(e.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),(i=s.history)!=null&&i.length){const c=[],a=b(r==null?void 0:r.updated).utc(),u=b((o=s.history)==null?void 0:o.at(-1).updated).utc(),l=a.diff(u,"h")%24>2?24:12;for(const g of s.history){const f=b(g.updated).utc(),m=f.isSameOrBefore(a)||f.isSame(u);m&&a.add(-l,"h");const T=h.point([g.lng,g.lat],{name:s.name,nameCn:s.nameCn,date:f.format(),format:f.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:`${s.name}-history`,wind:g.wind,movement:g.movement,important:m});e.features.push(T),c.push(T.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const g=h.lineString(d.convertToMonotonicLng2(c),{name:s.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});e.features.push(g)}}}return e}static interpolate(t,e=3){var o,s,r,c;const n=(o=t==null?void 0:t.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),i=[];for(const a of n){const u=a.properties.name,l=a.properties.model,g=a.properties.showCircle,f=a.properties.disabled,m=b(a.properties.date).utc();let T=e*60;const p=(s=t==null?void 0:t.data)==null?void 0:s.features.filter(M=>M.geometry.type==="Point"&&M.properties.type==="forecast"&&M.properties.category===`${u}-${l}`);let y,P=m.clone().add(T,"minute").set({minute:0,second:0,millisecond:0});for(;y=this.pickIndex(p,P),y<=p.length-1;){if(y>0){const M=p[y],S=y===0?void 0:p[y-1],N=(T/60-((r=S==null?void 0:S.properties)==null?void 0:r.hour))/(M.properties.hour-((c=S==null?void 0:S.properties)==null?void 0:c.hour)),$=this.computeNumber(S==null?void 0:S.geometry.coordinates[0],M.geometry.coordinates[0],N),E=this.computeNumber(S==null?void 0:S.geometry.coordinates[1],M.geometry.coordinates[1],N),k=h.point([$,E],{name:u,model:l,category:M==null?void 0:M.properties.category,date:P.format(),format:P.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(S==null?void 0:S.properties.gusts,M.properties.gusts,N),hour:this.computeNumber(S==null?void 0:S.properties.hour,M.properties.hour,N),movement:this.computeNumber(S==null?void 0:S.properties.movement,M.properties.movement,N),pressure:this.computeNumber(S==null?void 0:S.properties.pressure,M.properties.pressure,N),wind:this.computeNumber(S==null?void 0:S.properties.wind,M.properties.wind,N),type:"forecast",disabled:f,showCircle:g});i.push(k)}T+=e*60,P=m.clone().add(T,"minute").set({minute:0,second:0,millisecond:0})}}return i}static accelPassageAt(t,e){const{t1:n,t2:i,hr:o,hours:s}=this.tropicalCenterTwin(t,24,e);return{t1:n,t2:i,hr:o,hours:s}}static diversionPassageAt(t,e,n,i={}){const{t1:o,t2:s,hr:r,hours:c}=this.tropicalCenterTwin(e,24,i);if(o&&s){if(!i.debug){const m=v.calculateDistance(t,o),T=v.calculateDistance(t,s);if(m>2*n&&T>2*n)return C==null||C.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",i.requestId,m,T,{from:t,t1:o,t2:s,hr:r}),{}}const a=v.calculateBearing(t,o),u=v.calculateBearing(o,s),l=Math.abs(a-u);let g=0;l<180?g=l+90:l>=180&&(g=l-90);const f=v.calculateCoordinate(o,g,n);return C==null||C.info("[%s] the right tangent position: %j",i.requestId,{from:t,t1:o,t2:s,radius:n,bearing1:a,bearing2:u,right:f}),{at:f,t1:o,t2:s,hr:Number(r),hours:c}}return{}}static driftPassageAt(t,e,n,i={}){const{t1:o,t2:s,hr:r,hours:c}=this.tropicalCenterTwin(e,24,i);if(o&&s){if(!i.debug){const f=v.calculateDistance(t,o),m=v.calculateDistance(t,s);if(f>2*n&&m>2*n)return C==null||C.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",i.requestId,f,m,{from:t,t1:o,t2:s,hr:r}),{}}const a=v.calculateBearing(t,o),u=v.calculateBearing(o,s),l=v.calculateDistance(t,o);return{at:v.calculateCoordinate(o,a-u+180,n<l?n:l),t1:o,t2:s,hr:Number(r),hours:c}}else return C==null||C.info("[%s] no need drift: %j",i.requestId,{from:t,t1:o,t2:s,hr:r}),{}}static tropicalCenterTwin(t,e=24,n={}){var u,l,g,f,m;let i={};(u=t.forecasts)==null||u.forEach(T=>{i={...T.hours,...i}});const o=((l=t==null?void 0:t.history)==null?void 0:l[0])||(i==null?void 0:i[(g=Object.keys(i))==null?void 0:g[0]]);C==null||C.info("[%s] the first tropical center: %j",n.requestId,o);let s=(f=Object.keys(i||{}).filter(T=>Number(T)<=(e<0?24:e)))==null?void 0:f.at(-1);s||(s=(m=Object.keys(i||{}).filter(T=>Number(T)<=(e<0?24:2*e)))==null?void 0:m.at(-1));const r=i==null?void 0:i[s||-1];C==null||C.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,s);const c=Object.keys(i||{}).filter(T=>Number(T)<=Number(s)),a={0:o};for(const T of c)a[T]=i[T];return{t1:o,t2:r,hr:Number(s),hours:a}}static pickIndex(t,e){let n=0;for(const i of t){if(b(i.properties.date).isAfter(e))return n===0?-1:n;n++}return n}static computeNumber(t,e,n){if(t)if(e){if(isNaN(t)&&isNaN(e)&&typeof t!="string"&&typeof e!="string"){const i={};for(const o in t)i[o]=this.computeNumber(t[o],e[o],n);return i}return Math.round((t+(e-t)*n)*100)/100}else return t;else return e}}let x;try{x=w.getLogger("meteo")}catch{}finally{}function z(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:R}=require("jsdom"),{DOMParser:t}=new R("").window;return new t}class O{static toArrayBuffer(t){return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}static drawCircle(t,e,n,i={}){const o=(i==null?void 0:i.steps)??64,s=(i==null?void 0:i.units)??"nauticalmiles",r=(i==null?void 0:i.properties)??{},c=h.point([t,e]),a=h.destination(c,n,90,{units:s}),u=b.utc();r.id=(i==null?void 0:i.id)||u.valueOf().toString();const l="circle";return r.name=(i==null?void 0:i.name)||`${l}_${u.format()}`,r.radius=n,r.center=[t,e],r.end=a.geometry.coordinates.map(g=>d.roundPrecision(g,9)),r.units=s,r.steps=o,r.shape="circle",x.info("[%s] draw circle with %j",i==null?void 0:i.requestId,r),h.circle(c,n,{steps:o,units:s,properties:r})}static drawRect(t,e,n={}){const i=(n==null?void 0:n.properties)??{},o=b.utc();i.id=(n==null?void 0:n.id)||o.valueOf().toString();const s="rect";i.name=(n==null?void 0:n.name)||`${s}_${o.format()}`,i.start=t.map(u=>d.roundPrecision(u,9)),i.end=e.map(u=>d.roundPrecision(u,9)),i.shape="rect",x.info("[%s] draw rect with %j",n==null?void 0:n.requestId,i);const[r,c]=d.convertToMonotonicLng2([t,e]),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 h.bboxPolygon(a,{properties:i})}static drawLine(t,e={}){const n=(e==null?void 0:e.properties)??{},i=b.utc();n.id=(e==null?void 0:e.id)||i.valueOf().toString();const o="line";n.name=(e==null?void 0:e.name)||`${o}_${i.format()}`,n.shape="line",x.info("[%s] draw line with %j",e==null?void 0:e.requestId,n);const s=d.convertToMonotonicLng2(t);return h.lineString(s,n)}static drawPolygon(t,e={}){const n=(e==null?void 0:e.properties)??{},i=b.utc();n.id=(e==null?void 0:e.id)||i.valueOf().toString();const o="polygon";n.name=(e==null?void 0:e.name)||`${o}_${i.format()}`,n.coordinates=t.map(r=>r.map(c=>d.roundPrecision(c,9))),n.shape="polygon",x.info("[%s] draw polygon with %j",e==null?void 0:e.requestId,n);const s=d.convertToMonotonicLng2(t);return h.polygon([s],n)}static drawPoint(t,e,n={}){const i=(n==null?void 0:n.properties)??{},o=b.utc();i.id=(n==null?void 0:n.id)||o.valueOf().toString();const s="point";return i.name=(n==null?void 0:n.name)||`${s}_${o.format()}`,i.shape="point",x.info("[%s] draw point with %j",n==null?void 0:n.requestId,i),h.point([e,t],i)}static parseCircle(t,e={}){var i,o;x.info("[%s] parse circle with %j",e==null?void 0:e.requestId,t.properties);const n=t.properties||{};if(n.shape=="circle"){const s=b.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const r=n==null?void 0:n.id,c=((i=n==null?void 0:n.center)==null?void 0:i.length)==2?h.point(n.center):h.centroid(t);let a="center";c.properties={id:`${a}_${r}`,parentId:r,name:a};const u=(n==null?void 0:n.units)||"nauticalmiles";let l=n==null?void 0:n.radius;if(!l){const m=h.polygonToLine(t);l=h.pointToLineDistance(c,m,{units:u})}a="end";const g=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?h.point(n.end):h.destination(c,l,90,{units:u});g.properties={id:`${a}_${r}`,parentId:r,name:a,radius:l,units:u};const f=h.lineString([c.geometry.coordinates,g.geometry.coordinates]);return a="edge",f.properties={id:`${a}_${r}`,parentId:r,name:a,radius:l,units:u},h.featureCollection([c,g,f,t])}else return x.warn("[%s] not a orm-std circle, just return the original feature",e==null?void 0:e.requestId),h.featureCollection([t])}static parseRect(t,e={}){x.info("[%s] parse rect with %j",e==null?void 0:e.requestId,t.properties);const n=t.properties||{};if(n.shape=="rect"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,s=t.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,u)=>{const l=h.point(s[u]);return l.properties={id:`${a}_${o}`,parentId:o,name:a},l});return h.featureCollection([...c,t])}else return x.warn("[%s] not a orm-std rect, just return the original feature",e==null?void 0:e.requestId),h.featureCollection([t])}static parseLine(t,e={}){x.info("[%s] parse line with %j",e==null?void 0:e.requestId,t.properties);const n=t.properties||{};if(n.shape=="line"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,r=t.geometry.coordinates.map((c,a)=>{const u=`point_${a}`,l=h.point(c);return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return h.featureCollection([...r,t])}else return x.warn("[%s] not a orm-std line, just return the original feature",e==null?void 0:e.requestId),h.featureCollection([t])}static parsePolygon(t,e={}){x.info("[%s] parse polygon with %j",e==null?void 0:e.requestId,t.properties);const n=t.properties||{};if(n.shape=="polygon"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,r=t.geometry.coordinates[0].map((c,a)=>{const u=h.point(c),l=`corner_${a}`;return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return h.featureCollection([...r,t])}else return x.warn("[%s] not a orm-std polygon, just return the original feature",e==null?void 0:e.requestId),h.featureCollection([t])}static _inflateRawSync(t){var e;if(typeof process<"u"&&((e=process.versions)!=null&&e.node)){const n=require("zlib");return new Uint8Array(n.inflateRawSync(Buffer.from(t)))}throw new Error("Sync inflate is not supported in browser; use the async convertKMZ2GeoJSONAsync / convertZIP2GeoJSONAsync instead")}static async _parseZipEntries(t){var c;const e=new Uint8Array(t),n=e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),i=new DataView(n),o=new Uint8Array(n),s=new Map;let r=0;for(;r+4<=n.byteLength&&i.getUint32(r,!0)===67324752;){const u=i.getUint16(r+8,!0),l=i.getUint32(r+18,!0),g=i.getUint16(r+26,!0),f=i.getUint16(r+28,!0),m=o.slice(r+30,r+30+g),T=new TextDecoder().decode(m),p=r+30+g+f,y=o.slice(p,p+l);if(u===0)s.set(T,y);else if(u===8){if(typeof DecompressionStream<"u"){const P=new DecompressionStream("deflate-raw"),M=P.writable.getWriter(),S=P.readable.getReader();M.write(y),M.close();const N=[];let $=0;for(;;){const{done:F,value:B}=await S.read();if(F)break;N.push(B),$+=B.length}const E=new Uint8Array($);let k=0;for(const F of N)E.set(F,k),k+=F.length;s.set(T,E)}else if(typeof process<"u"&&((c=process.versions)!=null&&c.node))try{s.set(T,O._inflateRawSync(y))}catch{}}r=p+l}return s}static async convertKML2GeoJSON(t,e={}){var r,c;x.info("[%s] convert kml to geojson",e==null?void 0:e.requestId);const i=z().parseFromString(t,"application/xml"),o=Array.from(i.querySelectorAll("Placemark")),s=[];for(const a of o){const u={},l=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const S of l){const N=S.getAttribute("name"),$=(c=(r=S.querySelector("value"))==null?void 0:r.textContent)==null?void 0:c.trim();N&&$!==void 0&&$!==null&&(u[N]=$)}const g=b.utc(),f=Object.keys(u).find(S=>S.toLowerCase().indexOf("name")!==-1),m=f?u[f]:void 0,T=`${g.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,p=S=>S.trim().split(/[\s\n]+/).filter(N=>N.length>0).map(N=>{const $=N.split(",").map(Number);return[$[0],$[1]]}),y=a.querySelector("LineString > coordinates");if(y){const S=p(y.textContent||"");if(S.length>=2){const N=h.lineString(S,{...u,shape:"line",id:T,name:m});s.push(N)}continue}const P=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(P){const S=p(P.textContent||"");if(S.length>=4){const N=S[0][0]===S[S.length-1][0]&&S[0][1]===S[S.length-1][1]?S:[...S,S[0]],$=h.polygon([N],{...u,shape:"polygon",id:T,name:m});s.push($)}continue}const M=a.querySelector("Point > coordinates");if(M){const S=p(M.textContent||"");if(S.length>=1){const N=h.point(S[0],{...u,shape:"point",id:T,name:m});s.push(N)}continue}}return h.featureCollection(s)}static async convertKMZ2GeoJSON(t,e={}){var s;x.info("[%s] convert kmz to geojson (async)",e==null?void 0:e.requestId),Buffer.isBuffer(t)&&(t=O.toArrayBuffer(t));const n=await O._parseZipEntries(t),i=n.get("doc.kml")??((s=[...n.entries()].find(([r])=>r.toLowerCase().endsWith(".kml")))==null?void 0:s[1]);if(!i)return x.warn("[%s] no .kml file found in kmz",e==null?void 0:e.requestId),h.featureCollection([]);const o=new TextDecoder().decode(i);return O.convertKML2GeoJSON(o,e)}static async convertZIP2GeoJSON(t,e={}){x.info("[%s] convert zip to geojson (async)",e==null?void 0:e.requestId),Buffer.isBuffer(t)&&(t=O.toArrayBuffer(t));const n=await O._parseZipEntries(t),i=[];for(const[o,s]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const r=new TextDecoder().decode(s),c=await O.convertKML2GeoJSON(r,e);i.push(...c.features)}return i.length===0?(x.warn("[%s] no .kml files found in zip",e==null?void 0:e.requestId),this.convertSHP2GeoJSON(t,e)):h.featureCollection(i)}static async convertSHP2GeoJSON(t,e={}){x.info("[%s] convert shp zip to geojson",e==null?void 0:e.requestId);try{Buffer.isBuffer(t)&&(t=O.toArrayBuffer(t));const n=await W(t);if(Array.isArray(n)){const i=n.flatMap(c=>c.features||[]),o=b.utc(),s=(e==null?void 0:e.id)||o.valueOf().toString(),r={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return i.forEach((c,a)=>{var m;const u=((m=c.geometry)==null?void 0:m.type)||"",l=r[u]||u.toLowerCase();c.properties=c.properties||{},c.properties.shape=l,c.properties.parentId=s,c.properties.id=`${s}_${a}`;const g=Object.keys(c.properties).find(T=>T.toLowerCase().indexOf("name")!==-1),f=g?c.properties[g]:void 0;c.properties.name=f||`${l}_${o.format()}_${a}`}),h.featureCollection(i)}return n}catch(n){return x.warn("[%s] failed to convert shp zip: %s",e==null?void 0:e.requestId,n),h.featureCollection([])}}}D.AisHelper=j,D.GeoJsonHelper=O,D.LaneHelper=v,D.LngLatHelper=d,D.TropicalHelper=L,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function($,I){typeof exports=="object"&&typeof module<"u"?I(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"],I):($=typeof globalThis<"u"?globalThis:$||self,I($["idm-plugin-rabbitmq"]={},$["@turf/turf"],$.moment,$["@log4js-node/log4js-api"],$["moment-timezone"],$["tz-lookup"],$.shpjs))})(this,function($,I,b,F,J,U,L){"use strict";function z(C){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(C){for(const t in C)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(C,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>C[t]})}}return e.default=C,Object.freeze(e)}const h=z(I);class d{static guessTimeZoneOffset(e,t){e=d.convertToStdLng(e);const n=U(t,e),i=b().tz(n).utcOffset();return d.roundPrecision(i/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 i="E";e<0&&(i="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,s,c,a,u,l;r=o%3600%60,n.indexOf("S")!==-1&&(o=o-r,s=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),u=o/3600,n.indexOf("M")!==-1?l=d.roundPrecision(u,t).toString().padStart(3,"0"):l=d.padNumber(u,3,6),Number(s)>=60&&(a=Number(a)+1,s=0),Number(a)>=60&&(l=Number(l)+1,a=0);const g=`${n.replace(/S+/gi,s).replace(/M+/gi,a).replace(/H+/gi,l)}${i}`;return{direction:i,degree:d.roundPrecision(u,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:s,M:a,H:l}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let i="N";e<0&&(i="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,s,c,a,u,l;r=o%3600%60,n.indexOf("S")!==-1&&(o=o-r,s=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),u=o/3600,n.indexOf("M")!==-1?l=d.roundPrecision(u,t).toString().padStart(2,"0"):l=d.padNumber(u,2,6),Number(s)>=60&&(a=Number(a)+1,s=0),Number(a)>=60&&(l=Number(l)+1,a=0);const g=`${n.replace(/S+/gi,s).replace(/M+/gi,a).replace(/H+/gi,l)}${i}`;return{direction:i,degree:d.roundPrecision(u,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:s,M:a,H:l}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LNG");const i=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,s,c]=o;if(s=s||0,s=s>60?s/Math.pow(10,String(s).length-2):s,c=c||0,c=c>60?c/Math.pow(10,String(c).length-2):c,r>360&&!s){const a=this.roundPrecision(r/100,0);s=r-a*100,r=a}n=r+s/60+c/3600,i==="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 i=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,s,c]=o;if(c=c||0,s=s||0,s=s>60?s/Math.pow(10,String(s).length-2):s,c=c>60?c/Math.pow(10,String(c).length-2):c,r>90&&!s){const a=this.roundPrecision(r/100,0);s=r-a*100,r=a}if(n=r+s/60+c/3600,n>90)throw new Error(`latitude out of range: ${e}${i}`);i==="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 i=e[e.length-1].toUpperCase();return["N","S"].includes(i)?{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 i=e,o=Number(i.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${i}E`:o<=-90?e=`${i}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${i}${o>0?"E":"W"}`:e=`${i}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const i=d.roundPrecision(e-Math.trunc(e),n),o=i>=1?Math.trunc(e+1).toString().padStart(t,"0"):Math.trunc(e).toString().padStart(t,"0");return i>=1?o:n>0?`${o}.${Math.trunc(i*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class B{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,i,o,r,s,c,a,u,l,g]=e.split("|");return{lat:Number(t),lng:Number(n),positionTime:Number(i),sog:Number(o),cog:Number(r),hdg:Number(s),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:u?JSON.parse(u):void 0,vendor:l,deleted:g==="true"}}static inspectStoppages(e,t=1,n=!0){const i=e.at(0).positionTime<e.at(-1).positionTime;i||e.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let r,s;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 u=c+1;u<e.length;u++){const l=e[u-1],g=e[u];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const f=g.positionTime-l.positionTime;if(y.calculateDistance(g,l,!0,4)/(f/3600)<t)r||(r=a),u===e.length-1&&(s=g,c=u);else{r&&(s=e[u-1],c=u);break}}if((s==null?void 0:s.positionTime)>(r==null?void 0:r.positionTime)&&r){const u={start:{lat:r.lat,lng:r.lng,sog:r.sog,positionTime:r.positionTime,utc:b.unix(r.positionTime).utc().format()},end:{lat:s.lat,lng:s.lng,sog:s.sog,positionTime:s.positionTime,utc:b.unix(s.positionTime).utc().format()},duration:s.positionTime-r.positionTime},l=e.filter(f=>f.positionTime>=u.start.positionTime&&f.positionTime<=u.end.positionTime),g=y.divideAccordingToLng(l);u.distance=y.calculateRouteDistance(g),u.hours=Math.round(u.duration/3600*10)/10,u.avgSog=Math.round(u.distance/u.hours*10)/10,o.push(u)}r=void 0,s=void 0}}return i||e.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(e,t,n){const i=b(t),o=b(n),r=e.filter(u=>u.positionTime>=i.unix()&&u.positionTime<=o.unix());let s=0,c=0;if(r.length>1)for(let u=0;u<r.length-1;u++){const l=r[u],g=r[u+1];s+=y.calculateDistance(l,g,!0,4),c+=Math.abs(g.positionTime-l.positionTime)}s=Math.round(s*100)/100,c=Math.round(c/3600*100)/100;const a=c?Math.round(s/c*100)/100:0;return{distance:s,interval:c,avgSpd:a}}}let A;try{A=F.getLogger("meteo")}catch{}finally{}class y{static calculateBearing(e,t,n=!0,i=4){const o=h.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=h.rhumbBearing(o.features[0],o.features[1]):r=h.bearing(o.features[0],o.features[1]),r<0&&(r+=360),d.roundPrecision(r,i)}static calculateDistance(e,t,n=!0,i=4,o="nauticalmiles"){e={...e},t={...t},e.lng=d.convertToStdLng(e.lng,i),t.lng=d.convertToStdLng(t.lng,i);const r=h.points([[e.lng,e.lat],[t.lng,t.lat]]);let s;return n?s=h.rhumbDistance(r.features[0],r.features[1],{units:o}):s=h.distance(r.features[0],r.features[1],{units:o}),d.roundPrecision(s,i)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let i=0,o;for(const r of e)for(let s=0;s<r.length-1;s++){const c={lng:r[s][0],lat:r[s][1]};s===0&&o&&(i+=this.calculateDistance(o,c,!0,t,n));const a={lng:r[s+1][0],lat:r[s+1][1]};i+=this.calculateDistance(c,a,!0,t,n),o=a}return d.roundPrecision(i,t)}static calculateCoordinate(e,t,n,i="nauticalmiles",o=!0){const r=h.point([e.lng,e.lat]);let s;o?s=h.rhumbDestination(r,n,t,{units:i}):s=h.destination(r,n,t,{units:i});const c=s.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,i=!0,o=!0,r="nauticalmiles"){const s=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,r);i&&s.push({lng:e.lng,lat:e.lat});let u=0;for(;u<a;)u+=n,u<a&&s.push(this.calculateCoordinate(e,c,u,r,!1));return o&&s.push({lng:t.lng,lat:t.lat}),s}static divideAccordingToLng(e,t=!1,n=!0){if((e==null?void 0:e.length)<2)return[];e=n?this.deduplicateCoordinates(e):e;let i=[];const o=[];let r,s;for(let c=0;c<e.length-1;c++){r=d.convertToStdLng(e[c].lng,8),s=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),i.push([r,e[c].lat]);const a=r-s;if(Math.abs(a)>180){const u=d.convertToMonotonicLng2([[r,e[c].lat],[s,e[c+1].lat]]);let l,g;t?(l=h.lineString(u),g=h.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(l=h.greatCircle(u[0],u[1]),g=h.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const f=h.lineIntersect(l,g);let T;if(f.features.length){const S=h.getCoord(f.features[0]);T=d.roundPrecision(S[1],8)}else T=e[c].lat;a>0?(i.push([180-1e-6,T]),o.push([...i]),i=[],i.push([-(180-1e-6),T])):(i.push([-(180-1e-6),T]),o.push([...i]),i=[],i.push([180-1e-6,T]))}c===e.length-2&&i.push([s,e[c+1].lat])}return o.push(i),o}static deduplicateRoute(e){const t=[];for(const n of e){const i=n.reduce((o,r)=>(o.findIndex(s=>s[0]===r[0]&&s[1]===r[1])===-1&&o.push(r),o),[]);t.push(i)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(i=>i.lat===n.lat&&i.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 i=n.length-1;i>=0;i--)d.roundPrecision(n[i][0],8)===e.lng&&d.roundPrecision(n[i][1],8)===d.roundPrecision(e.lat,8)&&n.splice(i,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,i=0,o=0,r,s;return t.forEach((c,a)=>{for(let u=0;u<c.length-1;u++){const l={lng:c[u][0],lat:c[u][1]},g={lng:c[u+1][0],lat:c[u+1][1]},f=this.calculatePointToLineDistance(e,l,g);n>f&&(n=f,o=u,i=a,r=this.calculateDistance(l,e),s=this.calculateDistance(g,e))}}),r!==0&&s!==0?t[i].splice(o+1,0,[e.lng,e.lat]):r===0?t[i].splice(o,1,[e.lng,e.lat]):s===0&&t[i].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);const n=y.convertRouteToCoordinates(t);return n.push(e),y.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=y.convertRouteToCoordinates(t);return n.unshift(e),y.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 i=[];let o=0;return n.forEach(r=>{if(o===2)return;const s=[];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)){s.push(c),o===0&&s.push([e.lng,e.lat]),o=2;break}o===1?s.push(c):d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)&&(o=1,s.push(c))}s.length&&i.push(s)}),i}static calculateRangeWaypoints(e,t,n,i=[]){const o=this.convertRouteToCoordinates(n,0),r=this.mergeCoordinatesToWaypoints([e,t],o.length?o:i),s=r.findIndex(u=>d.roundPrecision(e.lng,8)===d.roundPrecision(u.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(u.lat,8)),c=r.findIndex(u=>d.roundPrecision(t.lng,8)===d.roundPrecision(u.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(u.lat,8));return r.filter((u,l)=>l>=s&&l<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,i=0,o=0;return t.forEach((r,s)=>{for(let c=0;c<r.length-1;c++){const a={lng:r[c][0],lat:r[c][1]},u={lng:r[c+1][0],lat:r[c+1][1]},l=this.calculatePointToLineDistance(e,a,u);n>l&&(n=l,i=c,o=s)}}),{minDist:n,segIndex:o,minIndex:i}}static calculateSubRoute(e,t){const n=y.convertRouteToCoordinates(t);y.mergeCoordinateToWaypoints(e,n,!0),t=y.divideAccordingToLng(n);const{segIndex:i,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=d.convertToStdLng(e.lng);const r=[];let s=!0;for(let c=i;c<t.length;c++)if(s){const a=[];a.push([e.lng,e.lat]);for(let u=o+1;u<t[c].length;u++)e.lng===t[c][u][0]&&e.lat===t[c][u][1]||a.push(t[c][u]);r.push(a),s=!1}else r.push([...t[c]]);return r}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,i=0;for(let r=0;r<t.length-1;r++){const s=t[r],c=t[r+1];if(this.calculateDistance(e,s)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((u,l)=>l>0);const a=this.calculatePointToLineDistance(e,s,c);n>a&&(n=a,i=r)}e.lng=d.convertToStdLng(e.lng);const o=[e];for(let r=i+1;r<t.length;r++)o.push(t[r]);return o}static calculatePointToLineDistance(e,t,n,i={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=h.lineString([[t.lng,t.lat],[n.lng,n.lat]]),s=h.pointToLineDistance(h.point([e.lng,e.lat]),r,i),c=h.pointToLineDistance(h.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),r,i);return d.roundPrecision(Math.min(s,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const i=e[n],o=e[n+1],r=this.calculateRangeRoute(i,o,t);n===0&&(i.distanceFromPrevious=0,i.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(r),o.distanceFromStart=d.roundPrecision((i.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const i of e)this.mergeCoordinateToWaypoints(i,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=d.convertToStdLng(e.lng,8);let i=Number.MAX_VALUE,o=0,r=0,s=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},u={lng:t[c+1].lng,lat:t[c+1].lat},l=this.calculatePointToLineDistance(e,a,u);i>=l&&(i=l,o=c,r=this.calculateDistance(a,e,!1,6),s=this.calculateDistance(u,e,!1,6))}r!==0&&s!==0?r<=i&&o===0?t.unshift(e):s<=i&&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):s===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 u=t[a+1];if(u&&((c.bearing===null||c.bearing===void 0)&&((c.positionTime||0)>(u.positionTime||0)?c.bearing=this.calculateBearing(u,c,!0):c.bearing=this.calculateBearing(c,u,!0)),c.cog=c.cog||c.bearing,!c.sog&&c.positionTime&&u.positionTime)){const l=this.calculateDistance(c,u,!0),g=Math.abs(u.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(l/g,2)}return c})}static generateRouteAccordingToWaypoints(e,t=!0,n=!0){const i=[];for(let o=1;o<e.length;o++){const r=e[o-1],s=e[o];if(o===1&&i.push(r),s.gcToPrevious){const c=this.interpolateCoordinates(r,s,200,!1,!0,"nauticalmiles");i.push(...c)}else i.push(s)}return this.divideAccordingToLng(i,t,n)}static nearestCoordinateInRoute(e,t){const n=h.point([e.lng,e.lat]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),r=h.lineString(o),s=h.nearestPointOnLine(r,n),c=h.getCoord(s);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 i=0;i<t.length-1;i++){const o=t[i],r=t[i+1];if(this.calculateDistance(e,o)===0){n=i;break}if(this.calculateDistance(e,r)===0){n=i+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,i="nauticalmiles"){var g;const o=e.speed||12,r=[];let s=[],c=!1,a=0,u=0,l;if(t&&n.length?(r.push(e),n.forEach((f,T)=>{if(c)s.push(f);else{const S=[];let p;for(let v=0;v<f.length;v++)if(l)S.push(f[v]);else{p={lng:f[v][0],lat:f[v][1]};const P=this.calculateDistance(e,p,!0,8,i);if(a+=P,a<t)u+=P,P&&r.push(p),e=p;else{if(u=t,a===t)l=p,S.push([l.lng,l.lat]);else{const M=a-t,m=this.calculateBearing(p,e);l=this.calculateCoordinate(p,m,M,i),S.push([l.lng,l.lat]),S.push([p.lng,p.lat])}c=!0}}S.length&&s.push(S),T===n.length-1&&!l&&(l=p)}})):(s=n,l={...e}),l)if(r.push(l),l.distanceFromPrevious=Math.round(u*1e4)/1e4,l.hourFromPrevious=Math.round(u/o*1e4)/1e4,((g=s[0])==null?void 0:g.length)>1){const f={lng:s[0][1][0],lat:s[0][1][1]};l.bearing=this.calculateBearing(l,f)}else l.bearing=0;return{coordinate:l,nextRoute:s,prevRoute:r}}static nearestCoordinateInLine(e,t,n){const i=d.convertToStdLng(e.lng,6),o=h.point([i,e.lat]),r=d.convertToStdLng(t.lng,6),s=d.convertToStdLng(n.lng,6),c=h.lineString([[r,t.lat],[s,n.lat]]),a=h.nearestPointOnLine(c,o),u=h.getCoord(a),l=d.roundPrecision(u[0],6),g=d.roundPrecision(u[1],6);return{lng:l,lat:g,inline:!(l===r&&g===t.lat)&&!(l===s&&g===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let i,o;return e.forEach(r=>{r.forEach(s=>{const c={lng:d.roundPrecision(s[0],8),lat:d.roundPrecision(s[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(i,c,!0);a&&a>=t&&(i.bearing=this.calculateBearing(i,c,!0),n.push(i),o=i)}i=c})}),i&&n.push(i),n}static simplifyRouteToCoordinates(e,t,n=1){let i=this.convertRouteToCoordinates(e,n);return i=this.simplifyGCCoordinates(i,t),i}static simplifyGCCoordinates(e,t){t.forEach(i=>{this.mergeCoordinateToWaypoints(i,e,!0)});for(let i=1;i<t.length;i++){const o=t[i-1],r=t[i];if(r.gcToPrevious){const s=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>s;a--)e.splice(a,1)}}let n=0;for(let i=1;i<e.length;i++){const o=e[i-1],r=e[i];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(i=>(i.lng=d.convertToStdLng(i.lng),i))}static calculateCenter(e){const t=[];for(const s of e)for(const c of s)t.push(c);const n=h.featureCollection([]),i=d.convertToMonotonicLng2(t);for(const s of i)n.features.push(h.point(s));const r=h.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),i=h.lineString(n);return h.bbox(i)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}static simplifyCoordinates(e,t=1,n=180){const i=[];for(let o=1;o<e.length;o++){const r=e[o-1],s=e[o],c=e[o+1];let a=!1,u=!1;if((r.velocity||r.suspend||r.important||r.pilot||o===1)&&(a=!0,i.push(r)),s.gcToPrevious&&(a||(a=!0,i.push(r)),u=!0,i.push(s),o++),c){const l=y.calculateDistance(r,s,!0),g=y.calculateDistance(s,c,!0),f=y.calculateDistance(r,c,!0),T=(Math.pow(l,2)+Math.pow(g,2)-Math.pow(f,2))/(2*l*g);Math.round(Math.acos(T)*180/Math.PI)<n&&f>t&&!u&&(i.push(s),o++)}if(o>=e.length-1){const l=e.at(-1);l&&i.push(l)}}return i}static nearestTSPointInWaypoints(e,t,n){const i=b.unix(e),o=n.filter(r=>i.clone().subtract(t,"hour").unix()<=(r.positionTime||0)&&i.clone().add(t,"h").unix()>=(r.positionTime||0));return o.sort((r,s)=>(r.positionTime||0)-(s.positionTime||0)),o.at(-1)}static deadReckoning(e,t){var o,r,s,c;e>1e12&&(e=Math.round(e/1e3));const n=b.unix(e);let i=t.find(a=>a.positionTime===n.unix());if(!i){const a=(r=(o=t.filter(l=>(l==null?void 0:l.positionTime)<n.unix()))==null?void 0:o.sort((l,g)=>(l.positionTime||0)-(g.positionTime||0)))==null?void 0:r.at(-1),u=(c=(s=t.filter(l=>(l==null?void 0:l.positionTime)>n.unix()))==null?void 0:s.sort((l,g)=>(l.positionTime||0)-(g.positionTime||0)))==null?void 0:c.at(0);if(a&&u){const l=y.calculateBearing(a,u,!0),g=y.calculateDistance(a,u),f=(n.unix()-a.positionTime)/(u.positionTime-a.positionTime);i=y.calculateCoordinate(a,l,g*f),i.positionTime=n.unix(),i.utc=n.utc().format(),i.cog=l,i.sog=Math.round(g/((u.positionTime-a.positionTime)/3600)*100)/100}else i=a||u,i&&(i.utc=b.unix(i==null?void 0:i.positionTime).utc().format())}return i}static deadReckoningTime(e,t){t=JSON.parse(JSON.stringify(t)),t.sort((a,u)=>(a.positionTime||0)-(u.positionTime||0));let n=Number.MAX_SAFE_INTEGER,i=Number.MAX_SAFE_INTEGER;for(let a=0;a<t.length-1;a++){const u=t[a],l=t[a+1],g=y.calculatePointToLineDistance(e,u,l);g<n&&(n=g,i=a)}const o=t[i],r=t[i+1],s=y.calculateDistance(o,e),c=y.calculateDistance(r,e);if(s===0)e=o;else if(c===0)e=r;else{const a=o.positionTime||0,u=r.positionTime||0,l=y.calculateDistance(o,r);e.positionTime=Math.round(a+(u-a)*(s/l))}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 i=[];return i.push('<?xml version="1.0" encoding="UTF-8"?>'),i.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),i.push(` <routeInfo routeName="${y.xmlEscape(e)}"></routeInfo>`),i.push(...y.toRTZWaypoints(t,6)),i.push("</route>"),i.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="${y.xmlEscape(e)}"></routeInfo>`),o.push(...y.toRTZWaypoints(t,6,n)),o.push("</route>"),o.join(`
|
|
3
|
+
`)}static toRTZWaypoints(e,t=6,n=!0){const i=[];i.push(" <waypoints>");for(let o=0;o<e.length;o++){const r=e[o],s=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,u=[`id="${s}"`,'revision="0"'];if(r.name&&u.push(`name="${y.xmlEscape(r.name)}"`),i.push(` <waypoint ${u.join(" ")}>`),i.push(` <position lat="${y.xmlEscape(c)}" lon="${y.xmlEscape(a)}" />`),o>0){const l=r.gcToPrevious?"Orthodrome":"Loxodrome";i.push(` <leg geometryType="${l}" />`)}if(n){const l=[];if(r.description&&l.push(` <description>${y.xmlEscape(r.description)}</description>`),r.utc)l.push(` <time>${y.xmlEscape(r.utc)}</time>`);else if(r.positionTime)try{l.push(` <time>${y.xmlEscape(b.unix(r.positionTime).utc().format())}</time>`)}catch{}r.cog!==void 0&&l.push(` <cog>${y.xmlEscape(r.cog)}</cog>`),r.sog!==void 0&&l.push(` <sog>${y.xmlEscape(r.sog)}</sog>`),l.length&&(i.push(" <extensions>"),i.push(...l),i.push(" </extensions>"))}i.push(" </waypoint>")}return i.push(" </waypoints>"),i}static waypoints2CSV(e,t,n){A.debug("keep name for waypoints2CSV for legacy compatibility only",e);const i=(n==null?void 0:n.precision)??6,o=t.some(p=>p.name),r=t.some(p=>p.description),s=t.some(p=>p.port!=null),c=t.some(p=>p.stbd!=null),a=t.some(p=>p.arrRad!=null),u=t.some(p=>p.speed!=null),l=t.some((p,v)=>v>0&&p.gcToPrevious!=null),g=t.some(p=>p.bearing!=null),f=t.some(p=>p.distanceFromPrevious!=null),T=["WPT No.","Latitude","Longitude"];o&&T.push("Name"),r&&T.push("Description"),l&&T.push("Leg"),g&&T.push("Bearing[deg]"),f&&T.push("Distance[NM]"),u&&T.push("Speed[kn]"),s&&T.push("PORT XTD[NM]"),c&&T.push("STBD XTD[NM]"),a&&T.push("Arr.Rad[NM]");const S=[];S.push(T.map(p=>y.csvEscapeField(p)).join(","));for(let p=0;p<t.length;p++){const v=t[p],P=[];P.push((p+1).toString()),P.push(v.lat.toFixed(i)),P.push(v.lng.toFixed(i)),o&&P.push(v.name??""),r&&P.push(v.description??""),l&&P.push(p===0?"":v.gcToPrevious?"GC":"RL"),g&&P.push(v.bearing!=null?String(v.bearing):""),f&&P.push(v.distanceFromPrevious!=null?String(v.distanceFromPrevious):""),u&&P.push(v.speed!=null?String(v.speed):""),s&&P.push(v.port!=null?String(v.port):""),c&&P.push(v.stbd!=null?String(v.stbd):""),a&&P.push(v.arrRad!=null?String(v.arrRad):""),S.push(P.map(M=>y.csvEscapeField(M)).join(","))}return S.join(`
|
|
4
|
+
`)}static csvEscapeField(e){if(e==null)return"";const t=String(e);return t.includes(",")||t.includes('"')||t.includes(`
|
|
5
|
+
`)||t.includes("\r")?`"${t.replace(/"/g,'""')}"`:t}static decimalToNmeaDm(e,t){const n=Math.abs(e),i=Math.floor(n),o=(n-i)*60,r=t?`${i.toString().padStart(2,"0")}${o.toFixed(2).padStart(5,"0")}`:`${i.toString().padStart(3,"0")}${o.toFixed(2).padStart(5,"0")}`,s=t?e>=0?"N":"S":e>=0?"E":"W";return{dm:r,dir:s}}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 i=e[n],o=y.decimalToNmeaDm(i.lat,!0),r=y.decimalToNmeaDm(i.lng,!1),s=i.name?String(i.name).slice(0,6):`WPT${(n+1).toString().padStart(3,"0")}`,c=`GPWPL,${o.dm},${o.dir},${r.dm},${r.dir},${s}`,a=y.nmeaChecksum(c);t.push(`$${c}*${a}`)}return t.join(`\r
|
|
6
|
+
`)}static coordinatesSummary(e,t=3){if(e.length>1){const n=e[0],i=e[e.length-1],o=(n==null?void 0:n.positionTime)<(i==null?void 0:i.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(i==null?void 0:i.positionTime),r=(n==null?void 0:n.positionTime)>(i==null?void 0:i.positionTime)?b.unix(n==null?void 0:n.positionTime):b.unix(i==null?void 0:i.positionTime),s=Math.round(r.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(e,!0,!0),a=this.calculateRouteDistance(c),l=B.inspectStoppages(e,t).reduce((f,T)=>(f.duration+=T.duration,f.distance+=T.distance,f),{hours:0,distance:0,spd:0,duration:0});l.hours=Math.round(l.duration/3600*100)/100,l.distance=Math.round(l.distance*100)/100,l.spd=l.hours?Math.round(l.distance/l.hours*100)/100:0;const g=s?Math.round((a-l.distance)/(s-l.hours)*100)/100:0;return{begin:o.utc().format(),end:r.utc().format(),distance:Math.round((a-l.distance)*100)/100,hours:Math.round((s-l.hours)*100)/100,avgSpeed:g,stoppage:l}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(e,t){var u,l,g;if(!((l=(u=t==null?void 0:t.sample)==null?void 0:u.hours)!=null&&l.length))return{routes:[],hour:void 0};const n=t.sample.hours.at(0),i=b.utc(e),o=b.utc(t.eta),r=i.isAfter(o)?o:i;let s=t.sample.all.find(f=>f.eta===r.format());if(!s){const f=t.sample.all.filter(N=>b.utc(N.eta).isBefore(r)).at(-1),T=this.calculateSubRoute(f,t.route);s=(g=this.calculateNextCoordinateAlongRoute(f,f.speed*r.diff(b(f.etd),"hours",!0),T))==null?void 0:g.coordinate;const{cFactor:S,cog:p,wxFactor:v,meteo:P}=f,M=Math.round(s.distanceFromPrevious*1e4)/1e4,m=Math.round((M+f.distanceFromStart)*1e4)/1e4;s={...s,cFactor:S,cog:p,speed:f.speed,wxFactor:v,distanceFromStart:m,distanceFromPrevious:M,meteo:P,eta:r.format(),etd:r.format()}}s.distanceToGo=Math.round((t.distance-s.distanceFromStart)*100)/100,s.timeToGo=Math.round(o.diff(s.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,s,t.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:s}}static pickUTCSampleFromRoute(e,t,n){var f;const i=this.calculateSubRoute(t,n),o=this.calculateRouteDistance(i),r=o/t.speed,s=b.utc(e),c=b(t.etd),a=(f=this.calculateNextCoordinateAlongRoute(t,t.speed*s.diff(b(t.etd),"hours",!0),i))==null?void 0:f.coordinate;a.speed=t.speed;const u=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(u.diff(s,"second"))<2?s.format():u.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(b(a.etd),"hour")*100)/100;const l=this.calculateRangeWaypoints(t,a,n);return{routes:this.generateRouteAccordingToWaypoints(l),hour:a}}static includedAngle(e,t){A==null||A.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 D;try{D=F.getLogger("vessel")}catch{}finally{}class Z{static convert2Geojson(e){var n,i,o;const t=h.featureCollection([]);for(const r of e){const s=(n=r.history)==null?void 0:n[0];if(r.forecasts){s&&s.wind&&(s.wind.kts=s.kts);for(const c of r.forecasts){let a;const u=[],l=[],g=b(c.date).utc(),f=`${r.name}-${c.model}`;for(const S in c==null?void 0:c.hours){const p=c.hours[S];a=a||p;const v=g.clone().add(Number(S),"hour"),P=h.point([p.lng,p.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:v.format(),hour:Number(S),format:v.format("MMM-DD/HHmm[Z]"),pressure:p.pressure>1e4?d.roundPrecision(p.pressure/100,0):d.roundPrecision(p.pressure,0),gusts:p.gusts,wind:p.wind||{},movement:p.movement,category:f,type:"forecast"});l.push(P),u.push(P.geometry.coordinates)}const T={kts:void 0,deg:void 0};if(s){const S=b(s.updated).utc();if(a){const v=y.calculateDistance(s,a),P=b(a.utc||a.updated).diff(S,"h",!0);T.kts=Math.round(v/P*100)/100,T.deg=y.calculateBearing(s,a,!0,0)}const p=h.point([s.lng,s.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:S.format(),hour:0,format:S.format("MMM-DD/HHmm[Z]"),pressure:s.pressure>1e4?d.roundPrecision((s==null?void 0:s.pressure)/100,0):d.roundPrecision(s.pressure,0),wind:s.wind,movement:T,category:f,type:"forecast",important:!0});l.unshift(p),u.unshift(p.geometry.coordinates)}if(t.features.push(...l),(u==null?void 0:u.length)>1){const S=h.lineString(d.convertToMonotonicLng2(u),{date:(s==null?void 0:s.updated)||(g==null?void 0:g.format()),id:r.id||r.name,model:c.model,name:r.name,category:f,type:"forecast",movement:T});t.features.push(S)}}}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),(i=r.history)!=null&&i.length){const c=[],a=b(s==null?void 0:s.updated).utc(),u=b((o=r.history)==null?void 0:o.at(-1).updated).utc(),l=a.diff(u,"h")%24>2?24:12;for(const g of r.history){const f=b(g.updated).utc(),T=f.isSameOrBefore(a)||f.isSame(u);T&&a.add(-l,"h");const S=h.point([g.lng,g.lat],{name:r.name,nameCn:r.nameCn,date:f.format(),format:f.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:T});t.features.push(S),c.push(S.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const g=h.lineString(d.convertToMonotonicLng2(c),{name:r.name,type:"history",updated:s==null?void 0:s.updated,pressure:(s==null?void 0:s.pressure)>1e4?d.roundPrecision((s==null?void 0:s.pressure)/100,0):d.roundPrecision(s==null?void 0:s.pressure,0),kts:s==null?void 0:s.kts,level:s==null?void 0:s.type});t.features.push(g)}}}return t}static interpolate(e,t=3){var o,r,s,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"),i=[];for(const a of n){const u=a.properties.name,l=a.properties.model,g=a.properties.showCircle,f=a.properties.disabled,T=b(a.properties.date).utc();let S=t*60;const p=(r=e==null?void 0:e.data)==null?void 0:r.features.filter(M=>M.geometry.type==="Point"&&M.properties.type==="forecast"&&M.properties.category===`${u}-${l}`);let v,P=T.clone().add(S,"minute").set({minute:0,second:0,millisecond:0});for(;v=this.pickIndex(p,P),v<=p.length-1;){if(v>0){const M=p[v],m=v===0?void 0:p[v-1],N=(S/60-((s=m==null?void 0:m.properties)==null?void 0:s.hour))/(M.properties.hour-((c=m==null?void 0:m.properties)==null?void 0:c.hour)),R=this.computeNumber(m==null?void 0:m.geometry.coordinates[0],M.geometry.coordinates[0],N),E=this.computeNumber(m==null?void 0:m.geometry.coordinates[1],M.geometry.coordinates[1],N),k=h.point([R,E],{name:u,model:l,category:M==null?void 0:M.properties.category,date:P.format(),format:P.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(m==null?void 0:m.properties.gusts,M.properties.gusts,N),hour:this.computeNumber(m==null?void 0:m.properties.hour,M.properties.hour,N),movement:this.computeNumber(m==null?void 0:m.properties.movement,M.properties.movement,N),pressure:this.computeNumber(m==null?void 0:m.properties.pressure,M.properties.pressure,N),wind:this.computeNumber(m==null?void 0:m.properties.wind,M.properties.wind,N),type:"forecast",disabled:f,showCircle:g});i.push(k)}S+=t*60,P=T.clone().add(S,"minute").set({minute:0,second:0,millisecond:0})}}return i}static accelPassageAt(e,t){const{t1:n,t2:i,hr:o,hours:r}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:i,hr:o,hours:r}}static diversionPassageAt(e,t,n,i={}){const{t1:o,t2:r,hr:s,hours:c}=this.tropicalCenterTwin(t,24,i);if(o&&r){if(!i.debug){const T=y.calculateDistance(e,o),S=y.calculateDistance(e,r);if(T>2*n&&S>2*n)return D==null||D.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",i.requestId,T,S,{from:e,t1:o,t2:r,hr:s}),{}}const a=y.calculateBearing(e,o),u=y.calculateBearing(o,r),l=Math.abs(a-u);let g=0;l<180?g=l+90:l>=180&&(g=l-90);const f=y.calculateCoordinate(o,g,n);return D==null||D.info("[%s] the right tangent position: %j",i.requestId,{from:e,t1:o,t2:r,radius:n,bearing1:a,bearing2:u,right:f}),{at:f,t1:o,t2:r,hr:Number(s),hours:c}}return{}}static driftPassageAt(e,t,n,i={}){const{t1:o,t2:r,hr:s,hours:c}=this.tropicalCenterTwin(t,24,i);if(o&&r){if(!i.debug){const f=y.calculateDistance(e,o),T=y.calculateDistance(e,r);if(f>2*n&&T>2*n)return D==null||D.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",i.requestId,f,T,{from:e,t1:o,t2:r,hr:s}),{}}const a=y.calculateBearing(e,o),u=y.calculateBearing(o,r),l=y.calculateDistance(e,o);return{at:y.calculateCoordinate(o,a-u+180,n<l?n:l),t1:o,t2:r,hr:Number(s),hours:c}}else return D==null||D.info("[%s] no need drift: %j",i.requestId,{from:e,t1:o,t2:r,hr:s}),{}}static tropicalCenterTwin(e,t=24,n={}){var u,l,g,f,T;let i={};(u=e.forecasts)==null||u.forEach(S=>{i={...S.hours,...i}});const o=((l=e==null?void 0:e.history)==null?void 0:l[0])||(i==null?void 0:i[(g=Object.keys(i))==null?void 0:g[0]]);D==null||D.info("[%s] the first tropical center: %j",n.requestId,o);let r=(f=Object.keys(i||{}).filter(S=>Number(S)<=(t<0?24:t)))==null?void 0:f.at(-1);r||(r=(T=Object.keys(i||{}).filter(S=>Number(S)<=(t<0?24:2*t)))==null?void 0:T.at(-1));const s=i==null?void 0:i[r||-1];D==null||D.info("[%s] the second tropical center: %j in %d hrs",n.requestId,s,r);const c=Object.keys(i||{}).filter(S=>Number(S)<=Number(r)),a={0:o};for(const S of c)a[S]=i[S];return{t1:o,t2:s,hr:Number(r),hours:a}}static pickIndex(e,t){let n=0;for(const i of e){if(b(i.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 i={};for(const o in e)i[o]=this.computeNumber(e[o],t[o],n);return i}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(C){return C instanceof Uint8Array},from(C,e){if(typeof C=="string")return new TextEncoder().encode(C);if(C instanceof ArrayBuffer)return new Uint8Array(C);if(Array.isArray(C))return new Uint8Array(C);throw new TypeError("Buffer.from: unsupported source type")}});let x;try{x=F.getLogger("meteo")}catch{}finally{}function G(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:C}=require("jsdom"),{DOMParser:e}=new C("").window;return new e}class O{static toArrayBuffer(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}static drawCircle(e,t,n,i={}){const o=(i==null?void 0:i.steps)??64,r=(i==null?void 0:i.units)??"nauticalmiles",s=(i==null?void 0:i.properties)??{},c=h.point([e,t]),a=h.destination(c,n,90,{units:r}),u=b.utc();s.id=(i==null?void 0:i.id)||u.valueOf().toString();const l="circle";return s.name=(i==null?void 0:i.name)||`${l}_${u.format()}`,s.radius=n,s.center=[e,t],s.end=a.geometry.coordinates.map(g=>d.roundPrecision(g,9)),s.units=r,s.steps=o,s.shape="circle",x.info("[%s] draw circle with %j",i==null?void 0:i.requestId,s),h.circle(c,n,{steps:o,units:r,properties:s})}static drawRect(e,t,n={}){const i=(n==null?void 0:n.properties)??{},o=b.utc();i.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="rect";i.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,i.start=e.map(u=>d.roundPrecision(u,9)),i.end=t.map(u=>d.roundPrecision(u,9)),i.shape="rect",x.info("[%s] draw rect with %j",n==null?void 0:n.requestId,i);const[s,c]=d.convertToMonotonicLng2([e,t]),a=[Math.min(s[0],c[0]),Math.min(s[1],c[1]),Math.max(s[0],c[0]),Math.max(s[1],c[1])];return h.bboxPolygon(a,{properties:i})}static drawLine(e,t={}){const n=(t==null?void 0:t.properties)??{},i=b.utc();n.id=(t==null?void 0:t.id)||i.valueOf().toString();const o="line";n.name=(t==null?void 0:t.name)||`${o}_${i.format()}`,n.shape="line",x.info("[%s] draw line with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return h.lineString(r,n)}static drawPolygon(e,t={}){const n=(t==null?void 0:t.properties)??{},i=b.utc();n.id=(t==null?void 0:t.id)||i.valueOf().toString();const o="polygon";n.name=(t==null?void 0:t.name)||`${o}_${i.format()}`,n.coordinates=e.map(s=>s.map(c=>d.roundPrecision(c,9))),n.shape="polygon",x.info("[%s] draw polygon with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return h.polygon([r],n)}static drawPoint(e,t,n={}){const i=(n==null?void 0:n.properties)??{},o=b.utc();i.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="point";return i.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,i.shape="point",x.info("[%s] draw point with %j",n==null?void 0:n.requestId,i),h.point([t,e],i)}static parseCircle(e,t={}){var i,o;x.info("[%s] parse circle with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="circle"){const r=b.utc();n.id=(n==null?void 0:n.id)||r.valueOf().toString();const s=n==null?void 0:n.id,c=((i=n==null?void 0:n.center)==null?void 0:i.length)==2?h.point(n.center):h.centroid(e);let a="center";c.properties={id:`${a}_${s}`,parentId:s,name:a};const u=(n==null?void 0:n.units)||"nauticalmiles";let l=n==null?void 0:n.radius;if(!l){const T=h.polygonToLine(e);l=h.pointToLineDistance(c,T,{units:u})}a="end";const g=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?h.point(n.end):h.destination(c,l,90,{units:u});g.properties={id:`${a}_${s}`,parentId:s,name:a,radius:l,units:u};const f=h.lineString([c.geometry.coordinates,g.geometry.coordinates]);return a="edge",f.properties={id:`${a}_${s}`,parentId:s,name:a,radius:l,units:u},h.featureCollection([c,g,f,e])}else return x.warn("[%s] not a orm-std circle, just return the original feature",t==null?void 0:t.requestId),h.featureCollection([e])}static parseRect(e,t={}){x.info("[%s] parse rect with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="rect"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,u)=>{const l=h.point(r[u]);return l.properties={id:`${a}_${o}`,parentId:o,name:a},l});return h.featureCollection([...c,e])}else return x.warn("[%s] not a orm-std rect, just return the original feature",t==null?void 0:t.requestId),h.featureCollection([e])}static parseLine(e,t={}){x.info("[%s] parse line with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="line"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,s=e.geometry.coordinates.map((c,a)=>{const u=`point_${a}`,l=h.point(c);return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return h.featureCollection([...s,e])}else return x.warn("[%s] not a orm-std line, just return the original feature",t==null?void 0:t.requestId),h.featureCollection([e])}static parsePolygon(e,t={}){x.info("[%s] parse polygon with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="polygon"){const i=b.utc();n.id=(n==null?void 0:n.id)||i.valueOf().toString();const o=n==null?void 0:n.id,s=e.geometry.coordinates[0].map((c,a)=>{const u=h.point(c),l=`corner_${a}`;return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return h.featureCollection([...s,e])}else return x.warn("[%s] not a orm-std polygon, just return the original feature",t==null?void 0:t.requestId),h.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 c;const t=new Uint8Array(e),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),i=new DataView(n),o=new Uint8Array(n),r=new Map;let s=0;for(;s+4<=n.byteLength&&i.getUint32(s,!0)===67324752;){const u=i.getUint16(s+6,!0),l=i.getUint16(s+8,!0);let g=i.getUint32(s+18,!0);const f=i.getUint16(s+26,!0),T=i.getUint16(s+28,!0),S=o.slice(s+30,s+30+f),p=new TextDecoder().decode(S),v=s+30+f+T;if((u&8)!==0||g===0){let m=v;for(;m+4<=n.byteLength;){const N=i.getUint32(m,!0);if(N===67324752||N===33639248)break;m++}g=m-v}const M=o.slice(v,v+g);if(l===0)r.set(p,M);else if(l===8){if(typeof DecompressionStream<"u"){const m=new DecompressionStream("deflate-raw"),N=m.writable.getWriter(),R=m.readable.getReader();N.write(M),N.close();const E=[];let k=0;for(;;){const{done:w,value:W}=await R.read();if(w)break;E.push(W),k+=W.length}const j=new Uint8Array(k);let q=0;for(const w of E)j.set(w,q),q+=w.length;r.set(p,j)}else if(typeof process<"u"&&((c=process.versions)!=null&&c.node))try{r.set(p,O._inflateRawSync(M))}catch{}}s=v+g}return r}static async convertKML2GeoJSON(e,t={}){var s,c;x.info("[%s] convert kml to geojson",t==null?void 0:t.requestId);const i=G().parseFromString(e,"application/xml"),o=Array.from(i.querySelectorAll("Placemark")),r=[];for(const a of o){const u={},l=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const m of l){const N=m.getAttribute("name"),R=(c=(s=m.querySelector("value"))==null?void 0:s.textContent)==null?void 0:c.trim();N&&R!==void 0&&R!==null&&(u[N]=R)}const g=b.utc(),f=Object.keys(u).find(m=>m.toLowerCase().indexOf("name")!==-1),T=f?u[f]:void 0,S=`${g.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,p=m=>m.trim().split(/[\s\n]+/).filter(N=>N.length>0).map(N=>{const R=N.split(",").map(Number);return[R[0],R[1]]}),v=a.querySelector("LineString > coordinates");if(v){const m=p(v.textContent||"");if(m.length>=2){const N=h.lineString(m,{...u,shape:"line",id:S,name:T});r.push(N)}continue}const P=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(P){const m=p(P.textContent||"");if(m.length>=4){const N=m[0][0]===m[m.length-1][0]&&m[0][1]===m[m.length-1][1]?m:[...m,m[0]],R=h.polygon([N],{...u,shape:"polygon",id:S,name:T});r.push(R)}continue}const M=a.querySelector("Point > coordinates");if(M){const m=p(M.textContent||"");if(m.length>=1){const N=h.point(m[0],{...u,shape:"point",id:S,name:T});r.push(N)}continue}}return h.featureCollection(r)}static async convertKMZ2GeoJSON(e,t={}){var r;x.info("[%s] convert kmz to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=O.toArrayBuffer(e));const n=await O._parseZipEntries(e),i=n.get("doc.kml")??((r=[...n.entries()].find(([s])=>s.toLowerCase().endsWith(".kml")))==null?void 0:r[1]);if(!i)return x.warn("[%s] no .kml file found in kmz",t==null?void 0:t.requestId),h.featureCollection([]);const o=new TextDecoder().decode(i);return O.convertKML2GeoJSON(o,t)}static async convertZIP2GeoJSON(e,t={}){x.info("[%s] convert zip to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=O.toArrayBuffer(e));const n=await O._parseZipEntries(e),i=[];for(const[o,r]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const s=new TextDecoder().decode(r),c=await O.convertKML2GeoJSON(s,t);i.push(...c.features)}return i.length===0?(x.warn("[%s] no .kml files found in zip",t==null?void 0:t.requestId),this.convertSHP2GeoJSON(e,t)):h.featureCollection(i)}static async convertSHP2GeoJSON(e,t={}){x.info("[%s] convert shp zip to geojson",t==null?void 0:t.requestId);try{typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=O.toArrayBuffer(e));const n=await L(e);if(Array.isArray(n)){const i=n.flatMap(c=>c.features||[]),o=b.utc(),r=(t==null?void 0:t.id)||o.valueOf().toString(),s={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return i.forEach((c,a)=>{var T;const u=((T=c.geometry)==null?void 0:T.type)||"",l=s[u]||u.toLowerCase();c.properties=c.properties||{},c.properties.shape=l,c.properties.parentId=r,c.properties.id=`${r}_${a}`;const g=Object.keys(c.properties).find(S=>S.toLowerCase().indexOf("name")!==-1),f=g?c.properties[g]:void 0;c.properties.name=f||`${l}_${o.format()}_${a}`}),h.featureCollection(i)}return n}catch(n){return x.warn("[%s] failed to convert shp zip: %s",t==null?void 0:t.requestId,n),h.featureCollection([])}}}$.AisHelper=B,$.GeoJsonHelper=O,$.LaneHelper=y,$.LngLatHelper=d,$.TropicalHelper=Z,Object.defineProperty($,Symbol.toStringTag,{value:"Module"})});
|