import 'ol/ol.css' //引入样式
import Map from 'ol/Map' //地图
import View from 'ol/View' // 地图视图
import TileLayer from 'ol/layer/Tile' //地图图层
import {Group} from 'ol/layer' //地图图层
import OSM from 'ol/source/OSM'
import XYZ from 'ol/source/XYZ'
import TileWMS from 'ol/source/TileWMS'
import {getHeight, getWidth} from 'ol/extent'
import {transform, fromLonLat, get} from 'ol/proj' //坐标系转换
import TileGrid from 'ol/tilegrid/TileGrid'
import Projection from 'ol/proj/Projection'
import Vector from 'ol/layer/Vector' //图层
import SourceVector from 'ol/source/Vector' //资源
import ScaleLine from 'ol/control/ScaleLine' //比例尺
import FullScreen from 'ol/control/FullScreen' //比例尺
import Feature from 'ol/Feature' //矢量对象
import Overlay from 'ol/Overlay' //矢量对象
import Point from 'ol/geom/Point' //点
import CircleGeom from 'ol/geom/Circle'
import Icon from 'ol/style/Icon'
import LineString from 'ol/geom/LineString' //线
import Polygon from 'ol/geom/Polygon' //线
import intSelect from 'ol/interaction/Select' //地图监听函数
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom' //滚轮放大缩小地图
import Draw from 'ol/interaction/Draw' //画线工具
import Snap from 'ol/interaction/Snap'
import MousePosition from 'ol/control/MousePosition' //实时显示鼠标位置
import {createBox} from 'ol/interaction/Draw' //画线工具
import dayjs from "dayjs";
import {getArea, getLength, getDistance, DEFAULT_RADIUS} from 'ol/sphere'
import shipStyle from './style'
import {formatDate} from '../filters/filters'
import {register} from 'ol/proj/proj4'
import proj4 from 'proj4'
import ImageCanvasSource from 'ol/source/ImageCanvas'
import ImageLayer from 'ol/layer/Image'
import XYZSource from 'ol/source/XYZ'
import GeoJSON from 'ol/format/GeoJSON'
import {OlClient, Factor} from 'weatherv'
import WKT from 'ol/format/WKT'

// import { GetShipMessage } from '../../api/index'
import {Circle, Fill, Stroke, Style, Text} from 'ol/style.js'
import unByKey from 'ol/Observable.js'

const shipMap = new Object({
  map: null, //地图
  view: null, //地图的资源
  layer: null, //地图的图层
  shipSource: null, //船舶的资源
  portSource: null,//港口资源
  shipSourceStandby: null, //船舶的备用资源
  shipLayer: null, //船舶的图层
  shipStyle: null, //船舶样式
  shipClick: null, //船舶的点击函数
  pathLineSource: null, //轨迹路径资源层
  pathLineLayer: null, //轨迹路径图层
  portLayer: null,//港口图层
  pathPointSource: null, //轨迹点资源层
  pathPointLayer: null, //轨迹点图层
  selectSource: null, //船舶选择资源
  selectLayer: null, //船舶选择图层
  sourceList: [], //资源数组
  layerList: [], //图层数组
  drawPointSource: null, //标记资源
  drawPointLayer: null, //标记图层
  drawPointDraw: null, //标记画笔
  measureTooltipElement: null, //轨迹显示距离的div
  //我的修改
  drawRingDraw: null,
  maxpoint: Infinity,
  __selectPort: null,//点击港口

})
let mapToolOver = []
const shipFun = new Object({})
shipFun.setmap = function (map) {
  shipMap.map = map
}

var __pathData = {};
var __pathDrawData = {};
var __pathArray = {};
const abcLineData = [
  [
      11822129.922245655,
      2284881.0700673275
  ],
  [
      12022505.005673546,
      2284881.0700673275
  ],
  [
      12170927.282748217,
      2286852.8770299805
  ],
  [
      12356463.478053365,
      2309658.5222366545
  ],
  [
      12419544.522836259,
      2309658.5222366545
  ],
  [
      13503054.233224085,
      2309658.5222366545
  ]
]
//地图
shipMap.view = new View({
  projection: 'EPSG:3857', //使用这个坐标系
  center: transform([120, 36], 'EPSG:4326', 'EPSG:3857'), //定义中心位置
  zoom: 6, //定义等级
  minZoom: 3, //最小等级
  maxZoom: 18 //最大等级
  // rotation:120
})
shipMap.layer = new TileLayer({
  source: new OSM(), //资源
  zIndex: 1
})

var projection_3395 = new Projection({
  code: 'EPSG:3395',
  extent: [-20026376.39, -15496570.74, 20026376.39, 18764656.23],
  units: 'm',
  axisOrientation: 'neu'
})

proj4.defs(
  'EPSG:3395',
  '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
)
register(proj4)

var seaMapPath = 'http://cm191.myships.com/ChartMap'

function getSeaMapSource() {
  var projectionExtent = get('EPSG:3857').getExtent()
  var height = getHeight(projectionExtent)
  var width = getWidth(projectionExtent)
  var tileSize = [256, 256]
  var maxResolution = Math.max(width / tileSize[0], height / tileSize[1])
  var length = 18 + 1
  var resolutions = new Array(length)
  for (var z = 0; z < length; ++z) {
    resolutions[z] = maxResolution / Math.pow(2, z)
  }
  var tilegrid = new TileGrid({
    origin: [projectionExtent[0], projectionExtent[3]],
    tileSize: tileSize,
    resolutions: resolutions
  })
  shipMap.view.on('change:resolution', function (event) {
    freshPath();
  });


  function freshPath() {
    for (var pathId in __pathData) {
      var data = __pathData[pathId];
      var re = __makePathData(data, shipMap.map, pathId);
      var old_re = __pathDrawData[pathId];
      if (!old_re || re.length != old_re.length) {
        __pathDrawData[pathId] = re;
        var ids = __pathArray[pathId];
        if (ids && ids.length > 0) {
          ids.forEach(function (item, index) {
            var f = shipMap.sourceList.pathLineSource.getFeatureById(item);
            var f2 = shipMap.sourceList.pathPointSource.getFeatureById(item);
            if (f || f2) {
              shipMap.sourceList.pathLineSource.removeFeature(f);
              shipMap.sourceList.pathPointSource.removeFeature(f2);
            }
          })
        }
        __drawPathData(re, pathId);
      }
    }
  }

  function padLeft(num, val) {
    return (new Array(num).join('0') + val).slice(-num)
  }

  return new XYZ({
    cacheSize: 256,
    projection: projection_3395,
    tileGrid: tilegrid,
    tileUrlFunction: function (xyz, obj1, obj2) {
      if (!xyz) {
        return ''
      }
      var z = xyz[0] - 2
      if (z <= -1) return ''
      var x = Math.abs(xyz[1])
      var y = Math.abs(xyz[2])
      x = 'C' + padLeft(8, x.toString(16))
      y = 'R' + padLeft(8, y.toString(16))
      z = 'L' + padLeft(2, z)
      return seaMapPath + '/' + z + '/' + y + '/' + x + '.jpg'
    }
  })
}

shipMap.seaView = getSeaMapSource()

shipMap.seaLayer = new TileLayer({
  preload: Infinity,
  source: shipMap.seaView,
  zIndex: 1
})
//卫星图
shipMap.sateView = new XYZ({
  url:
    'http://mt{0-1}.google.cn/maps/vt?lyrs=s@198&hl=zh-CN&gl=CN&&x={x}&y={y}&z={z}'
})
shipMap.sateLayer = new TileLayer({
  preload: Infinity,
  source: shipMap.sateView,
  zIndex: 1
})


shipMap.tdtLayer = new Group({
  layers: [
    new TileLayer({
      source: new XYZ({
        crossOrigin: 'anonymous',
        url: 'https://t{0-7}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=f68226212bdd3ffed1b0bb884f81ddda'
      })
    }),
    new TileLayer({
      source: new XYZ({
        crossOrigin: 'anonymous',
        url: 'https://t{0-7}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=f68226212bdd3ffed1b0bb884f81ddda'
      })
    })
  ]
})
//分布图
shipMap.distributeLayer = new TileLayer({
  preload: Infinity,
  visible: true,
  source: new TileWMS({
    url: 'https://g.myships.com/dist/wms',
    params: {
      FORMAT: 'image/png',
      VERSION: '1.1.0',
      tiled: true,
      LAYERS: 'myships:pos_latest_3857_1hour',
      exceptions: 'application/vnd.ogc.se_inimage',
      tilesOrigin: -20037508.342789244 + ',' + -20048966.1040146
    }
  }),
  zIndex: 20
})


//船舶
shipMap.sourceList.shipSource = new SourceVector()
shipMap.layerList.shipLayer = new Vector({
  source: shipMap.sourceList.shipSource,
  name: 'shipLayer',
  style: (f, r) => shipStyle.newshipStyle(f, r, shipMap.map),
  zIndex: 21
})
//船舶
shipMap.sourceList.carSource = new SourceVector()
shipMap.layerList.carLayer = new Vector({
  source: shipMap.sourceList.carSource,
  name: 'carLayer',
  style: (f, r) => shipStyle.carStyle(f, r, shipMap.map),
  zIndex: 22
})


// 港资源
shipMap.sourceList.portSource = new SourceVector()
shipMap.layerList.portLayer = new Vector({
  source: shipMap.sourceList.portSource,
  zIndex: 15
})

// 泊位图层资源
shipMap.sourceList.berthSource = new SourceVector()
shipMap.layerList.berthLayer = new Vector({
  source: shipMap.sourceList.berthSource,
  zIndex: 17
})

//轨迹
shipMap.sourceList.pathLineSource = new SourceVector()
shipMap.layerList.pathLineLayer = new Vector({
  source: shipMap.sourceList.pathLineSource,
  zIndex: 4
})

// 轨迹上的点
shipMap.sourceList.pathPointSource = new SourceVector()
shipMap.layerList.pathPointLayer = new Vector({
  source: shipMap.sourceList.pathPointSource,
  zIndex: 5
})


// 地图上显示的点
shipMap.sourceList.PointSource = new SourceVector()
shipMap.layerList.PointLayer = new Vector({
  source: shipMap.sourceList.PointSource,
  zIndex: 5
})

var lineStyle = new Style({
  stroke: new Stroke({
    color: '#FF0000',
    width: 1
  })
});
shipMap.sourceList.jjxSource = new SourceVector();
shipMap.layerList.jjxLayer = new Vector({
  source: shipMap.sourceList.jjxSource,
  style: lineStyle,
  visible: false,
  zIndex: 3
});

shipMap.sourceList.taifeng = new SourceVector();
shipMap.layerList.taifengLayer = new Vector({
  source: shipMap.sourceList.taifeng,
  style: function (feature, res) {
    var style;
    var t = parseInt(feature.get('t'));
    if (t == 1 || t == 0)//历史当前点
      style = getTyphoonStyle(feature, res);
    else if (t == 2)//预报点
      style = getTyphoonFutureStyle(feature, res);
    else if (t == 3) {
      style = getTyphoonStyleLine(feature, res);
      return style;
    } else {
      style = getTyphoonFutureStyle(feature, res);
    }
    return style;
  }
});
shipMap.layerList.taifengLayer.setZIndex(20);

//定义区间
var min = [41.5, 10.8, 17.2, 24.5, 32.7, 51];
var max = [50.9, 17.1, 24.4, 32.6, 41.4, 1000];

