@idm-plugin/geo 1.2.1 → 1.2.3
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/README.md +1 -1
- package/dist/index.js +331 -296
- package/dist/index.umd.cjs +1 -1
- package/dist/tropicals/src/index.d.ts +35 -5
- package/package.json +1 -1
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(C,I){typeof exports=="object"&&typeof module<"u"?I(exports,require("@turf/turf"),require("moment"),require("moment-timezone"),require("tz-lookup")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","moment-timezone","tz-lookup"],I):(C=typeof globalThis<"u"?globalThis:C||self,I(C["idm-plugin-rabbitmq"]={},C["@turf/turf"],C.moment,C["moment-timezone"],C["tz-lookup"]))})(this,function(C,I,y,q,W){"use strict";function F(T){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(T){for(const t in T)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(T,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>T[t]})}}return e.default=T,Object.freeze(e)}const g=F(I);function O(T){return T&&T.__esModule&&Object.prototype.hasOwnProperty.call(T,"default")?T.default:T}class j{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(T=>{j.prototype[T.toLowerCase()]=()=>{},j.prototype[`is${T}Enabled`]=()=>!1});const k=(()=>{try{return require("log4js")}catch{return null}})();var E={getLogger:k?k.getLogger:()=>new j};const A=O(E);class l{static guessTimeZoneOffset(e,t){const n=W(t,e),o=y().tz(n).utcOffset();return this.roundPrecision(o/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=l.convertToStdLng(e,t);let o="E";e<0&&(o="W"),e=Math.abs(e),n=n.toUpperCase();let i=e*3600,s,r,c,u,a,d;s=i%3600%60,n.indexOf("S")!==-1&&(i=i-s,r=l.padNumber(s,2,2)),c=i/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?u=l.roundPrecision(c,t).toString().padStart(2,"0"):u=l.padNumber(c,2,2),i=i-c*60),a=i/3600,n.indexOf("M")!==-1?d=l.roundPrecision(a,t).toString().padStart(3,"0"):d=l.padNumber(a,3,2);const p=`${n.replace(/S+/gi,r).replace(/M+/gi,u).replace(/H+/gi,d)}${o}`;return{direction:o,degree:l.roundPrecision(a,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:p}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let o="N";e<0&&(o="S"),e=Math.abs(e),n=n.toUpperCase();let i=e*3600,s,r,c,u,a,d;s=i%3600%60,n.indexOf("S")!==-1&&(i=i-s,r=l.padNumber(s,2,2)),c=i/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?u=l.roundPrecision(c,t).toString().padStart(2,"0"):u=l.padNumber(c,2,2),i=i-c*60),a=i/3600,n.indexOf("M")!==-1?d=l.roundPrecision(a,t).toString().padStart(2,"0"):d=l.padNumber(a,2,2);const p=`${n.replace(/S+/gi,r).replace(/M+/gi,u).replace(/H+/gi,d)}${o}`;return{direction:o,degree:l.roundPrecision(a,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:p}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LNG");const o=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const i=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=i;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>360&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,o==="W"&&(n=n*-1)}else n=Number(e);return l.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LAT");const o=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const i=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=i;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>90&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,o==="S"&&(n=n*-1)}else n=Number(e);return l.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=l.strReplace(e,n);const o=e[e.length-1].toUpperCase();return["N","S"].includes(o)?{lat:l.str2Lat(e,t)}:{lng:l.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),l.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}return e}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(/-/g," ").replace(/°/," ").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 o=e,i=Number(o.split(" ")[0]);if(isNaN(i))throw new Error(`invalid Lat/Lng: ${e}`);i>=90?e=`${o}E`:i<=-90?e=`${o}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${o}${i>0?"E":"W"}`:e=`${o}${i>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const o=Math.trunc(e).toString().padStart(t,"0"),i=Math.trunc(l.roundPrecision(e-Math.trunc(e),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${o}.${i}`}}class v{static calculateBearing(e,t,n=!0,o=4){const i=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let s;return n?s=g.rhumbBearing(i.features[0],i.features[1]):s=g.bearing(i.features[0],i.features[1]),s<0&&(s+=360),l.roundPrecision(s,o)}static calculateDistance(e,t,n=!0,o=4,i="nauticalmiles"){e={...e},t={...t},e.lng=l.convertToStdLng(e.lng,o),t.lng=l.convertToStdLng(t.lng,o);const s=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=g.rhumbDistance(s.features[0],s.features[1],{units:i}):r=g.distance(s.features[0],s.features[1],{units:i}),l.roundPrecision(r,o)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let o=0,i;for(const s of e)for(let r=0;r<s.length-1;r++){const c={lng:s[r][0],lat:s[r][1]};r===0&&i&&(o+=this.calculateDistance(i,c,!0,t,n));const u={lng:s[r+1][0],lat:s[r+1][1]};o+=this.calculateDistance(c,u,!0,t,n),i=u}return l.roundPrecision(o,t)}static calculateCoordinate(e,t,n,o="nauticalmiles",i=!0){const s=g.point([e.lng,e.lat]);let r;i?r=g.rhumbDestination(s,n,t,{units:o}):r=g.destination(s,n,t,{units:o});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,o=!0,i=!0,s="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),u=this.calculateDistance(e,t,!1,8,s);o&&r.push({lng:e.lng,lat:e.lat});let a=0;for(;a<u;)a+=n,a<u&&r.push(this.calculateCoordinate(e,c,a,s,!1));return i&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1){if((e==null?void 0:e.length)<2)return[];e=this.deduplicateCoordinates(e);let n=[];const o=[];let i,s;for(let r=0;r<e.length-1;r++){i=l.convertToStdLng(e[r].lng,8),s=l.convertToStdLng(e[r+1].lng,8),n.push([i,e[r].lat]);const c=i-s;if(Math.abs(c)>180){const u=l.convertToMonotonicLng2([[i,e[r].lat],[s,e[r+1].lat]]);let a,d;t?(a=g.lineString(u),d=g.lineString([[c>0?180:-180,89],[c>0?180:-180,-89]])):(a=g.greatCircle(u[0],u[1]),d=g.greatCircle([c>0?180:-180,89],[c>0?180:-180,-89]));const p=g.lineIntersect(a,d);let h;if(p.features.length){const D=g.getCoord(p.features[0]);h=l.roundPrecision(D[1],8)}else h=e[r].lat;c>0?(n.push([180-1e-6,h]),o.push([...n]),n=[],n.push([-(180-1e-6),h])):(n.push([-(180-1e-6),h]),o.push([...n]),n=[],n.push([180-1e-6,h]))}r===e.length-2&&n.push([s,e[r+1].lat])}return o.push(n),o}static deduplicateRoute(e){const t=[];for(const n of e){const o=n.reduce((i,s)=>(i.findIndex(r=>r[0]===s[0]&&r[1]===s[1])===-1&&i.push(s),i),[]);t.push(o)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(o=>o.lat===n.lat&&o.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);for(const n of t)for(let o=n.length-1;o>=0;o--)l.roundPrecision(n[o][0],8)===e.lng&&l.roundPrecision(n[o][1],8)===l.roundPrecision(e.lat,8)&&n.splice(o,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=l.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)l.roundPrecision(t[n].lng,8)===e.lng&&l.roundPrecision(t[n].lat,8)===l.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,o=0,i=0,s,r;return t.forEach((c,u)=>{for(let a=0;a<c.length-1;a++){const d={lng:c[a][0],lat:c[a][1]},p={lng:c[a+1][0],lat:c[a+1][1]},h=this.calculatePointToLineDistance(e,d,p);n>h&&(n=h,i=a,o=u,s=this.calculateDistance(d,e),r=this.calculateDistance(p,e))}}),s!==0&&r!==0?t[o].splice(i+1,0,[e.lng,e.lat]):s===0?t[o].splice(i,1,[e.lng,e.lat]):r===0&&t[o].splice(i+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);const n=v.convertRouteToCoordinates(t);return n.push(e),v.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=v.convertRouteToCoordinates(t);return n.unshift(e),v.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 o=[];let i=0;return n.forEach(s=>{if(i===2)return;const r=[];for(const c of s){if(l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)){r.push(c),i===0&&r.push([e.lng,e.lat]),i=2;break}i===1?r.push(c):l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)&&(i=1,r.push(c))}r.length&&o.push(r)}),o}static calculateRangeWaypoints(e,t,n,o=[]){const i=this.convertRouteToCoordinates(n,0),s=this.mergeCoordinatesToWaypoints([e,t,...o],i),r=s.findIndex(a=>l.roundPrecision(e.lng,8)===l.roundPrecision(a.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(a.lat,8)),c=s.findIndex(a=>l.roundPrecision(t.lng,8)===l.roundPrecision(a.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(a.lat,8));return s.filter((a,d)=>d>=r&&d<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,o=0,i=0;return t.forEach((s,r)=>{for(let c=0;c<s.length-1;c++){const u={lng:s[c][0],lat:s[c][1]},a={lng:s[c+1][0],lat:s[c+1][1]},d=this.calculatePointToLineDistance(e,u,a);n>d&&(n=d,o=c,i=r)}}),{minDist:n,segIndex:i,minIndex:o}}static calculateSubRoute(e,t){const{segIndex:n,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const i=[];let s=!0;for(let r=n;r<t.length;r++)if(s){const c=[];c.push([e.lng,e.lat]);for(let u=o+1;u<t[r].length;u++)e.lng===t[r][u][0]&&e.lat===t[r][u][1]||c.push(t[r][u]);i.push(c),s=!1}else i.push([...t[r]]);return i}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,o=0;for(let s=0;s<t.length-1;s++){const r=t[s],c=t[s+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((a,d)=>d>0);const u=this.calculatePointToLineDistance(e,r,c);n>u&&(n=u,o=s)}e.lng=l.convertToStdLng(e.lng);const i=[e];for(let s=o+1;s<t.length;s++)i.push(t[s]);return i}static calculatePointToLineDistance(e,t,n,o={units:"nauticalmiles",method:"geodesic"}){e.lng=l.convertToStdLng(e.lng),t={...t},n={...n},t.lng=l.convertToStdLng(t.lng,8),n.lng=l.convertToStdLng(n.lng,8);const i=l.convertToMonotonicLng([t,n]);t=i[0],n=i[1];const s=g.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([e.lng,e.lat]),s,o),c=g.pointToLineDistance(g.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),s,o);return l.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 o=e[n],i=e[n+1],s=this.calculateRangeRoute(o,i,t);n===0&&(o.distanceFromPrevious=0,o.distanceFromStart=0),i.distanceFromPrevious=this.calculateRouteDistance(s),i.distanceFromStart=l.roundPrecision((o.distanceFromStart||0)+i.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const o of e)this.mergeCoordinateToWaypoints(o,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=l.convertToStdLng(e.lng,8);let o=Number.MAX_VALUE,i=0,s=0,r=0;for(let c=0;c<t.length-1;c++){const u={lng:t[c].lng,lat:t[c].lat},a={lng:t[c+1].lng,lat:t[c+1].lat},d=this.calculatePointToLineDistance(e,u,a);o>=d&&(o=d,i=c,s=this.calculateDistance(u,e,!1,6),r=this.calculateDistance(a,e,!1,6))}return s!==0&&r!==0?s<o||s===o&&i===0?t.unshift(e):r<o||r===o&&i===t.length-2?t.push(e):t.splice(i+1,0,e):s===0?n&&t.splice(i,1,e):r===0&&n&&t.splice(i+1,1,e),t.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(e){const t=[];for(let n=1;n<e.length;n++){const o=e[n-1],i=e[n];if(n===1&&t.push(o),i.gcToPrevious){const s=this.interpolateCoordinates(o,i,200,!1,!0,"nauticalmiles");t.push(...s)}else t.push(i)}return this.divideAccordingToLng(t,!0)}static nearestCoordinateInRoute(e,t){const n=g.point([e.lng,e.lat]),o=[];for(const c of t){const u=c.map(a=>g.point(a));o.push(...u)}const i=g.featureCollection(o),s=g.nearestPoint(n,i),r=g.getCoord(s);return{lng:r[0],lat:r[1]}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let o=0;o<t.length-1;o++){const i=t[o],s=t[o+1];if(this.calculateDistance(e,i)===0){n=o;break}if(this.calculateDistance(e,s)===0){n=o+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,o="nauticalmiles"){var p;const i=e.speed||12,s=[];let r=[],c=!1,u=0,a=0,d;if(t&&n.length?(s.push(e),n.forEach((h,D)=>{if(c)r.push(h);else{const P=[];let b;for(let S=0;S<h.length;S++)if(d)P.push(h[S]);else{b={lng:h[S][0],lat:h[S][1]};const m=this.calculateDistance(e,b,!0,8,o);if(u+=m,u<t)a+=m,s.push(b),e=b;else{if(a=t,u===t)d=b,P.push([d.lng,d.lat]);else{const f=u-t,M=this.calculateBearing(b,e);d=this.calculateCoordinate(b,M,f,o),P.push([d.lng,d.lat]),P.push([b.lng,b.lat])}c=!0}}P.length&&r.push(P),D===n.length-1&&!d&&(d=b)}})):(r=n,d={...e}),d)if(s.push(d),d.distanceFromPrevious=a,d.hourFromPrevious=Math.round(a/i*1e4)/1e4,((p=r[0])==null?void 0:p.length)>1){const h={lng:r[0][1][0],lat:r[0][1][1]};d.bearing=this.calculateBearing(d,h)}else d.bearing=0;return{coordinate:d,nextRoute:r,prevRoute:s}}static nearestCoordinateInLine(e,t,n){const o=l.convertToStdLng(e.lng,6),i=g.point([o,e.lat]),s=l.convertToStdLng(t.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[s,t.lat],[r,n.lat]]),u=g.nearestPointOnLine(c,i),a=g.getCoord(u),d=l.roundPrecision(a[0],6),p=l.roundPrecision(a[1],6);return{lng:d,lat:p,inline:!(d===s&&p===t.lat)&&!(d===r&&p===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let o,i;return e.forEach(s=>{s.forEach(r=>{const c={lng:r[0],lat:r[1]};if(!i)n.push(c),i=c;else if(i.bearing===void 0)i.bearing=this.calculateBearing(i,c,!0);else{const u=this.calculateDistance(o,c,!0);u&&u>=t&&(o.bearing=this.calculateBearing(o,c,!0),n.push(o),i=o)}o=c})}),o&&n.push(o),n}static simplifyRouteToCoordinates(e,t,n=1){let o=this.convertRouteToCoordinates(e,n);return o=this.simplifyGCCoordinates(o,t),o}static simplifyGCCoordinates(e,t){t.forEach(o=>{this.mergeCoordinateToWaypoints(o,e)});for(let o=1;o<t.length;o++){const i=t[o-1],s=t[o];if(s.gcToPrevious){const r=e.findIndex(u=>u.lng===i.lng&&u.lat===i.lat),c=e.findIndex(u=>u.lng===s.lng&&u.lat===s.lat);for(let u=c-1;u>r;u--)e.splice(u,1)}}let n=0;for(let o=1;o<e.length;o++){const i=e[o-1],s=e[o];s.gcToPrevious?(i.bearing=this.calculateBearing(i,s,!1),s.distanceFromPrevious=this.calculateDistance(i,s,!1)):(i.bearing=this.calculateBearing(i,s,!0),s.distanceFromPrevious=this.calculateDistance(i,s,!0)),n=l.roundPrecision(n+s.distanceFromPrevious),s.distanceFromStart=n}return e.map(o=>(o.lng=l.convertToStdLng(o.lng),o))}static calculateCenter(e){const t=[];for(const r of e)for(const c of r)t.push(c);const n=g.featureCollection([]),o=l.convertToMonotonicLng2(t);for(const r of o)n.features.push(g.point(r));const s=g.center(n).geometry.coordinates;return{lng:l.convertToStdLng(s[0],8),lat:l.roundPrecision(s[1],8)}}static calculateCenter2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateCenter(t)}static calculateBBox(e){const t=[];for(const i of e)for(const s of i)t.push(s);const n=l.convertToMonotonicLng2(t),o=g.lineString(n);return g.bbox(o)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}}const R=A.getLogger("vessel");class B{static convert2Geojson(e){var n;const t=g.featureCollection([]);for(const o of e){if(o.forecasts){const i=(n=o.history)==null?void 0:n[0];for(const s of o.forecasts){const r=[],c=y(s.date).utc(),u=`${o.name}-${s.model}`;if(i){const a=y(i.updated).utc(),d=g.point([i.lng,i.lat],{model:s.model,name:o.name,date:a.format(),hour:0,format:a.format("MMM-DD/HHmm[Z]"),pressure:i.pressure>1e4?l.roundPrecision(i.pressure/100,0):l.roundPrecision(i.pressure,0),wind:{kts:i.kts,spd:i.speed||i.spd},category:u,type:"forecast"});t.features.push(d),r.push(d.geometry.coordinates)}for(const a in s==null?void 0:s.hours){const d=s.hours[a];d.wind.spd=d.wind.spd||d.wind.speed;const p=c.clone().add(Number(a),"hour"),h=g.point([d.lng,d.lat],{model:s.model,name:o.name,date:p.format(),hour:Number(a),format:p.format("MMM-DD/HHmm[Z]"),pressure:d.pressure>1e4?l.roundPrecision(d.pressure/100,0):l.roundPrecision(d.pressure,0),gusts:d.gusts,wind:d.wind||{},movement:d.movement,category:u,type:"forecast"});t.features.push(h),r.push(h.geometry.coordinates)}if((r==null?void 0:r.length)>1){const a=g.lineString(l.convertToMonotonicLng2(r),{date:s.date,id:o.id||o.name,model:s.model,name:o.name,category:u,type:"forecast"});t.features.push(a)}}}if(o.history){const i=[];for(const r of o.history){const c=y(r.updated).utc(),u=g.point([r.lng,r.lat],{name:o.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?l.roundPrecision(r.pressure/100,0):l.roundPrecision(r.pressure,0),spd:r.speed||r.spd,kts:r.kts,source:r.source,level:r.type,type:"history",category:`${o.name}-history`});t.features.push(u),i.push(u.geometry.coordinates)}const s=o.history[0];if(i.length===1&&i.push(i[0]),i.length>1){const r=g.lineString(l.convertToMonotonicLng2(i),{name:o.name,type:"history",updated:s==null?void 0:s.updated,pressure:(s==null?void 0:s.pressure)>1e4?l.roundPrecision((s==null?void 0:s.pressure)/100,0):l.roundPrecision(s==null?void 0:s.pressure,0),spd:(s==null?void 0:s.speed)||(s==null?void 0:s.spd),kts:s==null?void 0:s.kts,source:s==null?void 0:s.source,level:s==null?void 0:s.type});t.features.push(r)}}}return t}static interpolate(e,t=3){var i,s,r,c,u;const n=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),o=[];for(const a of n){const d=a.properties.name,p=a.properties.model,h=y(a.properties.date).utc();let D=t*60-(h.get("hour")*60+h.get("minute"))%(t*60);const P=(s=e==null?void 0:e.data)==null?void 0:s.features.filter(m=>m.geometry.type==="Point"&&m.properties.type==="forecast"&&m.properties.category===`${d}-${p}`);let b,S=h.clone().add(D,"minute").set({minute:0,second:0,millisecond:0});for(;b=this.pickIndex(P,S),b<=P.length-1;){if(b>0){const m=P[b],f=b===0?void 0:P[b-1],M=(D/60-((r=f==null?void 0:f.properties)==null?void 0:r.hour))/(m.properties.hour-((c=f==null?void 0:f.properties)==null?void 0:c.hour)),x=this.computeNumber(f==null?void 0:f.geometry.coordinates[0],m.geometry.coordinates[0],M),$=this.computeNumber(f==null?void 0:f.geometry.coordinates[1],m.geometry.coordinates[1],M),N=g.point([x,$],{name:d,model:p,category:m==null?void 0:m.properties.category,date:S.format(),format:S.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(f==null?void 0:f.properties.gusts,m.properties.gusts,M),hour:this.computeNumber(f==null?void 0:f.properties.hour,m.properties.hour,M),movement:this.computeNumber(f==null?void 0:f.properties.movement,m.properties.movement,M),pressure:this.computeNumber(f==null?void 0:f.properties.pressure,m.properties.pressure,M),wind:this.computeNumber(f==null?void 0:f.properties.wind,m.properties.wind,M),type:"forecast",showCircle:(u=a==null?void 0:a.properties)==null?void 0:u.showCircle});o.push(N)}D+=t*60,S=h.clone().add(D,"minute").set({minute:0,second:0,millisecond:0})}}return o}static diversionPassageAt(e,t,n,o,i={requestId:""}){var a,d,p,h,D,P,b,S,m;const s=(d=(a=t==null?void 0:t.forecasts)==null?void 0:a[0])==null?void 0:d.hours,r=((p=t==null?void 0:t.history)==null?void 0:p[0])||(s==null?void 0:s[(h=Object.keys(s))==null?void 0:h[0]]);R.info("[%s] the first evasion point: %j",i.requestId,r);const c=(D=Object.keys(s||{}).filter(f=>Number(f)<=24))==null?void 0:D.at(-1),u=s==null?void 0:s[c||-1];if(R.info("[%s] the second evasion point in %s hrs: %j",i.requestId,c,r),r&&u){const f=v.calculateBearing(e,r),M=v.calculateBearing(r,u),x=v.calculateCoordinate(r,f-M+90,n);R.info("[%s] the right tangent point: %j",i.requestId,{from:e,p1:r,p2:u,radius:n,bearing1:f,bearing2:M,right:x});const $=v.calculateBearing(e,x);let N=v.calculateCoordinate(e,$,o*Number(c));N.utc=y((b=(P=t==null?void 0:t.forecasts)==null?void 0:P[0])==null?void 0:b.date).add(Number(c),"hours").utc().format(),R.info("[%s] the temp evasion point: %j",i.requestId,N);const L=v.calculateDistance(N,u);return R.info("[%s] the distance(%d) between tmp & p2: %j - %j",i.requestId,L,N,u),L<n&&(N=v.calculateCoordinate(e,$,o*Number(c)/2),N.utc=y((m=(S=t==null?void 0:t.forecasts)==null?void 0:S[0])==null?void 0:m.date).add(Number(c)/2,"hours").utc().format(),R.warn("[%s] tmp is too close to p2, replace with 1/2 position: %j",i.requestId,N)),N}else{R.info("[%s] no need evasion: %j",i.requestId,{from:e,p1:r,p2:u});return}}static pickIndex(e,t){let n=0;for(const o of e){if(y(o.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 o={};for(const i in e)o[i]=this.computeNumber(e[i],t[i],n);return o}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}C.LaneHelper=v,C.LngLatHelper=l,C.TropicalHelper=B,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(S,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("@turf/turf"),require("moment"),require("moment-timezone"),require("tz-lookup")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","moment-timezone","tz-lookup"],y):(S=typeof globalThis<"u"?globalThis:S||self,y(S["idm-plugin-rabbitmq"]={},S["@turf/turf"],S.moment,S["moment-timezone"],S["tz-lookup"]))})(this,function(S,y,D,A,$){"use strict";function j(b){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(b){for(const t in b)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(b,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>b[t]})}}return e.default=b,Object.freeze(e)}const g=j(y);function k(b){return b&&b.__esModule&&Object.prototype.hasOwnProperty.call(b,"default")?b.default:b}class R{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(b=>{R.prototype[b.toLowerCase()]=()=>{},R.prototype[`is${b}Enabled`]=()=>!1});const x=(()=>{try{return require("log4js")}catch{return null}})();var L={getLogger:x?x.getLogger:()=>new R};const W=k(L);class l{static guessTimeZoneOffset(e,t){const n=$(t,e),i=D().tz(n).utcOffset();return this.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=l.convertToStdLng(e,t);let i="E";e<0&&(i="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,s,r,c,a,d,u;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=l.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(3,"0"):u=l.padNumber(d,3,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${i}`;return{direction:i,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:h}}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,s,r,c,a,d,u;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=l.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(2,"0"):u=l.padNumber(d,2,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${i}`;return{direction:i,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:h}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LNG");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>360&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,i==="W"&&(n=n*-1)}else n=Number(e);return l.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LAT");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>90&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,i==="S"&&(n=n*-1)}else n=Number(e);return l.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=l.strReplace(e,n);const i=e[e.length-1].toUpperCase();return["N","S"].includes(i)?{lat:l.str2Lat(e,t)}:{lng:l.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),l.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}return e}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(/-/g," ").replace(/°/," ").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=Math.trunc(e).toString().padStart(t,"0"),o=Math.trunc(l.roundPrecision(e-Math.trunc(e),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${i}.${o}`}}class P{static calculateBearing(e,t,n=!0,i=4){const o=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let s;return n?s=g.rhumbBearing(o.features[0],o.features[1]):s=g.bearing(o.features[0],o.features[1]),s<0&&(s+=360),l.roundPrecision(s,i)}static calculateDistance(e,t,n=!0,i=4,o="nauticalmiles"){e={...e},t={...t},e.lng=l.convertToStdLng(e.lng,i),t.lng=l.convertToStdLng(t.lng,i);const s=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=g.rhumbDistance(s.features[0],s.features[1],{units:o}):r=g.distance(s.features[0],s.features[1],{units:o}),l.roundPrecision(r,i)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let i=0,o;for(const s of e)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,t,n));const a={lng:s[r+1][0],lat:s[r+1][1]};i+=this.calculateDistance(c,a,!0,t,n),o=a}return l.roundPrecision(i,t)}static calculateCoordinate(e,t,n,i="nauticalmiles",o=!0){const s=g.point([e.lng,e.lat]);let r;o?r=g.rhumbDestination(s,n,t,{units:i}):r=g.destination(s,n,t,{units:i});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,i=!0,o=!0,s="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,s);i&&r.push({lng:e.lng,lat:e.lat});let d=0;for(;d<a;)d+=n,d<a&&r.push(this.calculateCoordinate(e,c,d,s,!1));return o&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1){if((e==null?void 0:e.length)<2)return[];e=this.deduplicateCoordinates(e);let n=[];const i=[];let o,s;for(let r=0;r<e.length-1;r++){o=l.convertToStdLng(e[r].lng,8),s=l.convertToStdLng(e[r+1].lng,8),n.push([o,e[r].lat]);const c=o-s;if(Math.abs(c)>180){const a=l.convertToMonotonicLng2([[o,e[r].lat],[s,e[r+1].lat]]);let d,u;t?(d=g.lineString(a),u=g.lineString([[c>0?180:-180,89],[c>0?180:-180,-89]])):(d=g.greatCircle(a[0],a[1]),u=g.greatCircle([c>0?180:-180,89],[c>0?180:-180,-89]));const h=g.lineIntersect(d,u);let p;if(h.features.length){const C=g.getCoord(h.features[0]);p=l.roundPrecision(C[1],8)}else p=e[r].lat;c>0?(n.push([180-1e-6,p]),i.push([...n]),n=[],n.push([-(180-1e-6),p])):(n.push([-(180-1e-6),p]),i.push([...n]),n=[],n.push([180-1e-6,p]))}r===e.length-2&&n.push([s,e[r+1].lat])}return i.push(n),i}static deduplicateRoute(e){const t=[];for(const n of e){const i=n.reduce((o,s)=>(o.findIndex(r=>r[0]===s[0]&&r[1]===s[1])===-1&&o.push(s),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=l.convertToStdLng(e.lng,8);for(const n of t)for(let i=n.length-1;i>=0;i--)l.roundPrecision(n[i][0],8)===e.lng&&l.roundPrecision(n[i][1],8)===l.roundPrecision(e.lat,8)&&n.splice(i,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=l.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)l.roundPrecision(t[n].lng,8)===e.lng&&l.roundPrecision(t[n].lat,8)===l.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,i=0,o=0,s,r;return t.forEach((c,a)=>{for(let d=0;d<c.length-1;d++){const u={lng:c[d][0],lat:c[d][1]},h={lng:c[d+1][0],lat:c[d+1][1]},p=this.calculatePointToLineDistance(e,u,h);n>p&&(n=p,o=d,i=a,s=this.calculateDistance(u,e),r=this.calculateDistance(h,e))}}),s!==0&&r!==0?t[i].splice(o+1,0,[e.lng,e.lat]):s===0?t[i].splice(o,1,[e.lng,e.lat]):r===0&&t[i].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);const n=P.convertRouteToCoordinates(t);return n.push(e),P.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=P.convertRouteToCoordinates(t);return n.unshift(e),P.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(s=>{if(o===2)return;const r=[];for(const c of s){if(l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([e.lng,e.lat]),o=2;break}o===1?r.push(c):l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&i.push(r)}),i}static calculateRangeWaypoints(e,t,n,i=[]){const o=this.convertRouteToCoordinates(n,0),s=this.mergeCoordinatesToWaypoints([e,t,...i],o),r=s.findIndex(d=>l.roundPrecision(e.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(d.lat,8)),c=s.findIndex(d=>l.roundPrecision(t.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(d.lat,8));return s.filter((d,u)=>u>=r&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,i=0,o=0;return t.forEach((s,r)=>{for(let c=0;c<s.length-1;c++){const a={lng:s[c][0],lat:s[c][1]},d={lng:s[c+1][0],lat:s[c+1][1]},u=this.calculatePointToLineDistance(e,a,d);n>u&&(n=u,i=c,o=r)}}),{minDist:n,segIndex:o,minIndex:i}}static calculateSubRoute(e,t){const{segIndex:n,minIndex:i}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const o=[];let s=!0;for(let r=n;r<t.length;r++)if(s){const c=[];c.push([e.lng,e.lat]);for(let a=i+1;a<t[r].length;a++)e.lng===t[r][a][0]&&e.lat===t[r][a][1]||c.push(t[r][a]);o.push(c),s=!1}else o.push([...t[r]]);return o}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,i=0;for(let s=0;s<t.length-1;s++){const r=t[s],c=t[s+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((d,u)=>u>0);const a=this.calculatePointToLineDistance(e,r,c);n>a&&(n=a,i=s)}e.lng=l.convertToStdLng(e.lng);const o=[e];for(let s=i+1;s<t.length;s++)o.push(t[s]);return o}static calculatePointToLineDistance(e,t,n,i={units:"nauticalmiles",method:"geodesic"}){e.lng=l.convertToStdLng(e.lng),t={...t},n={...n},t.lng=l.convertToStdLng(t.lng,8),n.lng=l.convertToStdLng(n.lng,8);const o=l.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const s=g.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([e.lng,e.lat]),s,i),c=g.pointToLineDistance(g.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),s,i);return l.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 i=e[n],o=e[n+1],s=this.calculateRangeRoute(i,o,t);n===0&&(i.distanceFromPrevious=0,i.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(s),o.distanceFromStart=l.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=l.convertToStdLng(e.lng,8);let i=Number.MAX_VALUE,o=0,s=0,r=0;for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},d={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,d);i>=u&&(i=u,o=c,s=this.calculateDistance(a,e,!1,6),r=this.calculateDistance(d,e,!1,6))}return s!==0&&r!==0?s<i||s===i&&o===0?t.unshift(e):r<i||r===i&&o===t.length-2?t.push(e):t.splice(o+1,0,e):s===0?n&&t.splice(o,1,e):r===0&&n&&t.splice(o+1,1,e),t.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(e){const t=[];for(let n=1;n<e.length;n++){const i=e[n-1],o=e[n];if(n===1&&t.push(i),o.gcToPrevious){const s=this.interpolateCoordinates(i,o,200,!1,!0,"nauticalmiles");t.push(...s)}else t.push(o)}return this.divideAccordingToLng(t,!0)}static nearestCoordinateInRoute(e,t){const n=g.point([e.lng,e.lat]),i=[];for(const c of t){const a=c.map(d=>g.point(d));i.push(...a)}const o=g.featureCollection(i),s=g.nearestPoint(n,o),r=g.getCoord(s);return{lng:r[0],lat:r[1]}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let i=0;i<t.length-1;i++){const o=t[i],s=t[i+1];if(this.calculateDistance(e,o)===0){n=i;break}if(this.calculateDistance(e,s)===0){n=i+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,i="nauticalmiles"){var h;const o=e.speed||12,s=[];let r=[],c=!1,a=0,d=0,u;if(t&&n.length?(s.push(e),n.forEach((p,C)=>{if(c)r.push(p);else{const v=[];let T;for(let m=0;m<p.length;m++)if(u)v.push(p[m]);else{T={lng:p[m][0],lat:p[m][1]};const f=this.calculateDistance(e,T,!0,8,i);if(a+=f,a<t)d+=f,s.push(T),e=T;else{if(d=t,a===t)u=T,v.push([u.lng,u.lat]);else{const M=a-t,I=this.calculateBearing(T,e);u=this.calculateCoordinate(T,I,M,i),v.push([u.lng,u.lat]),v.push([T.lng,T.lat])}c=!0}}v.length&&r.push(v),C===n.length-1&&!u&&(u=T)}})):(r=n,u={...e}),u)if(s.push(u),u.distanceFromPrevious=d,u.hourFromPrevious=Math.round(d/o*1e4)/1e4,((h=r[0])==null?void 0:h.length)>1){const p={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,p)}else u.bearing=0;return{coordinate:u,nextRoute:r,prevRoute:s}}static nearestCoordinateInLine(e,t,n){const i=l.convertToStdLng(e.lng,6),o=g.point([i,e.lat]),s=l.convertToStdLng(t.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[s,t.lat],[r,n.lat]]),a=g.nearestPointOnLine(c,o),d=g.getCoord(a),u=l.roundPrecision(d[0],6),h=l.roundPrecision(d[1],6);return{lng:u,lat:h,inline:!(u===s&&h===t.lat)&&!(u===r&&h===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let i,o;return e.forEach(s=>{s.forEach(r=>{const c={lng:r[0],lat:r[1]};if(!o)n.push(c),o=c;else if(o.bearing===void 0)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)});for(let i=1;i<t.length;i++){const o=t[i-1],s=t[i];if(s.gcToPrevious){const r=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===s.lng&&a.lat===s.lat);for(let a=c-1;a>r;a--)e.splice(a,1)}}let n=0;for(let i=1;i<e.length;i++){const o=e[i-1],s=e[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=l.roundPrecision(n+s.distanceFromPrevious),s.distanceFromStart=n}return e.map(i=>(i.lng=l.convertToStdLng(i.lng),i))}static calculateCenter(e){const t=[];for(const r of e)for(const c of r)t.push(c);const n=g.featureCollection([]),i=l.convertToMonotonicLng2(t);for(const r of i)n.features.push(g.point(r));const s=g.center(n).geometry.coordinates;return{lng:l.convertToStdLng(s[0],8),lat:l.roundPrecision(s[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 s of o)t.push(s);const n=l.convertToMonotonicLng2(t),i=g.lineString(n);return g.bbox(i)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}}const N=W.getLogger("vessel");class F{static convert2Geojson(e){var n;const t=g.featureCollection([]);for(const i of e){if(i.forecasts){const o=(n=i.history)==null?void 0:n[0];for(const s of i.forecasts){const r=[],c=D(s.date).utc(),a=`${i.name}-${s.model}`;if(o){const d=D(o.updated).utc(),u=g.point([o.lng,o.lat],{model:s.model,name:i.name,date:d.format(),hour:0,format:d.format("MMM-DD/HHmm[Z]"),pressure:o.pressure>1e4?l.roundPrecision(o.pressure/100,0):l.roundPrecision(o.pressure,0),wind:{kts:o.kts,spd:o.speed||o.spd},category:a,type:"forecast"});t.features.push(u),r.push(u.geometry.coordinates)}for(const d in s==null?void 0:s.hours){const u=s.hours[d];u.wind.spd=u.wind.spd||u.wind.speed;const h=c.clone().add(Number(d),"hour"),p=g.point([u.lng,u.lat],{model:s.model,name:i.name,date:h.format(),hour:Number(d),format:h.format("MMM-DD/HHmm[Z]"),pressure:u.pressure>1e4?l.roundPrecision(u.pressure/100,0):l.roundPrecision(u.pressure,0),gusts:u.gusts,wind:u.wind||{},movement:u.movement,category:a,type:"forecast"});t.features.push(p),r.push(p.geometry.coordinates)}if((r==null?void 0:r.length)>1){const d=g.lineString(l.convertToMonotonicLng2(r),{date:s.date,id:i.id||i.name,model:s.model,name:i.name,category:a,type:"forecast"});t.features.push(d)}}}if(i.history){const o=[];for(const r of i.history){const c=D(r.updated).utc(),a=g.point([r.lng,r.lat],{name:i.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?l.roundPrecision(r.pressure/100,0):l.roundPrecision(r.pressure,0),spd:r.speed||r.spd,kts:r.kts,source:r.source,level:r.type,type:"history",category:`${i.name}-history`});t.features.push(a),o.push(a.geometry.coordinates)}const s=i.history[0];if(o.length===1&&o.push(o[0]),o.length>1){const r=g.lineString(l.convertToMonotonicLng2(o),{name:i.name,type:"history",updated:s==null?void 0:s.updated,pressure:(s==null?void 0:s.pressure)>1e4?l.roundPrecision((s==null?void 0:s.pressure)/100,0):l.roundPrecision(s==null?void 0:s.pressure,0),spd:(s==null?void 0:s.speed)||(s==null?void 0:s.spd),kts:s==null?void 0:s.kts,source:s==null?void 0:s.source,level:s==null?void 0:s.type});t.features.push(r)}}}return t}static interpolate(e,t=3){var o,s,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"),i=[];for(const a of n){const d=a.properties.name,u=a.properties.model,h=D(a.properties.date).utc();let p=t*60-(h.get("hour")*60+h.get("minute"))%(t*60);const C=(s=e==null?void 0:e.data)==null?void 0:s.features.filter(m=>m.geometry.type==="Point"&&m.properties.type==="forecast"&&m.properties.category===`${d}-${u}`);let v,T=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0});for(;v=this.pickIndex(C,T),v<=C.length-1;){if(v>0){const m=C[v],f=v===0?void 0:C[v-1],M=(p/60-((r=f==null?void 0:f.properties)==null?void 0:r.hour))/(m.properties.hour-((c=f==null?void 0:f.properties)==null?void 0:c.hour)),I=this.computeNumber(f==null?void 0:f.geometry.coordinates[0],m.geometry.coordinates[0],M),O=this.computeNumber(f==null?void 0:f.geometry.coordinates[1],m.geometry.coordinates[1],M),E=g.point([I,O],{name:d,model:u,category:m==null?void 0:m.properties.category,date:T.format(),format:T.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(f==null?void 0:f.properties.gusts,m.properties.gusts,M),hour:this.computeNumber(f==null?void 0:f.properties.hour,m.properties.hour,M),movement:this.computeNumber(f==null?void 0:f.properties.movement,m.properties.movement,M),pressure:this.computeNumber(f==null?void 0:f.properties.pressure,m.properties.pressure,M),wind:this.computeNumber(f==null?void 0:f.properties.wind,m.properties.wind,M),type:"forecast",showCircle:a.showCircle});i.push(E)}p+=t*60,T=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0})}}return i}static diversionPassageAt(e,t,n,i,o={requestId:""}){var a,d,u,h;const{t1:s,t2:r,hr:c}=this.tropicalCenterTwin(t,24,o);if(s&&r){const p=P.calculateBearing(e,s),C=P.calculateBearing(s,r),v=P.calculateCoordinate(s,p-C+90,n);N.info("[%s] the right tangent position: %j",o.requestId,{from:e,t1:s,t2:r,radius:n,bearing1:p,bearing2:C,right:v});const T=P.calculateBearing(e,v);let m=P.calculateCoordinate(e,T,i*Number(c));m.utc=D((d=(a=t==null?void 0:t.forecasts)==null?void 0:a[0])==null?void 0:d.date).add(Number(c),"hours").utc().format(),N.info("[%s] the diversion position: %j",o.requestId,m);const f=P.calculateDistance(m,r);return N.info("[%s] the distance(%d) between the diversion position & t2: %j - %j",o.requestId,f,m,r),f<n&&(m=P.calculateCoordinate(e,T,i*Number(c)/2),m.utc=D((h=(u=t==null?void 0:t.forecasts)==null?void 0:u[0])==null?void 0:h.date).add(Number(c)/2,"hours").utc().format(),N.warn("[%s] the prev diversion position is too close to t2, replace with 1/2 position: %j",o.requestId,m)),m}else{N.info("[%s] no need to diversion: %j",o.requestId,{from:e,t1:s,t2:r});return}}static driftPassageAt(e,t,n,i={requestId:""}){const{t1:o,t2:s,hr:r}=this.tropicalCenterTwin(t,24,i);if(o&&s){const c=P.calculateBearing(e,o),a=P.calculateBearing(o,s);return P.calculateCoordinate(o,c-a+180,n)}else{N.info("[%s] no need drift: %j",i.requestId,{from:e,t1:o,t2:s});return}}static tropicalCenterTwin(e,t=24,n={requestId:""}){var c,a,d,u,h;const i=(a=(c=e==null?void 0:e.forecasts)==null?void 0:c[0])==null?void 0:a.hours,o=((d=e==null?void 0:e.history)==null?void 0:d[0])||(i==null?void 0:i[(u=Object.keys(i))==null?void 0:u[0]]);N.info("[%s] the first tropical center: %j",n.requestId,o);const s=(h=Object.keys(i||{}).filter(p=>Number(p)<=(t<0?24:t)))==null?void 0:h.at(-1),r=i==null?void 0:i[s||-1];return N.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,s),{t1:o,t2:r,hr:s}}static pickIndex(e,t){let n=0;for(const i of e){if(D(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}}S.LaneHelper=P,S.LngLatHelper=l,S.TropicalHelper=F,Object.defineProperty(S,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -30,11 +30,14 @@ export declare class TropicalHelper {
|
|
|
30
30
|
showCircle: any;
|
|
31
31
|
}>[];
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @param
|
|
33
|
+
* 计算最佳绕航点
|
|
34
|
+
* 1) 确定当前船位与当前台风中心点之间的方位角,
|
|
35
|
+
* 2) 当前台风中心点与近24小时台风中心点的方位角,
|
|
36
|
+
* 3) 根据1)、2)及可航半圆计算绕航点
|
|
37
|
+
* @param from 船舶位置
|
|
38
|
+
* @param tropical 台风数据 { history: any[], forecasts: any[] }
|
|
39
|
+
* @param radius 与台风中心的距离
|
|
40
|
+
* @param speed 前进速度
|
|
38
41
|
* @param options
|
|
39
42
|
*/
|
|
40
43
|
static diversionPassageAt(from: {
|
|
@@ -43,6 +46,33 @@ export declare class TropicalHelper {
|
|
|
43
46
|
}, tropical: any, radius: number, speed: number, options?: {
|
|
44
47
|
requestId: string;
|
|
45
48
|
}): any;
|
|
49
|
+
/**
|
|
50
|
+
* 计算最佳漂航点
|
|
51
|
+
* 1) 确定当前船位与当前台风中心点之间的方位角,
|
|
52
|
+
* 2) 当前台风中心点与近24小时台风中心点的方位角,
|
|
53
|
+
* 3) 根据2)、3)反向计算航漂航点
|
|
54
|
+
* @param from 船舶位置
|
|
55
|
+
* @param tropical 台风数据 { history: any[], forecasts: any[] }
|
|
56
|
+
* @param radius 与台风中心的距离
|
|
57
|
+
* @param options
|
|
58
|
+
*/
|
|
59
|
+
static driftPassageAt(from: {
|
|
60
|
+
lat: number;
|
|
61
|
+
lng: number;
|
|
62
|
+
}, tropical: any, radius: number, options?: {
|
|
63
|
+
requestId: string;
|
|
64
|
+
}): {
|
|
65
|
+
lng: number;
|
|
66
|
+
lat: number;
|
|
67
|
+
} | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* 获取台风中心点对数
|
|
70
|
+
* @param tropical { history: any[], forecasts: any[] }
|
|
71
|
+
* @param hrs 未来小时数,默认24
|
|
72
|
+
* @param options
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
private static tropicalCenterTwin;
|
|
46
76
|
private static pickIndex;
|
|
47
77
|
private static computeNumber;
|
|
48
78
|
}
|