{"version":3,"file":"TrackForecast.mjs","sources":["../../../../../../packages/sdk/plugins/Trackplayer/TrackForecast.ts"],"sourcesContent":["import L from 'leaflet'\nimport { CanvasShipUtils } from '@map-sdk/sdk/utils/CanvasShipUtils'\nimport { CommUtils } from '@map-sdk/sdk/utils/CommUtils'\nimport { WeatherPlayBack } from '@map-sdk/sdk/plugins/Trackplayer/WeatherPlayBack'\nimport { ElaneForecastData } from '@map-sdk/sdk/plugins/Trackplayer/ElaneForecastData'\nimport { GetCurrvoyageNew } from '@map-sdk/sdk/plugins/Trackplayer/GetCurrvoyageNew'\nimport { multipoint } from '@map-sdk/sdk/plugins/Trackplayer/multipoint'\nimport { WeatherServiceImpl } from '@map-sdk/sdk/plugins/weather/WeatherServiceImpl'\nimport type { Track } from '@map-sdk/sdk/plugins/Trackplayer/TrackServiceImpl'\nimport type { MyMap } from '@map-sdk/sdk/ShipxyAPISDK'\n\n/*\n * @Author: Yolo\n * @Date: 2024-06-14 13:22:00\n * @Last Modified by: Yolo\n * @Last Modified time: 2024-06-18 10:10:17\n * @Desc 航线预测\n */\nclass TrackForecast {\n  //目的港名称\n  destName = ''\n  destID = ''\n  mmsi = ''\n  //平均航速\n  speed = 0\n  hash: any[] = [] // 具体类型根据实际情况定义\n  //目的地缓存\n  hashDest: { [key: string]: any } = {}\n  //离开港\n  starPort = ''\n  str = ''\n  //离港时间\n  DepPortTime = true\n  //离港时区\n  startTimeZone = 99\n  //目的港时区\n  endTimeZone = 99\n  //本地时区\n  localZone = 8\n  private _map: MyMap\n  private markObjs: Record<string, any>\n  private hashMark: Record<string, any>\n  private yuceLine: any\n  private yucePoints: any\n  weathLy: any\n  weathLyGroup!: L.LayerGroup<any>\n  originShip: any\n  weatherPlayBack: any\n  type!: string\n  drawShipWeatherCanvas = new L.Canvas()\n\n  // 构造函数\n  constructor(map: MyMap) {\n    // 初始化操作\n    this._map = map\n    this.markObjs = {}\n    this.hashMark = {}\n    this.mmsi = '4131101'\n  }\n\n  //开始预测\n  begin() {\n    this.startTimeZone = 99\n    this.endTimeZone = 99\n    this.clearLineAndMark()\n    //目的地港口Id\n    const _destid = 621474\n    const _speed = 12\n\n    // TODO: 获取当前选中的船舶\n    const selShip = {\n      mmsi: 4131101,\n      lat: 38.727367,\n      lon: 121.13555,\n      lng: 121.13555,\n      ais_time: 1718341930,\n      lastdyn: 1718341930,\n    }\n\n    this.getForecastPoints(\n      this.mmsi,\n      _destid, //目的地港口\n      _speed, // 航速 必须大于等于 0\n      selShip.lat,\n      selShip.lon || selShip.lng,\n      selShip.lastdyn\n    )\n\n    // this.showForecastWeatherDetail('windColor')\n  }\n\n  //获取预测点数据\n  getForecastPoints(\n    mmsi: string,\n    destid: number,\n    speed: number,\n    lat: number,\n    lon: number,\n    aisTime: number\n  ) {\n    console.log(aisTime)\n    // this.hideWeatherLayer()\n    //mmsi=413370760&portid=12710&speed=7.9082375&lon=121.45565&lat=28.39393&ais_time=1568255324\n    const d = ElaneForecastData\n    if (d.status == 0) {\n      this.hashDest = d.data\n      const ps = d.data.route as any\n      this.endTimeZone =\n        d.data.porttimezone == undefined || d.data.porttimezone == ''\n          ? this.endTimeZone\n          : Number.parseFloat(d.data.porttimezone)\n      if (ps.length > 0) {\n        let tmp = [{ lon, lat }]\n        tmp = tmp.concat(ps)\n        let points: any[] = []\n\n        tmp.forEach((item, i) => {\n          if (tmp[i + 1])\n            points = points.concat(this.polylineArc(item, tmp[i + 1]))\n          else points.push(item)\n        })\n\n        //去除两点间距离小于100米点\n        const rpoints: any[] = []\n        points.forEach((p) => {\n          if (rpoints.length == 0) rpoints.push(p)\n          else {\n            if (\n              L.latLng(p).distanceTo(L.latLng(rpoints[rpoints.length - 1])) >\n              100\n            ) {\n              rpoints.push(p)\n            }\n          }\n        })\n\n        this.yucePoints = rpoints\n        this.drawForecastWeather(rpoints, speed)\n        this.yuceLine = this._map.trackService.addAndShow(\n          'forecast_yuceline',\n          rpoints.map((item) => ({\n            ...item,\n            lat: item.lat * 1000000,\n            lng: item.lng * 1000000,\n            lon: item.lon * 1000000,\n          })),\n          {\n            lineWeight: 2,\n            lineColor: '#dc3c96',\n            circleOverColor: '#f60',\n            dash: true,\n            dashArray: [5, 5],\n            middleShow: false,\n            isShowTip: false,\n            stopShow: false,\n            slowShow: false,\n            directionShow: false,\n            isShowLable: false,\n            isDilute: false,\n            startShow: false,\n            endShow: false,\n            startCircleType: 0,\n            endCircleType: 2,\n            tipHideTimeOut: 30000,\n            lableFields: ['name', 'mmsi'],\n          } as any,\n          { name: d.data.EnName, mmsi }\n        )\n        this.endMark(rpoints[rpoints.length - 1])\n        this.getCurrentVoyage(mmsi) //当前航次\n      } else {\n        this.yucePoints = []\n        console.log('未找到预测航线，请更换查询条件')\n      }\n    }\n  }\n\n  //绘制底部气象逻辑\n  drawForecastWeather(latLngs: any[], speed: number) {\n    if (!this.weathLy) {\n      this.weathLyGroup = L.layerGroup().addTo(this._map)\n      this.weathLyGroup.setZIndex(100)\n    }\n    this.weathLyGroup && this.weathLyGroup.clearLayers()\n    this.originShip = this._map.shipsService.getShipByMmsi(this.mmsi, false)\n    const result = this.inferPointWeather(latLngs, speed) as any\n    //挂在气象数据\n    const lst = this.dealWeather(\n      this.dealWeather(\n        latLngs.map((c: any) => {\n          c.weather =\n            ((result && result.data) || []).find(\n              (d: any) => d.time == c.forecasttime\n            ) || null\n          return c\n        })\n      )\n    )\n    this.hashDest.weather = lst\n    this.drawTypeChange()\n    lst.length &&\n      this._map.setZoom(this._map.getZoom() <= 5 ? 5 : this._map.getZoom() - 1)\n  }\n  drawTypeChange(type = 'windColor') {\n    const weatherDataList = this.hashDest.weather.slice()\n    if (!weatherDataList || weatherDataList.length === 0) {\n      return\n    }\n    this.type = type\n    this.showForecastWeatherDetail(type)\n  }\n\n  inferPointWeather(latLngs: any, speed: any) {\n    let c, distance, prev\n    //utc\n    const _utc = this.originShip.lastdyn * 1000\n    for (let i = 0; i < latLngs.length; i++) {\n      c = latLngs[i]\n      prev = latLngs[i - 1]\n      if (i == 0) c.forecasttimeUTC = _utc\n      else {\n        distance = L.latLng(c).distanceTo(prev)\n        //推测utc(1.852 * 1000)\n        const diff = distance / (speed * (1.852 * 1000))\n        c.forecasttimeUTC = prev.forecasttimeUTC + diff * 3600 * 1000\n      }\n      //气象数据利用前一包数据\n      c.forecasttime = new WeatherServiceImpl(this._map).getCurDate(\n        new Date(c.forecasttimeUTC),\n        false\n      )\n    }\n\n    // $.ajax({\n    //   url: 'http://127.0.0.1:4523/m1/3339587-0-default/oceanweather/v1/multipoint',\n    //   type: 'POST',\n    //   dataType: 'JSON',\n    //   data: {\n    //     x: latLngs.map((c: { lng: any }) => c.lng).join(','),\n    //     y: latLngs.map((c: { lat: any }) => c.lat).join(','),\n    //     source: 1,\n    //     type: '11,12,13,14,15,18',\n    //     time: '',\n    //     forecasttime: latLngs.map((item: { forecasttime: any }) => item.forecasttime).join(',')\n    //   }\n    // })\n    //tip 1 从接口中匹配出气象数据\n    return multipoint\n  }\n  //处理气象点展示\n  dealWeather(latLngs: any) {\n    //初始配置\n    const common = {\n      //#1976d24d\n      //color: [null,\"#1976d24d\",\"#00cc004d\",\"#eeeb3d4d\",\"#ee7F004d\",\"#EE40004d\",\"#B222224d\"],\n      color: [\n        null,\n        'rgba(25,118,210,.3)',\n        'rgba(0,204,0,.3)',\n        'rgba(238,235,61,.3)',\n        'rgba(238,127,0,.3)',\n        'rgba(238,64,0,.3)',\n        'rgba(178,34,34,.3)',\n      ],\n      k: [\n        -32767, 11.25, 33.75, 56.25, 78.75, 101.25, 123.75, 146.25, 168.75,\n        191.25, 213.75, 236.25, 258.75, 281.25, 303.75, 326.25, 348.75, 360,\n      ],\n    }\n    const wind = {\n      color: {\n        k: [-32767, 8, 11, 15, 19, 23, 56],\n        v: common.color,\n      },\n      type: {\n        k: [-32767, 5, 8, 11, 15, 19, 23, 27, 31, 35, 39, 43, 48, 56],\n        v: [\n          '未知',\n          '3~4级',\n          '4~5级',\n          '5~6级',\n          '6~7级',\n          '7~8级',\n          '8~9级',\n          '9~10级',\n          '10~11级',\n          '11~12级',\n          '12~13级',\n          '13~14级',\n          '14~15级',\n          '15~16级',\n        ],\n      },\n      dir: {\n        k: common.k,\n        v: [\n          '未知',\n          '南',\n          '南西南',\n          '西南',\n          '西西南',\n          '西',\n          '西西北',\n          '西北',\n          '北西北',\n          '北',\n          '北东北',\n          '东北',\n          '东东北',\n          '东',\n          '东东南',\n          '东南',\n          '南东南',\n          '南',\n        ],\n      },\n    }\n    const wave = {\n      color: {\n        k: [-32767, 1.4, 2.9, 3.9, 4.9, 5.9, 26],\n        v: common.color,\n      },\n      dir: {\n        k: common.k,\n        v: [\n          '未知',\n          '北',\n          '北东北',\n          '东北',\n          '东东北',\n          '东',\n          '东东南',\n          '东南',\n          '南东南',\n          '南',\n          '南西南',\n          '西南',\n          '西西南',\n          '西',\n          '西西北',\n          '西北',\n          '北西北',\n          '北',\n        ],\n      },\n    }\n    const getDescript = (\n      o: { [x: string]: string | any[]; k: any; v: any },\n      v: any\n    ) => {\n      let ret = v[0]\n      for (let i = 0; i < o['k'].length; i++) {\n        if (v <= o.k[i]) {\n          ret = o.v[i]\n          break\n        }\n      }\n      return ret\n    }\n    /* 处理气象显示 */\n    return latLngs.map(\n      (ll: {\n        weather: {\n          windColor?: any\n          windspeed: any\n          waveColor?: any\n          waveheight: any\n        }\n      }) => {\n        if (!ll.weather) {\n          ll.weather = {\n            windspeed: -32767,\n            waveheight: -32767,\n          }\n        }\n        if (ll.weather) {\n          ll.weather.windColor = getDescript(wind.color, ll.weather.windspeed)\n          ll.weather.waveColor = getDescript(wave.color, ll.weather.waveheight)\n        }\n        return ll\n      }\n    )\n  }\n\n  //结束点\n  endMark(p: Track) {\n    if (p == undefined) return\n    if (this.markObjs['yuce']) {\n      this._map.removeLayer(this.markObjs['yuce'])\n    }\n    const endPort = this.hashDest\n    const sig = L.icon({\n      iconUrl: 'https://cdn.xplusship.com/img/images/port.png',\n      iconSize: [16, 26], // size of the icon\n      shadowSize: [0, 10], // size of the shadow\n      iconAnchor: [8, 26], // point of the icon which will correspond to marker's location\n      shadowAnchor: [0, 0], // the same for the shadow\n      popupAnchor: [-2, -6],\n    })\n    const newP = CanvasShipUtils.GPSEncryptByMapToLatLng(\n      L.latLng(Number(p.lat), Number(p.lng)),\n      this._map\n    )\n    const m = L.marker([newP.lat, newP.lng], { icon: sig })\n    const d = Number.parseInt(`${endPort.sailing_time / 24}`)\n    const diffDay = d > 0 ? `${d} d ` : ''\n    const _utc =\n      new Date(endPort.eta.replace(new RegExp('-', 'g'), '/')).getTime() -\n      8 * 3600000\n    let htm = `<div class=\"forecast_popup\">\n    <div class=\"\" style=\"text-align:center\">\n    <b class=\"fz_14 text_overflow\"><span style=\"color:#2a8bbb\">${\n      endPort.EnName\n    } ${endPort.CnName} </span></b>\n    </div>\n    <p class=\"\">剩余航程：<span class=\"fz_12   text_overflow\">${\n      endPort.distance\n    } nm </span></p>\n    <p class=\"\">剩余时间：<span class=\"fz_12   text_overflow\">${diffDay}${(\n      endPort.sailing_time % 24\n    ).toFixed(1)} h </span>\n    </p>\n    <p class=\"\">预到时间：<span class=\"fz_12   text_overflow\"  title=\"${CommUtils.dataFormat(\n      new Date(_utc + 8 * 3600000),\n      'MM/DD HH:mm'\n    )}\" >${CommUtils.dataFormat(\n      new Date(_utc + 8 * 3600000),\n      'MM/DD HH:mm'\n    )}  UTC+8</span>\n    </p>`\n    if (this.endTimeZone != 99) {\n      htm += `<p class=\"\">预到时间：<span class=\"fz_12 text_overflow\">${CommUtils.dataFormat(\n        new Date(_utc + this.endTimeZone * 3600000),\n        'MM/DD HH:mm'\n      )} LT</span></p>`\n    }\n    htm += '<div class=\"clear\"></div>'\n    htm += '</div>'\n\n    //标签\n    m.bindTooltip(`${htm}`, {\n      direction: 'top',\n      permanent: true,\n      className: 'my_css_forecast',\n    })\n\n    //存储添加\n    this.markObjs['yuce'] = m\n    m.addTo(this._map)\n    m.openPopup()\n  }\n\n  //当前航次\n  getCurrentVoyage(mmsi: string) {\n    console.log(mmsi)\n    const d = GetCurrvoyageNew.data as any\n    if (d != null && d.deptime != '') {\n      const _startPort =\n        d.depCountryCode == 'CN' ? d.depportname_cn : d.depportname_en\n      this.starPort = _startPort\n      this.startTimeZone =\n        d.depportzone == undefined || d.depportzone == '未知'\n          ? this.startTimeZone\n          : Number.parseFloat(d.depportzone)\n    }\n  }\n\n  //显示气象列表\n  showForecastWeatherDetail(type: string | number) {\n    const list = this.hashDest.weather.slice()\n    if (!list || list.length == 0) return\n    const dealEmpty = (n: number) => (n == -32767 ? '--' : n)\n    const playSpeed = 60\n    const time = Math.ceil(Date.now() / 1000)\n    const points = list.map((item: any, index: number) => {\n      const getWeather = (weather: any) => {\n        if (weather.weather[type]) {\n          return {\n            ...weather.weather,\n            timeutc:\n              new Date(weather.weather.time.replace(/-/g, '/')).getTime() /\n              1000,\n            playtime: time + playSpeed * index,\n          }\n        }\n      }\n      return {\n        ...item,\n        weather: getWeather(item),\n      }\n    })\n\n    const exceptStyle = (v: number, type: string) => {\n      let style = ''\n      if (v == -32767) return style\n      switch (type) {\n        case 'windspeed':\n          if (v >= 8) style = 'background:rgba(0,204,0);color:#fff'\n          break\n        case 'waveheight':\n          if (v >= 1) style = 'background:#EEE5DE;'\n          break\n        case 'temperature':\n          if (v >= 30) style = 'background:#ff5a00;color:#fff'\n          if (v <= -10) style = 'background:#00ffdc;color:#fff'\n          break\n        case 'pressure':\n          if (v >= 1025) style = 'background:#96ff00;color:#fff'\n          if (v <= 1000) style = 'background:#00ffbe;color:#fff'\n\n          break\n      }\n      return style\n    }\n    const endPort = this.hashDest\n    const eta = new Date(\n      endPort.eta.replace(new RegExp('-', 'g'), '/')\n    ).getTime()\n    const _utc = eta - 8 * 3600000\n\n    const createHeader = () => {\n      return `\n    <p class=\"item\">时间</p>\n    <p class=\"item\">风速(米/秒)</p>\n    <p class=\"item\">风向(度)</p>\n    <p class=\"item\">浪高(米)</p>\n    <p class=\"item\">温度(摄氏度)</p>\n    <p class=\"item\">气压(hPa)</p>\n  `\n    }\n\n    let s = ''\n    s += '<div id=\"castbox\" class=\"castbox\">'\n    s += '</div>'\n    s += '<div class=\"forecast_left\">'\n    s += createHeader()\n    s += '</div>'\n    s += '<div class=\"forecast_table\">'\n    s += '<table><tr style=\"background: #eaeaea;\">'\n    points.forEach((item: any, index: number) => {\n      s += `<td  width=\"100px\" data-idx=\"${index}\" class=\"clickFlag\">${CommUtils.dataFormat(\n        item.forecasttimeUTC,\n        'MM-DD HH:ss'\n      )}</td>`\n    })\n    s += '</tr><tr>'\n    points.forEach((item: any, index: number) => {\n      const style = exceptStyle(item.weather.windspeed, 'windspeed')\n      s += `<td data-idx=\"${index}\" style=\"${style}\" >${dealEmpty(\n        item.weather.windspeed\n      )}</td>`\n    })\n    s += '</tr><tr>'\n    points.forEach((item: any, index: number) => {\n      const style = exceptStyle(item.weather.windspeed, 'windspeed')\n      s += `<td data-idx=\"${index}\"  style=\"${style}\">${dealEmpty(\n        item.weather.winddir\n      )}</td>`\n    })\n    s += '</tr><tr>'\n    points.forEach((item: any, index: number) => {\n      const style = exceptStyle(item.weather.waveheight, 'waveheight')\n      s += `<td data-idx=\"${index}\"  style=\"${style}\">${dealEmpty(\n        item.weather.waveheight\n      )}</td>`\n    })\n    s += '</tr><tr>'\n    points.forEach((item: any, index: number) => {\n      const style = exceptStyle(item.weather.temperature, 'temperature')\n      s += `<td data-idx=\"${index}\"  style=\"${style}\">${dealEmpty(\n        item.weather.temperature\n      )}</td>`\n    })\n    s += '</tr><tr>'\n    points.forEach((item: any, index: number) => {\n      const style = exceptStyle(item.weather.pressure, 'pressure')\n      s += `<td data-idx=\"${index}\"  style=\"${style}\">${dealEmpty(\n        item.weather.pressure\n      )}</td>`\n    })\n    s += '</tr></table>'\n    //如果\n    //if (_utc * 1000 > points[points.length - 1].forecasttimeUTC) {\n    //    if (points.length) s += ' <span class=\"forecast_tooltip\" style=\"text-align: center;margin-left: 350px;top: 84px;font-size: 13px;margin-right: 5px;position: absolute;display: inline-block;\"> 气象预测最多预测到未来7天</span>'\n    //}\n    //if (_utc * 1000 < points[points.length - 1].forecasttimeUTC && points.length)\n    if (points.length)\n      s += ` <span class=\"forecast_tooltip\" style=\"text-align: center;margin-left: 350px;top: 84px;font-size: 13px;margin-right: 5px;position:absolute;display: inline-block;\"> 预测气象仅预测到下一港,船舶预计${CommUtils.dataFormat(\n        new Date(_utc + 8 * 3600000),\n        'MM月DD日 HH:mm'\n      )}抵达港口</span>`\n    s += '</div><div class=\"forecast_right\">'\n    s +=\n      '<i class=\"fa fa-angle-double-right\" style=\"margin-top: 80px;\"></i><p style=\"font-size: 12px;\">更多</p>'\n    //s += '<p class=\"item more\">更多</p>'\n    //s += '<p class=\"item\">风速(米/秒)</p>'\n    //s += '<p class=\"item\">风向(度)</p>'\n    //s += '<p class=\"item\">浪高(米)</p>'\n    //s += '<p class=\"item\">温度(摄氏度)</p>'\n    //s += '<p class=\"item\">气压(hPa)</p>'\n    s += '</div>'\n    s += '</div>'\n    const forecastPanel = L.DomUtil.create(\n      'div',\n      'foreacast_panel',\n      this._map._container\n    )\n\n    // 更新HTML内容并淡入显示\n    if (forecastPanel) {\n      forecastPanel.innerHTML = s\n      forecastPanel.offsetHeight // 触发重绘，以便动画生效\n      forecastPanel.style.opacity = '1' // 使用CSS opacity实现淡入效果，需预先在CSS中设置opacity: 0;\n    }\n    // 获取元素\n    // const  = document.querySelector('.foreacast_panel') as HTMLElement\n    const forecastTooltip = document.querySelector(\n      '.forecast_tooltip'\n    ) as HTMLElement\n    const forecastRight = document.querySelector(\n      '.forecast_right'\n    ) as HTMLElement\n    const forecast = document.querySelector(\n      '.foreacast_panel table'\n    ) as HTMLElement\n\n    // 设置宽度\n    const width = 110 * points.length\n    forecast && (forecast.style.width = `${width}px`)\n\n    // 判断并显示/隐藏右侧按钮\n    if (window.innerWidth - 140 > width) {\n      forecastRight.style.display = 'none'\n    } else {\n      forecastRight.style.display = 'block'\n    }\n\n    // 调整tooltip的左边距\n    if (forecastTooltip) forecastTooltip.style.marginLeft = `${width + 20}px`\n    const data = points.map((item: { weather: any }) => item.weather)\n    let currentTimePosition =\n      (this.weatherPlayBack && this.weatherPlayBack.currentTimePosition) || 0\n    this.weatherPlayBack = new WeatherPlayBack({\n      container: document.querySelector('#castbox'),\n      data,\n      playSpeed,\n      playCallBack: (time: number) => {\n        let idx = -1\n        for (const [i, datum] of data.entries()) {\n          const c = datum.playtime\n          if (c >= time) {\n            idx = i\n            break\n          }\n        }\n        const playLst = points.slice(0, idx + 1)\n        this.playWeatherLayer(playLst)\n        if (idx > 0) {\n          let angle = null\n          //船舶方向\n          if (time > currentTimePosition && idx < data.length - 1)\n            angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n              {\n                lat: points[idx].lat,\n                lng: points[idx].lng,\n              },\n              {\n                lat: points[idx + 1].lat,\n                lng: points[idx + 1].lng,\n              }\n            )\n          else if (points[idx - 1])\n            angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n              {\n                lat: points[idx - 1].lat,\n                lng: points[idx - 1].lng,\n              },\n              {\n                lat: points[idx].lat,\n                lng: points[idx].lng,\n              }\n            )\n          this.updateForecastShip(points[idx], 'playClick', angle)\n        } else {\n          this._map.shipsService.deleteShipByShipID(this.originShip.shipid)\n          this.originShip && this._map.shipsService.addShips([this.originShip])\n        }\n        currentTimePosition = time\n      },\n      close: () => {\n        const forecastWeather = document.querySelector(\n          '#forecast_weather'\n        ) as HTMLElement\n        forecastWeather && forecastWeather.click()\n        //船舶回归初始位置\n        this._map.shipsService.deleteShipByShipID(this.originShip.shipid)\n        this.originShip && this._map.shipsService.addShips([this.originShip])\n\n        this.weatherPlayBack && this.weatherPlayBack.removeAll()\n        this._map.shipsService.restoreZIndex()\n        this.hideWeatherLayer()\n      },\n      clearLayer: () => {\n        this.weathLyGroup && this.weathLyGroup.clearLayers()\n      },\n    })\n    this.playWeatherLayer(points)\n    //事件\n    this.tableEvt(points)\n  }\n\n  tableEvt(points: any[]) {\n    const clickFlagCells = document.querySelectorAll(\n      '.foreacast_panel table td.clickFlag'\n    )\n\n    clickFlagCells.forEach((cell: any) => {\n      cell.addEventListener('click', () => {\n        if (this.weatherPlayBack) this.weatherPlayBack.playStop()\n\n        const selectedCells = document.querySelectorAll(\n          '.foreacast_panel table td.areaplayer-td-sel'\n        )\n        selectedCells.forEach((cell) => {\n          cell.classList.remove('areaplayer-td-sel')\n        })\n\n        const idx = Number(cell.dataset.idx)\n        const selectedCell = document.querySelector(\n          `.foreacast_panel table td[data-idx='${idx}']`\n        )\n        let angle = null\n        if (selectedCell) {\n          selectedCell.classList.add('areaplayer-td-sel')\n          if (points[idx + 1]) {\n            angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n              { lat: points[idx].lat, lng: points[idx].lng },\n              { lat: points[idx + 1].lat, lng: points[idx + 1].lng }\n            )\n          } else if (points[idx - 1]) {\n            angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n              { lat: points[idx - 1].lat, lng: points[idx - 1].lng },\n              { lat: points[idx].lat, lng: points[idx].lng }\n            )\n          }\n          this.updateForecastShip(points[idx], 'click', angle)\n        } else {\n          if (points[1]) {\n            angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n              { lat: points[0].lat, lng: points[0].lng },\n              { lat: points[1].lat, lng: points[1].lng }\n            )\n          }\n          this.updateForecastShip(points[0], 'click', angle)\n        }\n      }) // 维持正确的this上下文\n    })\n\n    const forecastRight = document.querySelector('.forecast_right')\n    if (forecastRight) {\n      forecastRight.addEventListener('click', () => {\n        const forecast = document.querySelector(\n          '.forecast_table'\n        ) as HTMLElement\n        const forecastTable = document.querySelector(\n          '.forecast_table table'\n        ) as HTMLElement\n        if (forecastTable && forecast) {\n          const tableWidth = forecastTable.offsetWidth\n          const containerWidth = forecast.offsetWidth\n          const currentScroll = forecast.scrollLeft\n          const maxScroll = tableWidth - containerWidth\n\n          forecast.scrollLeft =\n            currentScroll < maxScroll ? currentScroll + containerWidth : 0\n        }\n      })\n    }\n\n    // 由于原代码中的on和off函数是为了兼容性封装的事件监听和移除，这里直接使用了addEventListener和removeEventListener，因此这部分不再重复定义。\n\n    const forecastTableElement = document.querySelector('.forecast_table')\n\n    if (forecastTableElement) {\n      forecastTableElement.addEventListener('mousedown', (e: any) => {\n        e.target.style.cursor = 'move'\n        const startX = e.pageX\n\n        forecastTableElement.addEventListener('mousemove', (ev: any) => {\n          const left = ev.pageX - startX\n          forecastTableElement.scrollTo({\n            left: forecastTableElement.scrollLeft - left,\n            behavior: 'smooth',\n          })\n        })\n\n        forecastTableElement.addEventListener('mouseup', (e: any) => {\n          e.target.style.cursor = 'default'\n          // forecastTableElement.removeEventListener('mousemove', moveHandler)\n        })\n\n        e.preventDefault()\n      })\n    }\n  }\n\n  //更新预测船位置\n  updateForecastShip(\n    next: { lat: any; lng: any; forecasttimeUTC: number },\n    from: string,\n    nextAngle: number | null\n  ) {\n    const ship = this._map.shipsService.getShipByMmsi('4131101', false)\n\n    if (next && ship) {\n      //更新船位\n      let angle = CanvasShipUtils.getAngleByLatLngToBigCircle(\n        { lat: ship.lat, lng: ship.lng },\n        { lat: next.lat, lng: next.lng }\n      )\n      if (angle < 0) angle += 360\n      if (angle > 360) angle -= 360\n      //点击船舶 取船舶\n      if (from)\n        angle = nextAngle || (this.originShip && this.originShip.hdg) || 0\n      this._map.shipsService.deleteShipByShipID(ship.shipid)\n      const forecastShip = Object.assign(ship, {\n        lat: next.lat,\n        lng: next.lng,\n        hdg: angle,\n        hdg_source: angle,\n        cog: angle,\n        tracks: [],\n        bodyArea: [],\n        istop: true,\n        lastdyn: next.forecasttimeUTC / 1000,\n      })\n      this._map.shipsService.addShips([forecastShip] as any)\n    }\n    this._map.shipsService.setZIndex(450)\n  }\n\n  playWeatherLayer(lst: any = []) {\n    this.weathLyGroup && this.weathLyGroup.clearLayers()\n    if (!lst || lst.length <= 1) return\n\n    const type = this.type || 'windColor'\n    //绘制线\n    const latLngs: any = []\n    const colors: any = []\n    lst.forEach((p: any) => {\n      // const next = lst[i + 1]\n      const latlng = CanvasShipUtils.GPSEncryptByMapToLatLng(p, this._map)\n      if (p.weather[type]) {\n        latLngs.push(latlng)\n        colors.push(p.weather[type])\n      }\n    })\n    const polycolor = L.polycolor(latLngs, {\n      renderer: this.drawShipWeatherCanvas,\n      weight: 20,\n      colors,\n      interactive: true,\n    })\n    polycolor.on('click', () => {\n      ///alert(e);\n      // var layerPoint = this._map.latLngToContainerPoint(e.target._source.point[0]);\n      //alert(layerPoint);\n    })\n    this.weathLyGroup.addLayer(polycolor)\n  }\n\n  //打开窗体\n  showWin(mmsi: string, dest: string) {\n    //本地与utc的时差\n    this.localZone = (new Date().getTimezoneOffset() / 60) * -1\n    //清楚绘制\n    this.clearLineAndMark()\n    this.destName = dest || ''\n    this.mmsi = mmsi\n    let htm = ''\n    htm += '<div class=\"forecast_box\">'\n    htm += `    <p>目的港：<input type=\"text\" id=\"_f_dest\" class=\"\" placeholder=\"请输入目的港\" value=\"${dest}\" maxlength=\"20\"  style=\"width:186px\"   /></p>`\n    htm +=\n      '    <p style=\"position:relative\">&nbsp;&nbsp;&nbsp;速度：<input type=\"text\" id=\"_f_speed\"  class=\"_number\"  maxlength=\"4\"   style=\"width:52px;margin-right:28px\"  /><span class=\"_speedup\"> </span><span class=\"_speeddown\"> </span>节<a href=\"javascript:void(0)\" style=\"margin-left:30px\" onclick=\"elane.forecast.begin()\" class=\"btn blue_btn\">预测</a></p>'\n    htm += '    <p style=\"position:relative\">'\n    htm +=\n      '    <i id=\"forecast_weather\" class=\"fa fa-toggle-off\" style=\"display: inline-block;font-size: 25px;line-height: 28px;margin-top: 12px;margin-left: 13px;color: #aaa;\">'\n    htm +=\n      '    <span style=\"font-size: 14px;margin-left: 8px;height: 28px;vertical-align: bottom;color: #666;\">显示预测气象</span></i></p>'\n    htm +=\n      '    <p style=\"color:#f60;margin-top: -4px;text-align:left;padding-left: 66px;\" ><span class=\"_forecast_tip\" style=\"display:none\"></span></p>'\n    htm +=\n      '    <p style=\"color:#f60;margin-top:10px;text-align:left;padding-left:10px\" ><span class=\"_forecast_tip\" style=\"display:none\"></span></p>'\n    htm += '</div>'\n    this.clearLineAndMark()\n    //关闭播放\n    this.weatherPlayBack && this.weatherPlayBack.removeAll()\n    this.originShip &&\n      this._map.shipsService.deleteShipByShipID(this.originShip.shipid)\n    this.originShip && this._map.shipsService.addShips([this.originShip])\n    this._map.shipsService.restoreZIndex()\n    this.yucePoints = []\n    // this.getSpeetByDest(this.mmsi, dest)\n    // this.bindEvent()\n  }\n  //关闭窗体\n  closeWin() {\n    this.clearLineAndMark()\n  }\n\n  //清空线和点\n  clearLineAndMark() {\n    if (this.markObjs['yuce']) {\n      this._map.trackService.remove('forecast_yuceline')\n      this._map.removeLayer(this.markObjs['yuce'])\n    }\n    if (this.markObjs['history']) {\n      this._map.trackService.remove('forecast_historyline')\n      this._map.removeLayer(this.markObjs['history'])\n    }\n    this.hideWeatherLayer()\n  }\n\n  hideWeatherLayer() {\n    this.weathLyGroup && this.weathLyGroup.clearLayers()\n    document.querySelectorAll('.foreacast_panel').forEach((element: any) => {\n      element.style.display = 'none'\n    })\n    //map.shipsService.setZIndex(300)\n    // this.restoreMapCss()\n  }\n\n  polylineArc(\n    _from: { lon: any; lat: any; lng?: any },\n    _to: { lon: any; lat: any; lng?: any }\n  ) {\n    _from.lng = _from.lng || _from.lon\n    _to.lng = _to.lng || _to.lon\n\n    const pointDis = 50 * 1852\n\n    const _GCinterpolate = (f: number) => {\n      const A = Math.sin((1 - f) * d) / Math.sin(d)\n      const B = Math.sin(f * d) / Math.sin(d)\n      const x =\n        A * Math.cos(fromLat) * Math.cos(fromLng) +\n        B * Math.cos(toLat) * Math.cos(toLng)\n      const y =\n        A * Math.cos(fromLat) * Math.sin(fromLng) +\n        B * Math.cos(toLat) * Math.sin(toLng)\n      const z = A * Math.sin(fromLat) + B * Math.sin(toLat)\n\n      const latInterpol =\n        (180 / Math.PI) * Math.atan2(z, Math.sqrt(x ** 2 + y ** 2))\n      let lngInterpol = (180 / Math.PI) * Math.atan2(y, x)\n\n      const diff = lngInterpol - (fromLng * 180) / Math.PI\n\n      const trunc = (n: number) => {\n        return Math[n > 0 ? 'floor' : 'ceil'](n)\n      }\n      if (diff < 0) {\n        lngInterpol = lngInterpol - trunc((diff - 180) / 360) * 360\n      } else {\n        lngInterpol = lngInterpol - trunc((diff + 180) / 360) * 360\n      }\n      return [latInterpol, lngInterpol]\n    }\n\n    const _GCarc = (npoints: number) => {\n      const arrArcCoords = []\n      const delta = 1.0 / (npoints - 1)\n      for (let i = 0; i < npoints; i++) {\n        const step = delta * i\n        const coordPair = _GCinterpolate(step)\n        arrArcCoords.push(coordPair)\n      }\n      return arrArcCoords\n    }\n\n    let arrLatLngs\n    let fromLat = _from.lat\n    let fromLng = _from.lng\n    let toLat = _to.lat\n    let toLng = _to.lng\n    fromLat = (fromLat * Math.PI) / 180\n    fromLng = (fromLng * Math.PI) / 180\n    toLat = (toLat * Math.PI) / 180\n    toLng = (toLng * Math.PI) / 180\n    const d =\n      2.0 *\n      Math.asin(\n        Math.sqrt(\n          Math.sin((fromLat - toLat) / 2.0) ** 2 +\n            Math.cos(fromLat) *\n              Math.cos(toLat) *\n              Math.sin((fromLng - toLng) / 2.0) ** 2\n        )\n      )\n    if (d === 0) {\n      arrLatLngs = [[_from.lat, _from.lng]]\n    } else {\n      const arcpoints = Math.floor(\n        L.latLng(_to.lat, _to.lng).distanceTo(L.latLng(_from.lat, _from.lng)) /\n          pointDis\n      )\n      if (arcpoints > 1) arrLatLngs = _GCarc(arcpoints)\n      else arrLatLngs = [[_from.lat, _from.lng]]\n    }\n    return arrLatLngs.map((p: any[]) => {\n      return {\n        lat: p[0],\n        lng: p[1],\n      }\n    })\n  }\n}\n\nexport { TrackForecast }\n"],"names":["B","constructor","e","this","destName","destID","mmsi","speed","hash","hashDest","starPort","str","DepPortTime","startTimeZone","endTimeZone","localZone","drawShipWeatherCanvas","f","Canvas","_map","markObjs","hashMark","begin","clearLineAndMark","getForecastPoints","s","i","o","n","t","a","C","status","data","p","route","porttimezone","Number","parseFloat","length","c","lon","lat","concat","m","forEach","r","g","polylineArc","push","y","latLng","distanceTo","yucePoints","drawForecastWeather","yuceLine","trackService","addAndShow","map","lng","lineWeight","lineColor","circleOverColor","dash","dashArray","middleShow","isShowTip","stopShow","slowShow","directionShow","isShowLable","isDilute","startShow","endShow","startCircleType","endCircleType","tipHideTimeOut","lableFields","name","EnName","endMark","getCurrentVoyage","weathLy","weathLyGroup","layerGroup","addTo","setZIndex","clearLayers","originShip","shipsService","getShipByMmsi","inferPointWeather","dealWeather","weather","find","time","forecasttime","drawTypeChange","setZoom","getZoom","slice","type","showForecastWeatherDetail","lastdyn","forecasttimeUTC","E","getCurDate","Date","P","color","k","v","dir","windspeed","waveheight","windColor","waveColor","yuce","removeLayer","icon","iconUrl","iconSize","shadowSize","iconAnchor","shadowAnchor","popupAnchor","S","GPSEncryptByMapToLatLng","marker","parseInt","sailing_time","eta","replace","RegExp","getTime","CnName","distance","toFixed","M","dataFormat","bindTooltip","direction","permanent","className","openPopup","D","deptime","depCountryCode","depportname_cn","depportname_en","depportzone","l","Math","ceil","now","h","b","timeutc","playtime","d","winddir","temperature","pressure","DomUtil","create","_container","innerHTML","offsetHeight","style","opacity","document","querySelector","u","L","width","window","innerWidth","display","marginLeft","_","w","weatherPlayBack","currentTimePosition","x","container","playSpeed","playCallBack","T","entries","playWeatherLayer","getAngleByLatLngToBigCircle","updateForecastShip","deleteShipByShipID","shipid","addShips","close","click","removeAll","restoreZIndex","hideWeatherLayer","clearLayer","tableEvt","querySelectorAll","addEventListener","playStop","classList","remove","dataset","idx","add","offsetWidth","scrollLeft","target","cursor","pageX","scrollTo","left","behavior","preventDefault","hdg","Object","assign","hdg_source","cog","tracks","bodyArea","istop","polycolor","renderer","weight","colors","interactive","on","addLayer","showWin","getTimezoneOffset","closeWin","history","sin","cos","PI","atan2","sqrt","asin","floor"],"mappings":"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"}