function getTyphoonStyle(f, r) {
  var maxWindSpeed = f.get('maxWindSpeed');
  var level = 0;
  for (var i = 0; i <= 5; i++) {
    if (min[i] <= maxWindSpeed && maxWindSpeed <= max[i]) {
      level = i;
    }
  }
  var color = '';
  switch (level) {
    case 0:
      color = '#EB4FA0'
      break;
    case 1:
      color = 'blue'
      break;
    case 2:
      color = 'yellow'
      break;
    case 3:
      color = 'orange'
      break;
    case 4:
      color = 'red'
      break;
    case 5:
      color = 'purple'
      break;
    default:
      break;
  }

  var s = new Style({
    fill: new Fill({
      color: color
    }),
    stroke: new Stroke({
      color: color,
      width: 2
    }),
    image: new Circle({
      radius: 4,
      fill: new Fill({
        color: color
      })
    })
  });
  if (r < 3000) {
    var ntext = new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({
        color: color
      }),
      stroke: new Stroke({
        color: "#FFF",
        width: 3
      }),
      textBaseline: "bottom",
      offsetX: 8,
      offsetY: -8,
      text: f.get("forecast")
    });
    s.setText(ntext);
  }

  const style2 = new Style({
    text: new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({
        color: '#fff'
      }),
      stroke: new Stroke({
        color: "black",
        width: 1
      }),
      textBaseline: "bottom",
      offsetX: 8,
      offsetY: -8,
      text: f.get("time")
    })
  })
  return [s, style2];
}

function getTyphoonFutureStyle(f, r) {
  var maxWindSpeed = f.get('maxWindSpeed');

  var level = 0;
  for (var i = 0; i <= 5; i++) {
    if (min[i] <= maxWindSpeed && maxWindSpeed <= max[i]) {
      level = i;
    }
  }
  var color = '';
  switch (level) {
    case 0:
      color = '#EB4FA0'
      break;
    case 1:
      color = 'blue'
      break;
    case 2:
      color = 'yellow'
      break;
    case 3:
      color = 'orange'
      break;
    case 4:
      color = 'red'
      break;
    case 5:
      color = 'purple'
      break;
    default:
      break;
  }
  var s = new Style({
    fill: new Fill({
      color: color
    }),
    stroke: new Stroke({
      color: color,
      lineDash: [10, 10],
      width: 2
    }),
    image: new Circle({
      radius: 4,
      fill: new Fill({
        color: color
      })
    })
  });
  if (r < 3000) {
    var t = f.get('temp');
    if (t != 1) {
      var ntext = new Text({
        textAlign: "left",
        font: '10px Microsoft YaHei',
        fill: new Fill({
          color: color
        }),
        stroke: new Stroke({
          color: "#FFF",
          width: 3
        }),
        textBaseline: "bottom",
        offsetX: 8,
        offsetY: -8,
        text: f.get("forecast")
      })
      s.setText(ntext);
    }
  }
  const style2 = new Style({
    text: new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({
        color: '#fff'
      }),
      stroke: new Stroke({
        color: "black",
        width: 1
      }),
      textBaseline: "bottom",
      offsetX: 8,
      offsetY: -8,
      text: f.get("time")
    })
  })


  return [s, style2];
}

function getTyphoonStyleLine(f, r) {
  var ss = [];
  var s = new Style({
    fill: new Fill({
      color: 'rgba(255, 120,120, 0.8)'
    }),
    stroke: new Stroke({
      color: 'rgba(255, 120,120, 0.8)',
      width: 2
    }),
    image: new Circle({
      radius: 4,
      fill: new Fill({
        color: 'rgba(255,120,120, 0.8)'
      })
    })
  });
  if (r < 3000) {
    var ntext = new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({
        color: "RGB(255,120,120)"
      }),
      stroke: new Stroke({
        color: "#FFF",
        width: 3
      }),
      textBaseline: "bottom",
      offsetX: 8,
      offsetY: -8,
      text: f.get("forecast")
    });
    s.setText(ntext);
  }
  ss.push(s);
  var geometry = f.getGeometry();
  geometry.forEachSegment(function (start, end) {
    var dx = end[0] - start[0];
    var dy = end[1] - start[1];
    var rotation = Math.atan2(dy, dx);
    // arrows
    ss.push(new Style({
      geometry: new Point(end),
      image: new Icon({
        src: 'images/msmap/arrow100.png',
        anchor: [1.5, 0.5],
        rotateWithView: true,
        rotation: -rotation
      })
    }));
  });
  return ss;
}

//船舶选择框
shipMap.sourceList.selectSource = new SourceVector()
shipMap.layerList.selectLayer = new Vector({
  source: shipMap.sourceList.selectSource,
  zIndex: 21
})

//标记画笔的添加
shipMap.drawPointSource = new SourceVector()
shipMap.drawPointLayer = new Vector({
  source: shipMap.drawPointSource,
  zIndex: 7
})
shipMap.drawPointDraw = new Draw({
  source: shipMap.drawPointSource,
  type: 'Point' //可以根据类型改变
})
//测距画笔的添加
shipMap.drawRingSource = new SourceVector()
shipMap.drawRingLayer = new Vector({
  source: shipMap.drawRingSource,
  zIndex: 8,
  style: shipStyle.ceJuStyle
})
//我的修改
shipMap.drawRingDraw = new Draw({
  maxPoints: shipMap.maxpoint,
  style: shipStyle.drawStyle,
  source: shipMap.drawRingSource,
  type: 'LineString'
})

//矩形画笔的添加
shipMap.drawRectangleSource = new SourceVector()
shipMap.drawRectangleLayer = new Vector({
  source: shipMap.drawRectangleSource,
  zIndex: 8
})
shipMap.drawRectangleDraw = new Draw({
  source: shipMap.drawRectangleSource,
  type: 'Circle',
  freehand: false,
  geometryFunction: createBox()
})
//圆型画笔的添加
shipMap.drawCircleSource = new SourceVector()
shipMap.drawCircleLayer = new Vector({
  source: shipMap.drawCircleSource,
  zIndex: 8
})
shipMap.drawCircleDraw = new Draw({
  source: shipMap.drawCircleSource,
  type: 'Circle'
})
//多边形的添加
//我的修改
shipMap.drawPolygonSource = new SourceVector()
shipMap.drawPolygonLayer = new Vector({
  source: shipMap.drawPolygonSource,
  zIndex: 8
})
shipMap.drawPolygonDraw = new Draw({
  source: shipMap.drawPolygonSource,
  type: 'Polygon'
})
//我的修改
//自定义线段的添加
shipMap.agtSource = new SourceVector()
shipMap.agtLayer = new Vector({
  source: shipMap.agtSource,
  zIndex: 16
})
//圆的半径
shipMap.sourceList.circlePath = new SourceVector()
shipMap.layerList.circlePathLayer = new Vector({
  source: shipMap.sourceList.circlePath,
  zIndex: 10
})
//我的修改
//eez线
shipMap.sourceList.eezSource = new XYZ({
  cacheSize: 256,
  tileUrlFunction: function (xyz, obj1, obj2) {
    if (!xyz) {
      return ''
    }
    let z = xyz[0]
    let x = Math.abs(xyz[1])
    let y = xyz[2]
    y += Math.pow(2, z)
    let tf = Math.pow(2, Math.ceil(z / 2) - 1)
    let tt = Math.pow(2, z)
    let t = tt / tf
    let f1 = parseInt(x / t + '')
    let f2 = parseInt(y / t + '')
    let lev = shipFun.padLeft(2, z)
    let folder = '0_0'
    if (z <= 5) {
      folder = f1 + '_' + f2
    } else if (z >= 6 && z <= 11) {
      folder = shipFun.padLeft(2, f1) + '_' + shipFun.padLeft(2, f2)
    } else if (z >= 12 && z <= 17) {
      folder = shipFun.padLeft(3, f1) + '_' + shipFun.padLeft(3, f2)
    } else {
      folder = shipFun.padLeft(4, f1) + '_' + shipFun.padLeft(4, f2)
    }

    let xx, yy
    if (z <= 5) {
      xx = shipFun.padLeft(2, x)
      yy = shipFun.padLeft(2, y)
    } else if (z >= 6 && z <= 11) {
      if (x === 100 || x === 1000) {
        xx = shipFun.padLeft(5, x)
      } else {
        xx = shipFun.padLeft(4, x)
      }

      if (y === 100 || y === 1000) {
        yy = shipFun.padLeft(5, y)
      } else {
        yy = shipFun.padLeft(4, y)
      }
    } else if (z >= 12 && z <= 17) {
      if (x === 100 || x === 1000 || x === 10000 || x === 100000) {
        xx = shipFun.padLeft(7, x)
      } else {
        xx = shipFun.padLeft(6, x)
      }

      if (y === 100 || y === 1000 || x === 10000 || x === 100000) {
        yy = shipFun.padLeft(7, y)
      } else {
        yy = shipFun.padLeft(6, y)
      }
    } else {
      if (
        x === 100 ||
        x === 1000 ||
        x === 10000 ||
        x === 100000 ||
        x === 1000000 ||
        x === 10000000
      ) {
        xx = shipFun.padLeft(9, x)
      } else {
        xx = shipFun.padLeft(8, x)
      }

      if (
        y === 100 ||
        y === 1000 ||
        x === 10000 ||
        x === 100000 ||
        x === 1000000 ||
        x === 10000000
      ) {
        yy = shipFun.padLeft(9, y)
      } else {
        yy = shipFun.padLeft(8, y)
      }
    }
    return (
      'http://47.93.90.52:9080' +
      '/EPSG_900913_' +
      lev +
      '/' +
      folder +
      '/' +
      xx +
      '_' +
      yy +
      '.png'
    )
  }
})
shipMap.layerList.eezLayer = new TileLayer({
  preload: Infinity,
  visible: true,
  source: shipMap.sourceList.eezSource,
  zIndex: 20
});
//eez线转换函数
(shipFun.padLeft = function (num, val) {
  return (new Array(num).join('0') + val).slice(-num)
})
//等值线
// shipMap.layerList.isobarLayer = new Vector({
//   zIndex: 5
// })

// 行政区划图层/api/jfcfdt
// var  darkMapPath = 'http://cfdt.ninecosmos.cn';
var darkMapPath = ''
if (process.env.NODE_ENV === 'production') {
  darkMapPath = '/myships/api/jfcfdt'
} else {
  darkMapPath = '/myships/jfcfdt'
}
shipMap.layerList.vtLayer = (() => {
  const style = new Style({
    stroke: new Stroke({
      color: 'black',
      width: 1,
    }),
    text: new Text({
      font: '12px Calibri,sans-serif',
      fill: new Fill({
        color: '#000',
      }),
      stroke: new Stroke({
        color: '#fff',
        width: 3,
      }),
    }),
  })
  return new TileLayer({
    declutter: true,
    source: new XYZSource({
      crossOrigin: 'anonymous',
      // url: darkMapPath + '/darkmap-retina/{z}/{x}/{y}.png',
      url: 'https://api3.myships.com/tiledmap/darkmap-retina/{z}/{x}/{y}.png',
    }),
    style: function (feature) {
      style.getText().setText(feature.get('name'))
      return style
    },
  })
})()
shipMap.layerList.vtLayer.setZIndex(4)

// 九方 初始化可视化sdk
const mapClient = new OlClient()

// 气象图层数据源
const sourceImageCanvas = new ImageCanvasSource({
  canvasFunction: (extent3857, resolution, pixelRatio, size) =>
    mapClient.renderColorMapTileFunction(
      extent3857,
      resolution,
      pixelRatio,
      size,
      () => sourceImageCanvas.refresh()
    ),
})
// 气象图层
const config = require('../../../public/config/sys-config.json')
shipMap.layerList.iLayer = new ImageLayer({source: sourceImageCanvas})
shipMap.layerList.iLayer.setZIndex(3)
if (config.map.weatherLayerOpacity) {
  shipMap.layerList.iLayer.setOpacity(config.map.weatherLayerOpacity)
}


// 粒子动画图层数据源
const pImageCanvas = new ImageCanvasSource({
  canvasFunction: (extent3857, resolution, pixelRatio, size) =>
    mapClient.renderParticleFunction(extent3857, resolution, pixelRatio, size, () => shipMap.map.render()),
})
// 粒子图层
shipMap.layerList.pLayer = new ImageLayer({source: pImageCanvas})
shipMap.layerList.pLayer.setZIndex(6);
//创建地图的函数
(shipFun.creatMap = () => {
  return new Map({
    target: 'map', //定义要显示的dom元素 使用id绑定
    layers: [
      shipMap.seaLayer,
      //shipMap.layer,
      shipMap.layerList.PointLayer,
      shipMap.layerList.shipLayer,
      shipMap.layerList.carLayer,
      shipMap.layerList.jjxLayer,
      shipMap.layerList.taifengLayer,
      shipMap.layerList.pathLineLayer,
      shipMap.layerList.berthLayer,
      shipMap.layerList.pathPointLayer,
      shipMap.layerList.selectLayer,
      shipMap.layerList.portLayer,
      //shipMap.layerList.iLayer,//九方气象图层
      shipMap.layerList.pLayer,// 九方粒子
      //shipMap.layerList.vtLayer,//九方行政区图层
      // shipMap.drawPointLayer,
      shipMap.agtLayer,
      shipMap.drawRingLayer,
      shipMap.drawCircleLayer,
      shipMap.drawRectangleLayer,
      // ---我的修改---
      shipMap.drawPolygonLayer,
      // ---我的修改---
      //我的修改
      shipMap.layerList.circlePathLayer
      //我的修改
    ],
    view: shipMap.view
  })
})

//监听返回zoom
shipFun.getSelectPortFun = function (selectPort) {
  shipMap.__selectPort = selectPort
}

//九方温度
shipFun.loadTemp = function (url) {
  if (!hasLayerInMap(shipMap.layerList.iLayer)) {
    shipMap.map.addLayer(shipMap.layerList.iLayer)
  }
  if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
    shipMap.map.addLayer(shipMap.layerList.vtLayer)
  }
  mapClient.colorMapTileLayer.setOption({
    url: url,
    factor: Factor.Temp,
  })
  sourceImageCanvas.refresh()

}
// 加载气压
shipFun.loadPressure = function (url) {
  if (!hasLayerInMap(shipMap.layerList.iLayer)) {
    shipMap.map.addLayer(shipMap.layerList.iLayer)
  }
  if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
    shipMap.map.addLayer(shipMap.layerList.vtLayer)
  }
  // 气压色斑图
  mapClient.colorMapTileLayer.setOption({
    url: url,
    factor: Factor.Pressure,
  })
  sourceImageCanvas.refresh()
}
// 加载风场
shipFun.loadWind = function (url) {
  if (!hasLayerInMap(shipMap.layerList.iLayer)) {
    shipMap.map.addLayer(shipMap.layerList.iLayer)
  }
  if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
    shipMap.map.addLayer(shipMap.layerList.vtLayer)
  }
  mapClient.colorMapTileLayer.setOption({
    url: url,
    factor: Factor.Wind,
  })
  sourceImageCanvas.refresh()
}
// 加载洋流
shipFun.loadSeacurrents = function (url) {
  if (!hasLayerInMap(shipMap.layerList.iLayer)) {
    shipMap.map.addLayer(shipMap.layerList.iLayer)
  }
  if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
    shipMap.map.addLayer(shipMap.layerList.vtLayer)
  }
  // 气压色斑图
  mapClient.colorMapTileLayer.setOption({
    url: url,
    factor: Factor.SeaCurrents,
  })
  sourceImageCanvas.refresh()
}
//加载洋流粒子
shipFun.loadNineParticleSeacurrents = function (url) {
  if (!hasLayerInMap(shipMap.layerList.pLayer)) {
    shipMap.map.addLayer(shipMap.layerList.pLayer)
  }
  // 粒子动画
  mapClient.particleAnimationLayer.setConfig({
    lineWidth: 0.95,
    speedFactor: 1.8,
    fadeOpacity: 0.85,
    particlesNumber: 15000,
    dropRate: 0.0005,
    dropRateBump: 0.001,
    colorRamp: {
      0.0: 'rgba(255,255,255,0.2)',
      1.0: 'rgba(255,255,255,0.5)',
    }
  })
  mapClient.particleAnimationLayer.setOption({
    url: url,
    type: 'image',
    factor: Factor.SeaCurrents,
  })
}
//加载风粒子
shipFun.loadNineParticleWind = function (url) {
  if (!hasLayerInMap(shipMap.layerList.pLayer)) {
    shipMap.map.addLayer(shipMap.layerList.pLayer)
  }
  // 粒子动画
  mapClient.particleAnimationLayer.setConfig({
    lineWidth: 0.95,
    speedFactor: 0.2,
    fadeOpacity: 0.85,
    particlesNumber: 15000
  })
  mapClient.particleAnimationLayer.setOption({
    url: url,
    type: 'image',
    factor: Factor.Wind,
  })
}
// 加载等值线
shipFun.loadIsobar = function (url) {
  if (!hasLayerInMap(shipMap.layerList.isobarLayer)) {
    shipMap.layerList.isobarLayer = new Vector({
      source: new SourceVector({
        //'http://cfdt.ninecosmos.cn/meteo-open/s01/2021/09/06/006/pressure-surface-4326-isoline.json',
        url: url,
        format: new GeoJSON(),
      }),
      style: function (feature) {
        if (shipStyle.isobarStyle && shipStyle.isobarStyle.getText()) {
          shipStyle.isobarStyle.getText().setText(feature.get('values_'))
        }
        return shipStyle.isobarStyle
      },
    })
    shipMap.layerList.isobarLayer.setZIndex(5)
    shipMap.map.addLayer(shipMap.layerList.isobarLayer)
  }
}

//隐藏台风警戒线
shipFun.hidejjx = function () {
  shipMap.layerList.jjxLayer.setVisible(false)
}

//显示台风警戒线
shipFun.showjjx = function () {
  shipMap.layerList.jjxLayer.setVisible(true)
}

//清除九方气象
shipFun.clearJfWeather = function () {
  shipMap.map.removeLayer(shipMap.layerList.iLayer)
  shipMap.map.removeLayer(shipMap.layerList.vtLayer)
}
shipFun.clearJfWeatherIsobar = function () {
  if (hasLayerInMap(shipMap.layerList.isobarLayer)) {
    shipMap.map.removeLayer(shipMap.layerList.isobarLayer)
  }
}
shipFun.clearJfParticle = function () {
  if (hasLayerInMap(shipMap.layerList.pLayer)) {
    shipMap.map.removeLayer(shipMap.layerList.pLayer)
  }
}
shipFun.showPort = function (portInfo) {
  let coor = transform(
    [portInfo.lon, portInfo.lat],
    'EPSG:4326',
    'EPSG:3857'
  ) //先定义一个坐标  //速度   航向 经纬度  船舶名 类型
  let geom = new Point(coor) //根据坐标画点
  let f = new Feature({
    geometry: geom,
    portId: portInfo.id,
    type: 'port',
    portNmaeCn: portInfo.nameCn,
    portNmaeEn: portInfo.nameEn,
    portCode: portInfo.code,
    portLatLon: portInfo.latLonStr,
    portLon: portInfo.lon,
    portLat: portInfo.lat,
    name: portInfo.nameEn
  })
  f.setStyle(shipStyle.portStyle(f))
  f.set('geom', geom)
  shipMap.sourceList.portSource.addFeature(f)
}

shipFun.showBerth = function (berthInfo) {
  let coor = transform(
    [berthInfo.decLongitude, berthInfo.decLatitude],
    'EPSG:4326',
    'EPSG:3857'
  ) //先定义一个坐标  //速度   航向 经纬度  船舶名 类型
  let geom = new Point(coor) //根据坐标画点
  let f = new Feature({
    geometry: geom,
    berthId: berthInfo.berthId,
    type: 'berth',
    name: berthInfo.berthName,
    berthLon: berthInfo.decLongitude,
    berthLat: berthInfo.decLatitude,
  })
  f.setStyle(shipStyle.berthStyle(f))
  f.set('geom', geom)
  f.setId('berth-' + berthInfo.berthId)
  shipMap.sourceList.berthSource.addFeature(f)
}
// 清除所有泊位
shipFun.clearallBerth = (map) => {
  shipMap.sourceList.berthSource.clear()
  return true
}
//清除所有港口
shipFun.clearallPort = (map) => {
  shipMap.sourceList.portSource.clear()
  return true
}
//判定图层是否存在map
//判断当前图层是否存在地图中
function hasLayerInMap(layer) {
  var layers = shipMap.map.getLayers()
  for (var i = 0; i < layers.getLength(); i++) {
    var item = layers.item(i)
    if (item === layer) {
      return true
    }
  }
  return false
}

//清除所有船舶
shipFun.clearallship = (map) => {
  shipMap.sourceList.shipSource.clear()
  return true
}
shipFun.clearAllCar = (map) => {
  shipMap.sourceList.carSource.clear()
  return true
}
shipFun.addCar = (data, map) => {
  const source = shipMap.sourceList.carSource
  const features = source.getFeatures()
  if (features) {
    for (let i = 0; i < data.length; i++) {
      const item = data[i]
      features.forEach((f) => {
        if (f.getId() === item.carNum) {
          source.removeFeature(f)
        }
      })
    }
  }
  const newFeatures = []
  for (let i = 0; i < data.length; i++) {
    const item = data[i]
    if(item.carNum){
      const f = new Feature({
        geometry: new Point(transform([Number(item.longitude), Number(item.latitude)], 'EPSG:4326', 'EPSG:3857'))
      })
      f.setId(item.carNum);
      Object.keys(item).forEach((key) => {
        f.set(key, item[key])
      })
      f.set('type','car')
      newFeatures.push(f)
    }
  }
  source.addFeatures(newFeatures)
}
function identifySouOrNor(lines, point) {
  //将线段的点切割为数组，数组的每个元素为一条线段
  const lineData = []
  for(let i = 0; i<lines.length-1; i++){
    lineData.push([lines[i], lines[i+1]])
  }
  //先根据经度判断。这个点垂直投影在哪一条线段上
  let projectionLine = []
  lineData.forEach(line => {
    if(point[0]>line[0][0] && point[0]<line[1][0]){
      projectionLine = line
    }
  })
  //判断这个点是在线段的上（北）还是下（南）
  if(projectionLine.length == 0){
    const latitudeArr = []
    lines.map(item => {
      latitudeArr.push(item[1])
    })
    const maxLatitude = Math.max(...latitudeArr)
    if(point[1]>maxLatitude){
      return false
    } else {
      return true
    }
  }
  if (projectionLine[0][1] == projectionLine[1][1]) {
    if (point[1]<projectionLine[0][1]) {
      return true
    } else {
      return false
    }
  }
  const A = projectionLine[1][1] - projectionLine[0][1]
  const B = projectionLine[0][0] - projectionLine[1][0]
  const C = projectionLine[1][0]*projectionLine[1][1] - projectionLine[0][0]*projectionLine[1][1]
  let D = A*point[0] + B*point[1] + C
  if (D>0) {
    return true
  } else {
    return false
  }
}
//添加 船舶
shipFun.addShip = (dataList, zoom, map, selectlist) => {
  // shipMap.sourceList.shipSource.clear()
  for (let i = 0; i < dataList.length; i++) {
    const element = dataList[i]
    let coor = transform(
      [dataList[i].n / 600000, dataList[i].a / 600000],
      'EPSG:4326',
      'EPSG:3857'
    ) //先定义一个坐标  //速度   航向 经纬度  船舶名 类型
    // 判断船舶坐标在abc线的南北
    // if(identifySouOrNor(abcLineData, coor)==false){
    //   element.color = '#FF0000'
    // }
    let geom = new Point(coor) //根据坐标画点
    let f = new Feature({
      geometry: geom, //添加点图形
      type: 'ship',
      shiptype: element.y,
      mmsi: element.m,
      heading: element.h,
      callsign: element.g,
      cog: element.c,
      imo: element.o,
      sog: element.s,
      aisNavStatus: element.v,
      length: element.l,
      destPort: element.p,
      breadth: element.b,
      eta: element.r,
      draught: element.d,
      posTime: element.t,
      shipId: element.i,
      lon: dataList[i].n,
      lat: dataList[i].a,
      shipnameEn: dataList[i].e,
      color: element.color
    })
    f.setId(dataList[i].i)
    f.set('geom', geom)
    shipMap.sourceList.shipSource.addFeature(f, zoom)
  }
}

shipFun.getShipFeaturesByIds = (shipIds) => {  //根据shipId找到对应的feature
  const features = []
  shipIds.forEach(id => {
    let f = shipMap.sourceList.shipSource.getFeatureById(id)
    features.push(f)
  })
  return features
}
shipFun.getCarFeaturesByIds = (carIds) => {  //根据shipId找到对应的feature
  const features = []
  carIds.forEach(id => {
    let f = shipMap.sourceList.carSource.getFeatureById(id)
    features.push(f)
  })
  return features
}

shipFun.plotting = function (number) {
  shipStyle.plotting(number)
}
//添加全屏控件
shipFun.addFullScreen = (map) => {
  let FullScreenControl = new FullScreen({
    // units: 'metric',
    // target: 'scalebar',
    className: 'ol-full-screen'
  })
  map.addControl(FullScreenControl)
}

//添加比例尺控件
shipFun.addScaleLine = (map) => {
  let scaleLineControl = new ScaleLine({
    units: 'nautical',
    target: 'scalebar',
    className: 'ol-scale-line'
  })
  map.addControl(scaleLineControl)
}
window.wulaFeature = [];//台风显示需要的这个是风圈
window.wulaTime = [];//台风风圈运动的定时器
var wulaFeature1 = [];//台风显示需要的 这个是风圈中心点
var wktformat = new WKT()


// 显示台风
shipFun.showTyphoon = function (data, level, time, name) {
  __showTaiFengNew2(data, level, time, name);
}

//绘制台风图层new
function __showTaiFengNew2(tdata, level, time, name) {
  var data = tdata.data;

  var arr = data.filter(function (item, index) {
    item.longitude = item.lon;
    if (index > 0) {
      if ((item.lon - data[index - 1].lon) < -180)
        item.lon += 360;
      else if ((item.lon - data[index - 1].lon) > 180)
        item.lon -= 360;

    }
    item.f = item.forcast.filter(function (it, idx) {
      if (idx == 0) {
        if ((it.lon - item.lon) < -180)
          it.lon += 360;
        else if ((it.lon - item.lon) > 180)
          it.lon -= 360;
      }
      if (idx > 0) {
        if ((it.lon - item.forcast[idx - 1].lon) < -180)
          it.lon += 360;
        else if ((it.lon - item.forcast[idx - 1].lon) > 180)
          it.lon -= 360;
      }
      return it;
    });
    return item;
  });
  var his = [], current, fut = [], arrLength;
  arrLength = arr.length;
  for (var i = 0; i < arrLength - 1; i++) {
    arr[i].t = 0;
    his.push(arr[i]);
    if (arr[i].f.length > 0) {
      arr[i].f.unshift(arr[i]);
    }
  }
  current = arr[arrLength - 1];
  current.t = 1;
  for (var i = 0; i < current.f.length; i++) {
    current.f[i].t = 2;
    current.f[i].longitude = current.f[i].lon;
    fut.push(current.f[i]);
  }
  var all = his.concat(current);
  all = all.concat(fut);

  /*var startll = ol.proj.fromLonLat([arr[0].lon, arr[0].lat]);
  var startf = new ol.Feature({
      geometry: new Point(startll)
  });
  startf.set("name",tdata.seq);
  startf.setStyle(typhoonStart);
  Source.taifeng.addFeature(startf);*/

  var center = fromLonLat([current.lon, current.lat]);
  var ct = new Feature({
    geometry: new Point(center)
  });
  ct.set("name", tdata.seq);
  ct.setStyle(typhoonCenter2);
  ct.set("code", tdata.code);
  shipMap.sourceList.taifeng.addFeature(ct);
  drawTyphoonNew(all, tdata.seq, tdata.code, name);
  var rad_neq34kt = parseInt(current.radius7);
  var rad_neq50kt = parseInt(current.radius10);//暴风圈
  var liefeng = new Feature({
    geometry: new CircleGeom(center, rad_neq34kt * 1000)
  });
  var baofeng = new Feature({
    geometry: new CircleGeom(center, rad_neq50kt * 1000)
  });

  liefeng.setStyle(liefengStyle);
  baofeng.setStyle(baofengStyle);
  liefeng.set("code", tdata.code);
  baofeng.set("code", tdata.code);

  //绑定定时器的数组
  if (window.wulaTime[name] == undefined) {
    window.wulaTime[name] = [];
  }
  if (window.wulaTime[name].length == 0) {
    //尝试改变台风的显示样式开始
    for (var i = 0; i < all.length; i++) {
      (function (a) {
        var k = setTimeout(function () {
          typhoonMove(all[a], level, name);
        }, a * time * 1000); //.....
        window.wulaTime[name][a] = k;
      })(i)
    }
    //最后一个定时器 显示台风当前的点的位置
    all.filter(function (item, index, arr) {
      if (item.t == 1) {
        var k = setTimeout(function () {
          typhoonMove(all[index], level, name)
        }, all.length * time * 1000)
        window.wulaTime[name][all.length] = k;
      }
    })
  }
  //尝试改变台风的显示样式结束
}

//显示台风运动
function typhoonMove(data, level, name) {
  if (window.wulaFeature[name] != null) {
    shipMap.sourceList.taifeng.removeFeature(wulaFeature[name]);
  }
  // if(wulaFeature1[name] != null){
  // 	Source.taifeng.removeFeature(wulaFeature1[name]);
  // }

  var Configs = {
    CIRCLE_CENTER_X: data.lon,
    CIRCLE_CENTER_Y: data.lat,
    CIRCLE_R: {
      "SE": parseFloat(data.radius10.se),
      "NE": parseFloat(data.radius10.ne),
      "NW": parseFloat(data.radius10.nw),
      "SW": parseFloat(data.radius10.sw)
    }
  };
  var obj = makeTyphoonData(Configs, level);
  window.wulaFeature[name] = wktformat.readFeature(obj.wkt);
  window.wulaFeature[name].set('lineName', name);
  // wulaFeature1[name] = wktformat.readFeature("POINT("+obj.xy[0]+" "+obj.xy[1]+")");
  // wulaFeature1[name].set('lineName',name);
  window.wulaFeature[name].setStyle(styleFunc());
  shipMap.sourceList.taifeng.addFeatures([window.wulaFeature[name]]);
}

//台风圈数据处理函数
function makeTyphoonData(Configs, level) {
  var wkt = "POLYGON((";
  var wkt0 = "", _interval = 6;
  for (var i = 0; i < 360 / _interval; i++) {
    var _r = 0;
    var _ang = i * _interval;
    if (_ang > 0 && _ang <= 90) {
      _r = Configs.CIRCLE_R.NE * level;
    } else if (_ang > 90 && _ang <= 180) {
      _r = Configs.CIRCLE_R.NW * level;
    } else if (_ang > 180 && _ang <= 270) {
      _r = Configs.CIRCLE_R.SW * level;
    } else {
      _r = Configs.CIRCLE_R.SE * level;
    }

    var xy = transform([Configs.CIRCLE_CENTER_X, Configs.CIRCLE_CENTER_Y], 'EPSG:4326', 'EPSG:3857');
    var x = xy[0] + _r * Math.cos(_ang * 3.14 / 180);
    var y = xy[1] + _r * Math.sin(_ang * 3.14 / 180);
    wkt = wkt + "" + x + " " + y + ", ";
    if (i === 0) {
      wkt0 = "" + x + " " + y + "";
    }
  }
  wkt = wkt + wkt0 + "))";
  return {
    wkt: wkt,
    xy: xy
  }
}

//台风圈样式
function styleFunc() {
  return new Style({
    fill: new Fill({
      color: 'rgba(255, 0, 0, 0.2)'
    }),
    stroke: new Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new Circle({
      radius: 4,
      fill: new Fill({
        color: '#ff0000'
      })
    })
  });
};


//根据台风点绘制 线点
//isFuture true是预报点，false是当前点
//istemp是临时要素
function drawTyphoonNew(typhoonpts, name, code, lineName) {
  var typhoonLineFeatures = [];
  var count = typhoonpts.length;
  var _line1 = [];
  var _line2 = [];
  var cline = _line1;
  for (var i = 0; i < count; i++) {
    var _coor = fromLonLat([typhoonpts[i].lon, typhoonpts[i].lat]);
    var _geom = new Point(_coor);
    var _feature = new Feature();
    //var date = getDate(typhoonpts[i].typhoonTime);
    //var secondDate = new Date(date.valueOf() + 8*60*60*1000);
    //_feature.set("showTime",secondDate.format("yyyy-MM-dd hh"));
    _feature.setProperties(typhoonpts[i]);
    _feature.set("type", "typhoon");
    _feature.set("t", typhoonpts[i].t);
    _feature.set("time", typhoonpts[i].time);
    _feature.set("maxWindSpeed", typhoonpts[i].windSpeed);
    _feature.set("airPressure", typhoonpts[i].airPressure);
    _feature.set("maxRadius7", typhoonpts[i].maxRadius7);
    _feature.set("maxRadius10", typhoonpts[i].maxRadius10);
    _feature.set("radius7", typhoonpts[i].radius7);
    _feature.set("radius10", typhoonpts[i].radius10);
    _feature.set("moveDirection", typhoonpts[i].direction);
    _feature.set("moveSpeed", typhoonpts[i].speed);
    _feature.set("code", code);
    _feature.set("name", name);
    _feature.set("lineName", lineName);//这个用于删除时找到属于该台风的点
    _feature.setGeometry(_geom);
    if (i == 0) {
      _feature.setStyle(typhoonStartPoint);
    }
    // else {
    //   _feature.setStyle(typhoonStartPointTime);
    // }
    typhoonLineFeatures.push(_feature);
    cline.push(_coor);
    if (typhoonpts[i].t == 1) {
      cline = _line2;
      cline.push(_coor);
    }
    if (typhoonpts[i].lon >= 180) {
      var l = typhoonpts[i].lon - 360;
      var cd = fromLonLat([l, typhoonpts[i].lat]);
      var _g = new Point(cd);
      var _f = new Feature();
      _f.setProperties(typhoonpts[i]);
      _f.set("type", "typhoon");
      _f.set("longitude", l);
      _f.set("t", typhoonpts[i].t);
      _f.set("time", typhoonpts[i].time);
      _f.set("maxWindSpeed", typhoonpts[i].windSpeed);
      _f.set("airPressure", typhoonpts[i].airPressure);
      _f.set("maxRadius7", typhoonpts[i].maxRadius7);
      _f.set("maxRadius10", typhoonpts[i].maxRadius10);
      _f.set("radius7", typhoonpts[i].radius7);
      _f.set("radius10", typhoonpts[i].radius10);
      _f.set("moveDirection", typhoonpts[i].direction);
      _f.set("moveSpeed", typhoonpts[i].speed);
      _f.set("code", code);
      _f.set("name", name);
      _f.set("lineName", lineName);
      _f.setGeometry(_g);
      typhoonLineFeatures.push(_f);
    }
    if (typhoonpts[i].lon <= -180) {
      var l = typhoonpts[i].lon + 360;
      var cd = fromLonLat([l, typhoonpts[i].lat]);
      var _g = new Point(cd);
      var _f = new Feature();
      _f.setProperties(typhoonpts[i]);
      _f.set("type", "typhoon");
      _f.set("longitude", l);
      _f.set("t", typhoonpts[i].t);
      _f.set("time", typhoonpts[i].time);
      _f.set("maxWindSpeed", typhoonpts[i].windSpeed);
      _f.set("airPressure", typhoonpts[i].airPressure);
      _f.set("maxRadius7", typhoonpts[i].maxRadius7);
      _f.set("maxRadius10", typhoonpts[i].maxRadius10);
      _f.set("radius7", typhoonpts[i].radius7);
      _f.set("radius10", typhoonpts[i].radius10);
      _f.set("moveDirection", typhoonpts[i].direction);
      _f.set("moveSpeed", typhoonpts[i].speed);
      _f.set("code", code);
      _f.set("name", name);
      _f.set("lineName", lineName);
      _f.setGeometry(_g);
      typhoonLineFeatures.push(_f);
    }
  }
  //台风已经经过的线路
  var taifengLine1 = new Feature({
    geometry: new LineString(_line1)
  });
  taifengLine1.set("t", 3);
  taifengLine1.set("type", "typhoonLine");
  taifengLine1.set("code", code);
  taifengLine1.setId(lineName + '1');
  //台风未来经过的线路
  var taifengLine2 = new Feature({
    geometry: new LineString(_line2)
  });
  taifengLine2.set("t", 4);
  taifengLine2.set("type", "typhoonLine");
  taifengLine2.set("code", code);
  taifengLine2.setId(lineName + '2');
  shipMap.sourceList.taifeng.addFeature(taifengLine1);//台风线
  shipMap.sourceList.taifeng.addFeature(taifengLine2);//台风线
  shipMap.sourceList.taifeng.addFeatures(typhoonLineFeatures);//台风点
}

function typhoonStartPoint(f, r) {
  var s = new Style({
    fill: new Fill({
      color: 'rgba(255, 0, 0, 0.8)'
    }),
    stroke: new Stroke({
      color: 'rgba(255, 0, 0, 0.8)',
      width: 2
    }),
    image: new Circle({
      radius: 4,
      fill: new Fill({
        color: 'rgba(255, 0, 0, 0.8)'
      })
    })
  });
  var ntext = new Text({
    textAlign: "left",
    font: '12px Microsoft YaHei',
    fill: new Fill({
      color: "#5F88AA"
    }),
    stroke: new Stroke({
      color: "#FFF",
      width: 3
    }),
    textBaseline: "bottom",
    offsetX: 8,
    offsetY: -8,
    text: f.get('name')
  })
  s.setText(ntext);
  return [s];
}

function typhoonStartPointTime(f, r) {
  // var s = new Style({
  //   fill: new Fill({
  //     color: 'rgba(255, 0, 0, 0.8)'
  //   }),
  //   stroke: new Stroke({
  //     color: 'rgba(255, 0, 0, 0.8)',
  //     width: 2
  //   }),
  //   image: new Circle({
  //     radius: 4,
  //     fill: new Fill({
  //       color: 'rgba(255, 0, 0, 0.8)'
  //     })
  //   })
  // });
  var ntext = new Style({
    text: new Text({
      textAlign: "left",
      font: '12px Microsoft YaHei',
      fill: new Fill({
        color: "#5F88AA"
      }),
      stroke: new Stroke({
        color: "#FFF",
        width: 3
      }),
      textBaseline: "bottom",
      offsetX: 8,
      offsetY: -8,
      text: f.get('name')
    })
  })
  // s.setText(ntext);
  return [ntext];
}

//烈风圈
var liefengStyle = new Style({
  fill: new Fill({
    color: 'rgba(0,0,255,0.1)'
  }),
  stroke: new Stroke({
    color: 'rgb(0,0,255)',
    width: 2
  })
});

//暴风圈
var baofengStyle = new Style({
  fill: new Fill({
    color: 'rgba(255,0,0,0.2)'
  }),
  stroke: new Stroke({
    color: 'rgb(255,0,0)',
    width: 2
  })
});


//添加分布图
shipFun.addScattergram = (map) => {
  map.addLayer(shipMap.distributeLayer)
}
//取消分布图
shipFun.removeaScattergram = (map) => {
  map.removeLayer(shipMap.distributeLayer)
}

shipMap.languageType = 2
//语言设置
shipFun.setLanguage = (languageType) => {
  shipMap.languageType = languageType
}
shipFun.getZoom = function () {
  return shipMap.map.getView().getZoom()
}
//添加地图层级变化监听函数
shipFun.addZoomListener = (map, callback) => {
  map.on('moveend', function (e) {
    var zoom = map.getView().getZoom() //获取当前地图的缩放级别
    callback(zoom)
  })

  // 监听气象点击  ， 单击地图显示气象要素值
  shipMap.popupOverlay = new Overlay({
    element: document.getElementById('popup'),             //绑定dom对象，纯js必须使用document绑定，不能像Map的dom对象，只写‘popup’
    autoPan: true,                  //点击地图边缘时，地图自动调节
    autoPanMargin: 20,
    positioning: 'center-center'
  })
  shipMap.map.addOverlay(shipMap.popupOverlay)
  var container = document.getElementById('popup')
  var content = document.getElementById('popup-content')
  map.on('singleclick', function (evt) {
    //包含气象图层
    if (hasLayerInMap(shipMap.layerList.iLayer)) {
      let weatherType = mapClient.colorMapTileLayer.source.factor
      let weatherTypeStr = ''
      const language = window.localStorage.getItem('language')
      if (shipMap.languageType == 2) {
        switch (weatherType) {
          case 'temp':
            weatherTypeStr = language === 'zh' ? '温度' : 'temperature'
            break
          case 'pressure':
            weatherTypeStr = language === 'zh' ? '气压' : 'pressure'
            break
          case 'wind':
            weatherTypeStr = language === 'zh' ? '风' : 'wind'
            break
          case 'seaCurrents':
            weatherTypeStr = language === 'zh' ? '洋流' : 'ocean current'
            break
        }
      } else {
        weatherTypeStr = weatherType
      }
      var weatherStr = mapClient.decodeColorMapTileValue(evt.pixel, mapClient.getExtent(map), map.getView().getZoom())
      var coordinate = evt.coordinate // 获取坐标
      shipMap.popupOverlay.setPosition(coordinate)
      content.innerHTML = '<p>' + weatherTypeStr + ':' + weatherStr + '</p>'			//弹窗展示内容为经纬度信息
      container.style.display = 'block'
      container.style.color = '#ffffff'
    }

    let pixel = map.getEventPixel(evt.originalEvent)
    let feature = map.forEachFeatureAtPixel(pixel, function (feature) {
      return feature
    })
    // 查询方式有很多
    if (feature) {
      let type = feature.getProperties()['type']
    } else {
      shipFun.delSelect()
    }
  })
}
//移除地图层级变化监听函数
shipFun.removePopupOverlay = function () {
  // 把弹窗位置设置为undefined，并清空坐标数据
  shipMap.popupOverlay.setPosition(undefined)
  return false
}
//移除地图层级变化监听函数
shipFun.removeZoomListener = () => {
  unByKey(shipMap.Listen)
}

//添加实时显示鼠标位置的函数
shipFun.addMousePos = function (map) {
  let mapMousePosition = new MousePosition({
    coordinateFormat: function (coor) {
      while (coor[0] < -180) coor[0] = coor[0] + 360
      while (coor[0] > 180) coor[0] = coor[0] - 360
      //log(coor);
      let lon = shipFun.cacuLonLat(coor[0], 'lon')
      let lat = shipFun.cacuLonLat(coor[1], 'lat')
      document.getElementById('positionLng').innerText = lon
      document.getElementById('positionLat').innerText = lat
      return ''
    },
    projection: 'EPSG:4326'
  })
  map.addControl(mapMousePosition)
}
//隐藏船舶
shipFun.hideShips = (idList) => {
  let type = typeof idList
  if (type == 'string') {
    let f = shipMap.sourceList.shipSource.getFeatureById(idList)
    shipMap.sourceList.shipSource.removeFeature(f)
  } else if (type == 'object') {
    idList.forEach((x, i) => {
      let f = shipMap.sourceList.shipSource.getFeatureById(x)
      shipMap.sourceList.shipSource.removeFeature(f)
    })
  } else {
  }
  return ''
}
//显示船舶
shipFun.showShips = (idList) => {
  let type = typeof idList
  if (type == 'string') {
    shipMap.sourceList.shipSource.addFeature(f)
  } else if (type == 'object') {
    idList.forEach((x, i) => {
      shipMap.sourceList.shipSource.addFeature(f)
    })
  } else {
  }
  return ''
}

//船舶点击函数
shipFun.addClick = (callback) => {
  shipMap.shipClick = new intSelect({
    style: null,
    layers: [shipMap.layerList.berthLayer, shipMap.layerList.shipLayer, shipMap.layerList.portLayer,shipMap.layerList.carLayer]
  })
  let shipmes = ''
  shipMap.shipClick.on('select', function (evt) {
    let f = evt.selected[0]
    shipFun.delSelect()
    shipmes = f.values_
    if (f.values_.type === 'berth') {
      shipFun.addSelectByCoor([f.values_.berthLon, f.values_.berthLat])
      shipmes.isType = 'berth'
    } else if (f.values_.type === 'port') {
      shipFun.addSelectByCoor([shipmes.portLon, shipmes.portLat])
      shipmes.isType = 'port'
    } else if (f.values_.type === 'ship') {
      shipFun.addSelectByCoor([shipmes.lon / 600000, shipmes.lat / 600000])
      shipmes.isType = 'ship'
    } else if(f.values_.type === 'car') {
      shipFun.addSelectByCoor([shipmes.longitude, shipmes.latitude])
      shipmes.isType = 'car'
    }
    callback(shipmes)
  })
  shipMap.map.addInteraction(shipMap.shipClick)
}
//添加港口范围
shipFun.addarea = (dataList) => {
  let Coor = []
  for (let i = 0; i < dataList.length; i++) {
    let coor = transform(
      [dataList[i].lon, dataList[i].lat],
      'EPSG:4326',
      'EPSG:3857'
    )
    Coor.push(coor)
  }
  let line = new LineString(Coor) //这是已知点画线
  //多边形要素类
  let newFeature = new Feature({
    geometry: line
  })
  newFeature.setStyle(shipStyle.areastyle)
  shipMap.sourceList.pathLineSource.addFeature(newFeature)
}
// 清除电子围栏
shipFun.clearArea = () => {
  shipMap.sourceList.pathLineSource.clear()
}

function __makePathData(data, __map, pathId) {
  var re = [];
  var start = data[0];
  re.push(start);
  var it0 = transform([Number(start.lon), Number(start.lat)], 'EPSG:4326', 'EPSG:3857');
  for (var i = 1; i <= data.length - 2; i++) {
    var item = data[i];
    var it = transform([Number(item.lon), Number(item.lat)], 'EPSG:4326', 'EPSG:3857');
    var pix = __map.getPixelFromCoordinate(it);
    var pix0 = __map.getPixelFromCoordinate(it0);
    if (Math.abs(pix[0] - pix0[0]) > 50 || Math.abs(pix[1] - pix0[1]) > 50) {
      re.push(item);
      it0 = it;
    } else {
      var s = it0;
      var c = it;
      var e = transform([Number(data[i + 1].lon), Number(data[i + 1].lat)], 'EPSG:4326', 'EPSG:3857');
      var dx1 = c[0] - s[0];
      var dy1 = c[1] - s[1];
      var r1 = Math.atan2(dy1, dx1);
      var dx2 = e[0] - c[0];
      var dy2 = e[1] - c[1];
      var r2 = Math.atan2(dy2, dx2);
      var angle = Math.abs(r2 - r1);
      var jd = 180 / Math.PI * angle;
      if (jd > 30) {
        re.push(item);
        it0 = it;
      }
    }
  }
  re.push(data[data.length - 1]);
  return re;
}

function guid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8)
    return v.toString(16)
  })
}

function fitPath(data, map) {
  if (data) {
    var minx, miny, maxx, maxy
    data.forEach(function (item, index) {
      var it = transform([Number(item.lon), Number(item.lat)], 'EPSG:4326', 'EPSG:3857')
      if (!minx) minx = it[0]
      if (!miny) miny = it[1]
      if (!maxx) maxx = it[0]
      if (!maxy) maxy = it[1]
      if (minx > it[0]) minx = it[0]
      if (miny > it[1]) miny = it[1]
      if (maxx < it[0]) maxx = it[0]
      if (maxy < it[1]) maxy = it[1]

    })
    var view = map.getView()
    view.fit([minx, miny, maxx, maxy], {padding: [50, 50, 50, 50]})
  }
}

//添加轨迹
shipFun.addPath = (dataList, __map) => {
  dataList.map(function (item, index, arr) {
    if (index > 0) {
      if ((item.lon - arr[index - 1].lon) < -180) {
        item.lon += 360
      } else if ((item.lon - arr[index - 1].lon) > 180) {
        var i = index - 1
        while (i >= 0) {
          arr[i--].lon += 360
        }
      }
    }
  })

  let pathId = guid()
  let re = __makePathData(dataList, __map, pathId)
  __pathDrawData[pathId] = re;
  __pathData[pathId] = dataList;
  __drawPathData(re, pathId)
  fitPath(dataList, __map);
  return pathId
}
var __tsize = [];

function __drawPathData(dataList, pathId) {
  let Coor = []
  let ids = []
  for (let i = 0; i < dataList.length; i++) {
    let coor = transform(
      [dataList[i].lon, dataList[i].lat],
      'EPSG:4326',
      'EPSG:3857'
    )
    Coor.push(coor)
  }
  let line = new LineString(Coor) //这是已知点画线
  //多边形要素类
  let newFeature = new Feature({
    geometry: line
  })
  newFeature.setStyle(shipStyle.pathColor)
  newFeature.setId(pathId)
  ids.push(pathId)
  shipMap.sourceList.pathLineSource.addFeature(newFeature)

  for (let i = 0; i < Coor.length; i++) {
    let point = new Point(Coor[i]) //这是已知点画线
    let newFeature = new Feature({
      geometry: point,
      heading: dataList[i].direction,
      sog: dataList[i].sog,
      lon: dataList[i].lon,
      lat: dataList[i].lat,
      time: dataList[i].time,
      type: 'pathPoint'
    })
    newFeature.set('geom', point)
    newFeature.setId(pathId + '-' + (i + 1))
    ids.push(pathId + '-' + (i + 1))
    newFeature.setStyle(
      // shipStyle.pathStyle(formatDate(dataList[i].posTime, 'hh:mm:ss'))
      shipStyle.pathStyle(dayjs(dataList[i].posTime * 1000).format('YYYY-MM-DD hh:mm:ss'))
    )
    shipMap.sourceList.pathPointSource.addFeature(newFeature)
    if (i == 0) {
      let pointStart = new Point(Coor[i])
      let startF = new Feature({
        geometry: pointStart
      })
      startF.setId(pathId + '-start')
      ids.push(pathId + '-start')
      startF.setStyle(shipStyle.pathSEStyle('start'))
      shipMap.sourceList.pathPointSource.addFeature(startF)
    }
    if (i == dataList.length - 1) {
      let pointEnd = new Point(Coor[i])
      let endF = new Feature({
        geometry: pointEnd
      })
      endF.setId(pathId + '-end')
      ids.push(pathId + '-end')
      endF.setStyle(shipStyle.pathSEStyle('end'))
      shipMap.sourceList.pathPointSource.addFeature(endF)
    }
  }

  // fitPath(dataList, shipMap.map)
  __pathArray[pathId] = ids;
  return pathId
}

function _$(d) {
  return document.getElementById(d);
}

function textSize(text) {
  if (__tsize[text]) {
    return __tsize[text];
  }
  var result = {};
  var span = _$("__testStringWide");
  if (!span) {
    span = document.createElement("span");
    span.id = "__testStringWide";
    span.style.font = "16px Microsoft YaHei 100";
    span.style.whiteSpace = "nowrap";
    span.style.visibility = "hidden";
    document.body.appendChild(span);
  }
  if (typeof span.textContent != "undefined")
    span.textContent = "";
  else span.innerText = "";
  result.width = span.offsetWidth;
  result.height = span.offsetWidth;
  if (typeof span.textContent != "undefined")
    span.textContent = text;
  else span.innerText = text;
  result.width = span.offsetWidth - result.width + 3;
  //result.height = span.offsetHeight - result.height;
  result.height = 22;
  __tsize[text] = result;
  return result;
}

var screenText = {};
var heigthKey = 14;

function calcLablePos3(center, size, id) {
  var result = {};
  var pos = {};
  pos.l = Math.round((center.left + 10) / 30);
  pos.length = Math.round(size.width / 30) + 1;
  //右上
  pos.t = Math.round(center.top / 30) - 1;
  let hasLable = false;
  for (var i = pos.l; i < pos.l + pos.length; i++) {
    var o = screenText[i + "-" + pos.t];
    if (o) {
      if (o != id) {
        hasLable = true;
        break;
      }
    }
  }
  if (!hasLable) {
    result.canDraw = true;
    result.offsetX = 10;
    result.offsetY = -heigthKey - (center.top - (pos.t + 1) * 30);
    for (var i = pos.l; i < pos.l + pos.length; i++) {
      screenText[i + "-" + pos.t] = id;
    }
    return result;
  }

  //右下
  pos.t = Math.round(center.top / 30) + 1;
  hasLable = false;
  for (var i = pos.l; i < pos.l + pos.length; i++) {
    var o = screenText[i + "-" + pos.t];
    if (o) {
      if (o != id) {
        hasLable = true;
        break;
      }
    }
  }
  if (!hasLable) {
    result.canDraw = true;
    result.offsetX = 10;
    result.offsetY = heigthKey - (center.top - (pos.t - 1) * 30);
    for (var i = pos.l; i < pos.l + pos.length; i++) {
      screenText[i + "-" + pos.t] = id;
    }
    return result;
  }

  pos.length = Math.round(size.width / 30);
  pos.l = Math.round((center.left - size.width - 10) / 30) - 1;
  //左上
  pos.t = Math.round(center.top / 30) - 1;
  hasLable = false;
  for (var i = pos.l; i < pos.l + pos.length; i++) {
    var o = screenText[i + "-" + pos.t];
    if (o) {
      if (o != id) {
        hasLable = true;
        break;
      }
    }
  }
  if (!hasLable) {
    result.canDraw = true;
    result.offsetX = -size.width - 10;
    result.offsetY = -heigthKey - (center.top - (pos.t + 1) * 30);
    for (var i = pos.l; i < pos.l + pos.length; i++) {
      screenText[i + "-" + pos.t] = id;
    }
    return result;
  }


  //左下
  pos.t = Math.round(center.top / 30) + 1;
  hasLable = false;
  for (var i = pos.l; i < pos.l + pos.length; i++) {
    var o = screenText[i + "-" + pos.t];
    if (o) {
      if (o != id) {
        hasLable = true;
        break;
      }
    }
  }
  if (!hasLable) {
    result.canDraw = true;
    result.offsetX = -size.width - 10;
    result.offsetY = heigthKey - (center.top - (pos.t - 1) * 30);
    for (var i = pos.l; i < pos.l + pos.length; i++) {
      screenText[i + "-" + pos.t] = id;
    }
    return result;
  }
  return result;
}

var wayPointStyle = function (f, r) {
  let style = new Style({
    image: new Circle({
      radius: 3,
      fill: new Fill({
        color: '#ffffff'
      }),
      stroke: new Stroke({
        color: '#3272dd',
        width: 3
      })
    })
  });
  var map = shipMap.map;
  var pix = map.getPixelFromCoordinate(f.getGeometry().getCoordinates());
  var name = f.get("timeStr");
  var size = textSize(name);
  var center = {};
  center.left = Math.round(pix[0]);
  center.top = Math.round(pix[1]);
  var re = calcLablePos3(center, size, f.getId());
  var styles = [];
  styles.push(style);
  if (re.canDraw) {
    if (Math.abs(re.offsetY) < 10) {
      if (re.offsetY <= 0)
        re.offsetY = -10;
      else
        re.offsetY = 10;
    }
    var ntext = new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({
        color: "#5F88AA"
      }),
      stroke: new Stroke({
        color: "#FFF",
        width: 3
      }),
      textBaseline: "bottom",
      offsetX: re.offsetX,
      offsetY: re.offsetY,
      text: name
    });
    style.setText(ntext);
    var textLine = new Style({
      fill: new Fill({
        color: '#00C000'
      }),
      stroke: new Stroke({
        color: '#FF0000',
        width: 0.5
      })
    });
    var e = [];
    e[0] = pix[0];
    e[1] = pix[1];
    if (re.offsetX > 0) {
      e[0] += 10;
      e[1] += re.offsetY;
    }
    if (re.offsetX < 0) {
      e[0] -= 10;
      e[1] += re.offsetY;
    }
    var end = map.getCoordinateFromPixel(e);
    var slGeo = new LineString([f.getGeometry().getCoordinates(), end]);
    textLine.setGeometry(slGeo);
    styles.push(textLine);
  }
  return styles;
}

//删除轨迹
shipFun.delPath = () => {
  shipMap.sourceList.pathLineSource.clear()
  shipMap.sourceList.pathPointSource.clear()
  __pathData = {}
  __pathArray = {}
}
// 删除单条轨迹
shipFun.delPathOne = (path, points) => {
  const pathLineSource = shipMap.sourceList.pathLineSource
  const pathPointSource = shipMap.sourceList.pathPointSource
  const Feature = pathLineSource.getFeatureById(path)
  delete __pathData[path];
  delete __pathArray[path];
  const startFeature = pathPointSource.getFeatureById(path + '-start')
  const endFeature = pathPointSource.getFeatureById(path + '-end')
  pathLineSource.removeFeature(Feature)
  pathPointSource.removeFeature(startFeature)
  pathPointSource.removeFeature(endFeature)
  for (let i = 0; i < points; i++) {
    const Feature = pathPointSource.getFeatureById(path + '-' + (i + 1))
    pathPointSource.removeFeature(Feature)
  }
}
//移动显示船舶信息及船舶轨迹信息
shipFun.showShipPathMessage = (map, Vue) => {
  let showMes = new Overlay({
    element: document.getElementById('showShipMessage')
  })
  let showPathMes = new Overlay({
    element: document.getElementById('showPathPointMessage')
  })
  let showPortMes = new Overlay({
    element: document.getElementById('showPortMessage')
  })

  map.on('pointermove', function (evt) {
    if (evt.dragging) {
      return
    }
    let pixel = map.getEventPixel(evt.originalEvent)
    let feature = map.forEachFeatureAtPixel(pixel, function (feature) {
      return feature
    }) //查询方式有很多
    if (feature) {
      let type = feature.getProperties()['type']
      if (type === 'ship') {
        Vue.shipFloatMes = {
          shipnameEn: feature.get('shipnameEn'),
          mmsi: feature.get('mmsi'),
          chuanboid: feature.get('shipid'),
          lon: shipFun.cacuLonLat(feature.get('lon') / 600000, 'lon'),
          lat: shipFun.cacuLonLat(feature.get('lat') / 600000, 'lat'),
          time: feature.get('posTime')
        }
        showMes.setPosition(feature.get('geom').getCoordinates())
        map.addOverlay(showMes)
      } else if (type === 'pathPoint') {
        Vue.shipFloatMes = {
          heading: feature.get('heading'),
          sog: feature.get('sog'),
          lon: shipFun.cacuLonLat(feature.get('lon'), 'lon'),
          lat: shipFun.cacuLonLat(feature.get('lat'), 'lat'),
          time: feature.get('time')
        }
        showPathMes.setPosition(feature.get('geom').getCoordinates())
        map.addOverlay(showPathMes)
      } else if (type === 'port') {
        // 港口鼠标事件
        Vue.shipFloatMes = {
          portNameCn: feature.get('portNmaeCn'),
          portNameEn: feature.get('portNmaeEn'),
          portCode: feature.get('portCode'),
          portLatLon: feature.get('portLatLon'),
        }
        showPortMes.setPosition(feature.get('geom').getCoordinates())
        map.addOverlay(showPortMes)
      }
    } else {
      map.removeOverlay(showMes)
      map.removeOverlay(showPathMes)
      map.removeOverlay(showPortMes)
    }
  })
}

shipFun.updateSize = (map) => {
  map.updateSize()
}
//添加船舶的选择框
shipFun.addSelect = (id, type) => {
  // let f = shipMap.sourceList.shipSource.getFeatureById(id)
  let f = shipMap.sourceList.berthSource.getFeatureById(id)
  let p = new Point(f.get('geom').getCoordinates())
  let s = new Feature({
    geometry: p
  })
  s.setStyle(shipStyle.selectStyle)
  shipMap.sourceList.selectSource.addFeature(s)
}
shipFun.addSelectByCoor = (coor) => {
  shipFun.delSelect()
  let Coor = transform(coor, 'EPSG:4326', 'EPSG:3857')
  let p = new Point(Coor)
  let s = new Feature({
    geometry: p
  })
  // shipFun.setCenter(Coor);
  // shipFun.setZoom(12);
  s.setStyle(shipStyle.selectStyle)
  shipMap.sourceList.selectSource.addFeature(s)
}
//消除船舶选中
shipFun.delSelect = () => {
  shipMap.sourceList.selectSource.clear()
}
//添加标记
shipFun.addSign = (map) => {
  map.addInteraction(shipMap.drawPointDraw)
  shipMap.drawPointDraw.on('drawstart', function (e) {
    e.feature.setStyle(shipStyle.signStyle)
  })
  shipMap.drawPointDraw.on('drawend', function (e) {
    map.removeInteraction(shipMap.drawPointDraw)
  })
}
//删除标记
shipFun.delSign = () => {
}
//设置海图中心
shipFun.setCenter = (coor) => {
  coor = transform(coor, 'EPSG:4326', 'EPSG:3857')
  shipMap.view.setCenter(coor)
}
// 绘制警戒线
shipFun.drawLine = function (id, data, color, width, name, isDotted) {
  if (!color) {
    color = '#FF0000';
  }
  if (!width) {
    width = 1;
  }
  var feature = lineDataTrans(data);
  feature.setId(id);
  var style11 = null;
  if (isDotted) {
    style11 = new Style({
      stroke: new Stroke({
        color: color,
        width: width,
        lineDash: [5, 5]
      })
    });
  } else {
    style11 = new Style({
      stroke: new Stroke({
        color: color,
        width: width
      })
    });
  }
  if (name) {
    var ntext = new Text({
      textAlign: "left",
      font: '10px Microsoft YaHei',
      fill: new Fill({color: "#5F88AA"}),
      stroke: new Stroke({color: "#FFF", width: 3}),
      textBaseline: "bottom",
      offsetX: 0,
      offsetY: -8,
      overflow: true
    });
    ntext.setText(name);
    style11.setText(ntext);
  }
  feature.setStyle(style11);
  shipMap.sourceList.jjxSource.addFeature(feature);
}


shipFun.delTyphoon = function (name) {
  shipMap.sourceList.taifeng.removeFeature(shipMap.sourceList.taifeng.getFeatureById(name + '1'));
  window.wulaFeature[name] = null;
  shipMap.sourceList.taifeng.removeFeature(shipMap.sourceList.taifeng.getFeatureById(name + '2'));
  shipMap.sourceList.taifeng.forEachFeature(function (f) {
    if (f.get("lineName") == name) {
      shipMap.sourceList.taifeng.removeFeature(f);
    }
  })
  //清除台风定时器
  for (var i = 0; i < window.wulaTime[name].length; i++) {
    window.clearTimeout(window.wulaTime[name][i])
  }
  window.wulaTime[name].length = 0;
}

shipFun.hideTyphoon = function () {
  shipMap.sourceList.taifeng.clear();
  window.wulaFeature = [];
  for (let x in window.wulaTime) {
    for (var i = 0; i < window.wulaTime[x].length; i++) {
      window.clearTimeout(window.wulaTime[x][i])
    }
    window.wulaTime[x].length = 0;
  }
}
//绘制台风图层new
shipFun.showTaiFengNew2 = function (tdata, level, time, name) {
  var data = tdata.data;

  var arr = data.filter(function (item, index) {
    item.longitude = item.lon;
    if (index > 0) {
      if ((item.lon - data[index - 1].lon) < -180)
        item.lon += 360;
      else if ((item.lon - data[index - 1].lon) > 180)
        item.lon -= 360;

    }
    item.f = item.forcast.filter(function (it, idx) {
      if (idx === 0) {
        if ((it.lon - item.lon) < -180)
          it.lon += 360;
        else if ((it.lon - item.lon) > 180)
          it.lon -= 360;
      }
      if (idx > 0) {
        if ((it.lon - item.forcast[idx - 1].lon) < -180)
          it.lon += 360;
        else if ((it.lon - item.forcast[idx - 1].lon) > 180)
          it.lon -= 360;
      }
      return it;
    });
    return item;
  });
  var his = [], current, fut = [], arrLength;
  arrLength = arr.length;
  for (var i = 0; i < arrLength - 1; i++) {
    arr[i].t = 0;
    his.push(arr[i]);
    if (arr[i].f.length > 0) {
      arr[i].f.unshift(arr[i]);
    }
  }
  current = arr[arrLength - 1];
  current.t = 1;
  for (var i = 0; i < current.f.length; i++) {
    current.f[i].t = 2;
    current.f[i].longitude = current.f[i].lon;
    fut.push(current.f[i]);
  }
  var all = his.concat(current);
  all = all.concat(fut);

  /*var startll = ol.proj.fromLonLat([arr[0].lon, arr[0].lat]);
  var startf = new ol.Feature({
      geometry: new Point(startll)
  });
  startf.set("name",tdata.seq);
  startf.setStyle(typhoonStart);
  Source.taifeng.addFeature(startf);*/

  var center = fromLonLat([current.lon, current.lat]);
  var ct = new Feature({
    geometry: new Point(center)
  });
  ct.set("name", tdata.seq);
  ct.setStyle(typhoonCenter2);
  ct.set("code", tdata.code);
  Source.taifeng.addFeature(ct);
  drawTyphoonNew(all, tdata.seq, tdata.code, name);
  var rad_neq34kt = parseInt(current.radius7);
  var rad_neq50kt = parseInt(current.radius10);//暴风圈
  var liefeng = new ol.Feature({
    geometry: new CircleGeom(center, rad_neq34kt * 1000)
  });
  var baofeng = new ol.Feature({
    geometry: new CircleGeom(center, rad_neq50kt * 1000)
  });

  liefeng.setStyle(liefengStyle);
  baofeng.setStyle(baofengStyle);
  liefeng.set("code", tdata.code);
  baofeng.set("code", tdata.code);

  //绑定定时器的数组
  if (window.wulaTime[name] == undefined) {
    window.wulaTime[name] = [];
  }
  if (window.wulaTime[name].length == 0) {
    //尝试改变台风的显示样式开始
    for (var i = 0; i < all.length; i++) {
      (function (a) {
        var k = setTimeout(function () {
          typhoonMove(all[a], level, name);
        }, a * time * 1000); //.....
        window.wulaTime[name][a] = k;
      })(i)
    }
    //最后一个定时器 显示台风当前的点的位置
    all.filter(function (item, index, arr) {
      if (item.t == 1) {
        var k = setTimeout(function () {
          typhoonMove(all[index], level, name)
        }, all.length * time * 1000)
        window.wulaTime[name][all.length] = k;
      }
    })
  }


  //尝试改变台风的显示样式结束
}

function typhoonCenter2(f, r) {
  var s = new Style({
    image: new Icon({
      src: 'images/msmap/current.png',
      anchor: [0.5, 1.1]
    })
  });
  var ntext = new Text({
    textAlign: "left",
    font: '12px Microsoft YaHei',
    fill: new Fill({
      color: "#5F88AA"
    }),
    stroke: new Stroke({
      color: "#FFF",
      width: 3
    }),
    textBaseline: "bottom",
    offsetX: 8,
    offsetY: -8,
    text: f.get('name')
  })
  s.setText(ntext);
  return [s];
}

function lineDataTrans(json) {
  var data = [];
  for (var i in json) {
    data.push({lon: Number(json[i].lon), lat: Number(json[i].lat)});
  }
  data.map(function (item, index, arr) {
    if (index > 0) {
      if ((item.lon - arr[index - 1].lon) < -180)
        item.lon += 360;
      else if ((item.lon - arr[index - 1].lon) > 180) {
        var i = index - 1;
        while (i >= 0) {
          arr[i--].lon += 360;
        }
      }

    }

  });
  var ar = [];
  data.forEach(function (item, index) {
    ar.push(transform([Number(item.lon), Number(item.lat)], 'EPSG:4326', 'EPSG:3857'));
  });
  var ls = new LineString(ar);
  var lsf = new Feature({
    geometry: ls
  });
  lsf.set("type", "line");
  return lsf;
};

//设置地图层级
shipFun.setZoom = (num) => {
  shipMap.view.setZoom(num)
}
//添加eez线
shipFun.addEez = (map, state) => {
  if (state) {
    map.addLayer(shipMap.layerList.eezLayer)
  } else {
    map.removeLayer(shipMap.layerList.eezLayer)
  }
}

// ---我的修改---
//添加测距
shipFun.addRanging = (map, type) => {
  map.removeInteraction(shipMap.drawPolygonDraw)
  map.removeInteraction(shipMap.drawRingDraw)
  map.removeInteraction(shipMap.drawRectangleDraw)
  if (type == 'radius') {
    shipMap.drawRingDraw.maxPoints_ = 2
  } else {
    shipMap.drawRingDraw.maxPoints_ = Infinity
  }

  map.addInteraction(shipMap.drawRingDraw)
  let listener = null
  let sketch = null
  shipMap.drawRingDraw.on(
    'drawstart',
    function (e) {
      let tooltipCoord = e.coordinate
      sketch = e.feature
      listener = sketch.getGeometry().on('change', function (evt) {
        let geom = evt.target
        let output
        if (geom instanceof LineString) {
          output = shipFun.formatLength(geom)
          tooltipCoord = geom.getLastCoordinate()
        }
        shipMap.measureTooltipElement.innerHTML =
          output +
          '' +
          `<span   class="el-icon-circle-close"  style="margin-left: 9px;cursor: pointer;" onclick="window.deleteClick('delect'+'-'+${e.feature.ol_uid},'line')"  ></span>`
        shipMap.measureTooltipElement.style =
          'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
        shipMap.measureTooltip.setPosition(tooltipCoord)
      })
    },
    this
  )
  shipMap.drawRingDraw.on('drawend', function (e) {
    map.removeInteraction(shipMap.drawRingDraw)
    shipMap.measureTooltipElement.style =
      'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
    shipMap.measureTooltipElement.className = `ol-tooltip ol-tooltip-static `
    shipMap.measureTooltipElement.setAttribute('id', sketch.ol_uid)
    shipMap.measureTooltip.setOffset([0, -7])
    sketch = null
    shipMap.measureTooltipElement = null
    shipFun.createMeasureTooltip(map)
    unByKey(listener)
    shipMap.maxpoint = 'infinity'
  })
}
//我的修改 测距多边形
shipFun.addPolygon = (map) => {
  map.removeInteraction(shipMap.drawPolygonDraw)
  map.removeInteraction(shipMap.drawRingDraw)
  map.removeInteraction(shipMap.drawCircleDraw)
  map.removeInteraction(shipMap.drawRectangleDraw)
  map.addInteraction(shipMap.drawPolygonDraw)
  let listener = null
  let sketch = null
  shipMap.drawPolygonDraw.on(
    'drawstart',
    function (e) {
      let tooltipCoord = e.coordinate
      sketch = e.feature
      listener = sketch.getGeometry().on('change', function (evt) {
        let geom = evt.target
        let output
        if (geom instanceof Polygon) {
          output = shipFun.formatArea(geom)
          tooltipCoord = geom.getInteriorPoint().getCoordinates()
        }
        shipMap.measureTooltipElement.innerHTML =
          output +
          '' +
          `<span   class="el-icon-circle-close"  style="margin-left: 9px;cursor: pointer;" onclick="window.deleteClick('delect'+'-'+${e.feature.ol_uid},'polygon')"  ></span>`
        shipMap.measureTooltipElement.style =
          'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
        shipMap.measureTooltip.setPosition(tooltipCoord)
      })
    },
    this
  )
  shipMap.drawPolygonDraw.on('drawend', function (e) {
    map.removeInteraction(shipMap.drawPolygonDraw)
    shipMap.measureTooltipElement.style =
      'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
    shipMap.measureTooltipElement.className = `ol-tooltip ol-tooltip-static `
    shipMap.measureTooltipElement.setAttribute('id', sketch.ol_uid)
    shipMap.measureTooltip.setOffset([0, -7])
    sketch = null
    shipMap.measureTooltipElement = null
    shipFun.createMeasureTooltip(map)
    unByKey(listener)
  })
}
// ---我的修改---
shipFun.backVector = (type) => {
  if (type === 'line') {
    return shipMap.drawRingSource
  } else if (type === 'circle') {
    return shipMap.drawCircleSource
  } else if (type === 'polygon') {
    return shipMap.drawPolygonSource
  } else if (type === 'rectangle') {
    return shipMap.drawRectangleSource
  }
}

shipFun.delAllMapTool = () => {
  shipMap.drawPolygonLayer.getSource().clear()
  shipMap.drawCircleLayer.getSource().clear()
  shipMap.drawRectangleLayer.getSource().clear()
  shipMap.drawRingLayer.getSource().clear()
  shipMap.map.getOverlays()
    .getArray().forEach((item) => {
    shipMap.map.removeOverlay(item)
  })
}
// ---我的修改---
//清楚圆
shipFun.deleCircular = () => {
  shipMap.drawCircularSource.clear()
}
//清楚测距
shipFun.deleRing = () => {
  shipMap.drawRingSource.clear()
  let list = document.getElementsByName('ceju')
  for (let i = 0; i < list.length; i++) {
    list[i].style.display = 'none'
    // removeNode(true)
  }
}

//设置绑定轨迹数据的div
shipFun.createMeasureTooltip = function (map) {
  if (shipMap.measureTooltipElement) {
    shipMap.measureTooltipElement.parentNode.removeChild(
      shipMap.measureTooltipElement
    )
  }
  shipMap.measureTooltipElement = document.createElement('div')
  shipMap.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'
  shipMap.measureTooltip = new Overlay({
    element: shipMap.measureTooltipElement,
    offset: [1, -15],
    positioning: 'bottom-center'
  })
  map.addOverlay(shipMap.measureTooltip)
  mapToolOver.push(shipMap.measureTooltip)
}

//获取测距的长度
var ringLength = 0
shipFun.formatLength = function (line) {
  let length = getLength(line)
  ringLength = length
  let output
  if (length > 100) {
    output = (Math.round((length / 1000) * 100) / 100) * +' ' + 'km'
  } else {
    output = Math.round(length * 100) / 100 + ' ' + 'm'
  }
  output = Math.round(length * 0.00054 * 100) / 100 + ' ' + 'nm'
  return output
}
//我的修改

//获取多边形面积和矩形
shipFun.formatArea = function (polygon) {
  var area = getArea(polygon)
  var output
  if (area > 1000000) {
    output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>'
  } else {
    output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>'
  }
  return output
}
//我的修改

shipFun.addRectangle = (map) => {
  map.removeInteraction(shipMap.drawPolygonDraw)
  map.removeInteraction(shipMap.drawRingDraw)
  map.removeInteraction(shipMap.drawCircleDraw)
  map.removeInteraction(shipMap.drawRectangleDraw)
  map.addInteraction(shipMap.drawRectangleDraw)
  let listener = null
  let sketch = null
  shipMap.drawRectangleDraw.on('drawstart', function (e) {
    sketch = e.feature
    let tooltipCoord = e.coordinate
    listener = sketch.getGeometry().on('change', function (evt) {
      let geom = evt.target

      let output
      if (geom instanceof Polygon) {
        output = shipFun.formatArea(geom)
        tooltipCoord = geom.getInteriorPoint().getCoordinates()
      }
      shipMap.measureTooltipElement.innerHTML =
        output +
        '' +
        `<span   class="el-icon-circle-close"  style="margin-left: 9px;cursor: pointer;" onclick="window.deleteClick('delect'+'-'+${e.feature.ol_uid},'rectangle')"  ></span>`
      shipMap.measureTooltipElement.style =
        'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
      shipMap.measureTooltip.setPosition(tooltipCoord)
    })
  })
  shipMap.drawRectangleDraw.on('drawend', function (e) {
    map.removeInteraction(shipMap.drawRectangleDraw)
    shipMap.measureTooltipElement.style =
      'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
    shipMap.measureTooltipElement.className = `ol-tooltip ol-tooltip-static `
    shipMap.measureTooltipElement.setAttribute('id', sketch.ol_uid)
    shipMap.measureTooltip.setOffset([0, -7])
    sketch = null
    shipMap.measureTooltipElement = null
    shipFun.createMeasureTooltip(map)
    unByKey(listener)
  })
}
// 我的修改
//获取圆的半径长度
shipFun.formatcirclelength = function (a) {
  let output
  let area = Math.pow(a, 2) * Math.PI // 得到的圆的面积 单位平方米
  if (area > 1000000) {
    output =
      Math.round(area / 1000000 * 100) / 100 +
      ' ' +
      'km²'
  } else {
    output = Math.round(area * 100) / 100 + ' ' + 'm²'
  }
  return output
}
//我的修改

//添加圆
shipFun.addCircle = (map) => {
  map.removeInteraction(shipMap.drawPolygonDraw)
  map.removeInteraction(shipMap.drawCircleDraw)
  map.removeInteraction(shipMap.drawRectangleDraw)
  map.addInteraction(shipMap.drawCircleDraw)
  let listener = null
  let sketch = null
  shipMap.drawCircleDraw.on('drawstart', function (e) {
    sketch = e.feature
    let tooltipCoord = e.coordinate
    listener = sketch.getGeometry().on('change', function (evt) {
      let geom = evt.target

      let a1 = []
      let a2 = []
      a1 = transform(geom.getCenter(), 'EPSG:3857', 'EPSG:4326')
      a2 = transform(geom.getLastCoordinate(), 'EPSG:3857', 'EPSG:4326')
      shipMap.measureTooltip.setPosition(geom.getCenter())
    })
  })

  shipMap.drawCircleDraw.on('drawend', function (e) {
    map.removeInteraction(shipMap.drawCircleDraw)
    shipMap.measureTooltipElement.style =
      'background: #0050AC;color:#ffffff;padding:2px;border-radius: 10px;font-size: 10px;min-width: 87px;text-align: center'
    shipMap.measureTooltipElement.className = `ol-tooltip ol-tooltip-static `
    shipMap.measureTooltipElement.setAttribute('id', sketch.ol_uid)
    let output = shipFun.formatcirclelength(e.feature.getGeometry().getRadius())
    shipMap.measureTooltipElement.innerHTML =
      output +
      '' +
      `<span   class="el-icon-circle-close"  style="margin-left: 9px;cursor: pointer;" onclick="window.deleteClick('delect'+'-'+${e.feature.ol_uid},'circle')"  ></span>`

    shipMap.measureTooltip.setOffset([0, 0])
    sketch = null
    shipMap.measureTooltipElement = null
    shipFun.createMeasureTooltip(map)
    unByKey(listener)
  })
}
//我的修改
//转换地图海图卫星图
shipFun.changeMap = function (map, str) {
  switch (str) {
    case 'haitu':
      map.removeLayer(shipMap.sateLayer)
      map.removeLayer(shipMap.layer)
      map.removeLayer(shipMap.tdtLayer)
      map.addLayer(shipMap.seaLayer)
      break
    case 'weixingtu':
      map.removeLayer(shipMap.seaLayer)
      map.removeLayer(shipMap.layer)
      map.removeLayer(shipMap.tdtLayer)
      map.addLayer(shipMap.sateLayer)
      break
    case 'ditu':
      map.removeLayer(shipMap.sateLayer)
      map.removeLayer(shipMap.seaLayer)
      map.removeLayer(shipMap.tdtLayer)
      map.addLayer(shipMap.layer)
      break
    case 'tdt':
      map.removeLayer(shipMap.sateLayer)
      map.removeLayer(shipMap.seaLayer)
      map.removeLayer(shipMap.layer)
      map.addLayer(shipMap.tdtLayer)
  }
}
//添加线段
shipFun.addArgentina = (data, id) => {
  let f1 = lineDataTrans2(data)
  f1.setStyle(shipStyle.agtStyle('#FF5454', 2))
  f1.setId(id)
  shipMap.agtSource.addFeature(f1)
}
//获取测距的

//获得的经纬度转换
shipFun.aroundLonLat = (value) => {
  let lonlat = transform(value, 'EPSG:3857', 'EPSG:4326')
  return lonlat
}

//经纬度转化
shipFun.cacuLonLat = function (num, dir) {
  let degree = parseInt(num)
  let direction = null
  if (dir == 'lon') {
    if (degree >= 0) {
      direction = 'E'
    } else {
      direction = 'W'
    }
  } else if (dir == 'lat') {
    if (degree >= 0) {
      direction = 'N'
    } else {
      direction = 'S'
    }
  }
  let min = parseInt((num - degree) * 60)
  let sec = parseInt((num - degree) * 3600 - min * 60)

  degree = Math.abs(degree)
  min = Math.abs(min)
  sec = Math.abs(sec)

  let array = [direction, degree + '°' + min + '′' + sec + '″'] //这个得到的是方向 度 分 秒
  return array
}

shipFun.clickGetCoor = function (index, cb) {
  shipMap.map.once('singleclick', (e) => {
    const coor = e.coordinate
    const f = new Feature({
      geometry: new Point(coor)
    })
    f.setStyle(pointInnerStyle(index + ''))
    shipMap.sourceList.PointSource.addFeature(f)
    cb(transform(coor, 'EPSG:3857', 'EPSG:4326'))
  })
}

shipFun.clearPoint = function () {
  shipMap.sourceList.PointSource.clear()
}

function pointInnerStyle(textVale) {
  const textStyle = new Style({
    text: new Text({
      textAlign: 'center',
      textBaseline: 'middle',
      font: '20px',
      fill: new Fill({
        color: 'red'
      }),
      text: textVale,
      stroke: new Stroke({
        color: 'white',
        width: 2
      })
    })
  })
  return textStyle
}

//生成随机数
function Random() {
  return Math.floor(Math.random() * 10) // 可均衡获取 0 到 9 的随机整数。
}

//根据数据处理数据函数
function lineDataTrans2(d) {
  let data = []
  let d1 = d.split(',')
  for (let i1 in d1) {
    let d2 = d1[i1].split(' ')
    data.push({
      lon: Number(d2[0]),
      lat: Number(d2[1])
    })
  }
  data.map(function (item, index, arr) {
    if (index > 0) {
      if (item.lon - arr[index - 1].lon < -180) {
        item.lon += 360
      } else if (item.lon - arr[index - 1].lon > 180) {
        let i = index - 1
        while (i >= 0) {
          arr[i--].lon += 360
        }
      }
    }
  })
  let ar = []
  data.forEach(function (item, index) {
    ar.push(fromLonLat([Number(item.lon), Number(item.lat)]))
  })
  let ls = new LineString(ar)
  let lsf = new Feature({
    geometry: ls
  })
  lsf.set('type', 'line')
  return lsf
}

export default shipFun
