window.getMarkerPopup = function (attr) { let shiptype = attr.attributes.shiptype; if (attr.attributes.shipType) { shiptype = attr.attributes.shipType; } if (!shiptype) { shiptype = "未知" } let englishName = attr.attributes.englishName ? attr.attributes.englishName : "-" let MMSI = attr.attributes._targetID ? attr.attributes._targetID : "-" let name = attr.name ? attr.name : "-" let countryname = attr.attributes.countryname ? attr.attributes.countryname : "-" let time = '-' if( typeof attr.time === 'number' ){ if((attr.time+"").length === 10 ){ time = formatDate(attr.time * 1000) }else if((attr.time+"").length === 13){ time = formatDate(attr.time) } }else if(typeof attr.time === 'string'){ if(attr.time.length === 10 ){ time = formatDate(parseInt(attr.time) * 1000) }else if(attr.time.length === 13){ time = formatDate(parseInt(attr.time)) } } let speed = attr.attributes.speed ? attr.attributes.speed : "-" let course = attr.attributes.course ? attr.attributes.course : "-" var html = "
" + "MMSI:" + MMSI + "
" + "名称:" + name + "
" + "英文名称:" + englishName + "
" + "国籍:" + countryname + "
" + "类型:" + shiptype + "
" + "经度:" + attr.lon + "
" + "纬度:" + attr.lat + "
" + "更新时间:" + time + "
" + "转向:" + course + "
" //1:雷达;2:AIS 3:ADSB 4:北斗 5:GPS + "来源:" + (attr.attributes.dataflag == 1 ? '雷达' : attr.attributes.dataflag == 2 ? 'AIS' : attr.attributes.dataflag == 3 ? 'ADSB' : attr.attributes.dataflag == 4 ? '北斗' : attr.attributes.dataflag == 5 ? 'GPS' : attr.layerCnName) + "
" + "速度:" + speed + "
" + "
" return html; } // let websocket_layername = { "zt_cbzt_kyc_ss": true, "zt_cbzt_hc_ss": true, "zt_cbzt_yc_ss": true, "zt_cbzt_qt_ss": true, "zt_cbzt_ld_ss": true, "zt_cbzt_sw_ss": true, "zt_cbzt_wz_ss": true, "zt_cbzt_gz_ss": true, "zt_cbzt_tc_ss": true, "zt_cbzt_yhc_ss": true, "zt_cbzt_gc_ss": true }; let websocket_layername = { "cz_czlltc_wgy":true,"zt_cbzt_kyc_ss": true, "zt_cbzt_hc_ss": true, "zt_cbzt_yc_ss": true, "zt_cbzt_qt_ss": true, "zt_cbzt_ld_ss": true, "zt_cbzt_sw_ss": true, "zt_cbzt_wz_ss": true, "zt_cbzt_gz_ss": true, "zt_cbzt_tc_ss": true, "zt_cbzt_yhc_ss": true, "zt_cbzt_gc_ss": true }; let loadYJLayer = {}; L.TileLayer.WMTS.REALTIME = L.TileLayer.WMTS.extend({ options: { tileSize: 256, realtimeLayer: '', gjLayer: '', showrealtimelevel: 14, showLabellevel: 14, markerPopup: window.getMarkerPopup, time: 600, ObjType: '2', pointX:130, pointY:315, // websocketUrl : 'ws://localhost:8084/websocket/' websocketUrl: 'ws://10.110.35.104/websocket/' // websocketUrl : 'ws://10.110.35.88:8080/websocket/' }, realtimeMarkerLayerGroup: {}, realtimeHander: [], removeOutTimeHander: [], realtimeIcon: {}, markerGroup: {}, moveendHander: null, zoomendHander: null, realtimeGJLayer: {}, markerDrawJ: null, pupopOpenHander: null, gjLayer: {}, gjPaly: {}, eventMap: {}, messageType: "", realtimeWebsocket: null, realtimeParam: "", wgyInfoMap : new Map(), initialize: function (url, jsonUrl, options, markerClick) { // (String, Object) // options.sessionToken = window.sessionToken; this._jsonUrl = jsonUrl; this._url = url; this.markerClick = markerClick var wmtsParams = L.extend({}, this.defaultWmtsParams); var tileSize = options.tileSize || this.options.tileSize; if (options.detectRetina && L.Browser.retina) { wmtsParams.width = wmtsParams.height = tileSize * 2; } else { wmtsParams.width = wmtsParams.height = tileSize; } for (var i in options) { // all keys that are not TileLayer options go to WMTS params if (!this.options.hasOwnProperty(i) && i != "matrixIds" && i != "jsonUrl") { wmtsParams[i] = options[i]; } } this.wmtsParams = wmtsParams; this.matrixIds = options.matrixIds || this.getDefaultMatrix(); if (!options.zIndex || options.zIndex < 10) { options.zIndex = 10; } L.setOptions(this, options); this.realtimeMarkerLayerGroup.curZoom = window.map.getZoom(); this.realtimeMarkerLayerGroup.realtimeLayerGroup = L.layerGroup().addTo(window.map); this.realtimeGJLayer.layerGroup = L.layerGroup().addTo(window.map); this.gjLayer.layerGroup = L.layerGroup().addTo(window.map); this.markerDrawJ = L.layerGroup().addTo(window.map); this.gjLayer.gjPoyline = {}; this.gjLayer.gjCircleMarker = {}; this.gjLayer.seMarker = {}; this.realtimeGJLayer.gj = {}; this.realtimeGJLayer.ssgjOnMap = {}; this.currentRealTimeListObj = {} var _this = this; this.eventMap = { click: function (ev) { }, moveend: function (ev) { if (_this.moveendHander) { clearTimeout(_this.moveendHander); } _this.moveendHander = setTimeout(function () { _this.removeOutBounds(); }, 500); }, zoomend: function (ev) { if (_this.zoomendHander) { clearTimeout(_this.zoomendHander); } _this.zoomendHander = setTimeout(function () { _this.realtimeUpdate(); }, 500); } }; window.map.on(this.eventMap); /*window.map.on('moveend', function(ev) { //console.log("....."+ev); if(_this.moveendHander){ clearTimeout(_this.moveendHander); } _this.moveendHander = setTimeout(function(){ _this.removeOutBounds(); //_this.realtimeUpdate(); },1000); //_this.markerLayerGroup = L.marker(ev.latlng,{iconUrl:'images/marker-icon-2x.png'}).addTo(map); });*/ /*window.map.on('zoomend', function(ev) { _this.realtimeUpdate(); });*/ //window.gjThis = this; //window.goOpenGJ = this.goOpenGJ; if (this.realtimeHander && this.realtimeHander.length > 0) { for (var i in this.realtimeHander) { clearInterval(this.realtimeHander[i]); } } this.clearMarker(); var _this = this; this.realtimeHander.push(setInterval(function () { if (_this.messageType == "http") { _this.realtimeUpdate(); } }, 1000)); this.removeOutTimeHander.push(setInterval(function () { _this.removeOutTime() }, 1000)); }, // @method createTile(coords: Object, done?: Function): HTMLElement // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile) // to return an `` HTML element with the appropiate image URL given `coords`. The `done` // callback is called when the tile has been loaded. createTile: function (coords, done) { var tile = document.createElement('img'); L.DomEvent.on(tile, 'load', L.bind(this._tileOnLoad, this, done, tile)); L.DomEvent.on(tile, 'error', L.bind(this._tileOnError, this, done, tile)); if (this.options.crossOrigin) { tile.crossOrigin = ''; } /* Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons http://www.w3.org/TR/WCAG20-TECHS/H67 */ tile.alt = ''; /* Set role="presentation" to force screen readers to ignore this https://www.w3.org/TR/wai-aria/roles#textalternativecomputation */ if (coords.z < this.options.showrealtimelevel) { tile.setAttribute('role', 'presentation'); tile.src = this.getTileUrl(coords); this.clearMarker(); } else { tile.src = ""; //window.map.removeLayer(this); this.realtimeUpdate(); } return tile; }, sendRemoveLayerMsg: function () { if (this.realtimeWebsocket) { //发送消息后台删除相应的图层 let deleteParam = this.getParam(); deleteParam.deletelayername = this.options.realtimeLayer this.realtimeParam = JSON.stringify(deleteParam); this.sendWebsocketMsg(); //this.realtimeWebsocket.close(); this.realtimeWebsocket = null; // window.realtimeWebsocketHandle[this.options.realtimeLayer] = null; if (window.realtimeWebsocketHandle[this.options.realtimeLayer]) { delete window.realtimeWebsocketHandle[this.options.realtimeLayer]; } /*if(!window.realtimeWebsocketHandle || Object.keys(window.realtimeWebsocketHandle).length <= 0 ){ window.realtimeWebsocket.close(); window.realtimeWebsocketCreated =null; window.realtimeWebsocket = null; }*/ } }, onRemove: function (map) { //map.removeLayer(this); this.yjHander this.sendRemoveLayerMsg(); if (this.realtimeHander && this.realtimeHander.length > 0) { for (var i in this.realtimeHander) { clearInterval(this.realtimeHander[i]); this.realtimeHander[i] = null; } this.realtimeHander = []; } if (this.removeOutTimeHander && this.removeOutTimeHander.length > 0) { for (var i in this.removeOutTimeHander) { clearInterval(this.removeOutTimeHander[i]); this.removeOutTimeHander[i] = null; } this.removeOutTimeHander = []; } /* for (var k in this.markerGroup) { let m = this.markerGroup[k]; this.removeMarker(k); m = null; }*/ this.clearMarker(); window.map.off(this.eventMap); L.TileLayer.WMTS.prototype.onRemove.call(this, map); }, clearMarker: function () { //this.realtimeMarkerLayerGroup.realtimeLayerGroup.clearLayers(); for (let i in this.markerGroup) { this.removeMarker(i); } this.markerGroup = {}; this.realtimeGJLayer.layerGroup.clearLayers(); this.realtimeGJLayer.gj = {}; this.realtimeGJLayer.gjCircleMarker = {}; this.markerDrawJ.clearLayers(); }, removeMarker: function (id) { if (this.markerGroup[id]) { if (this.markerGroup[id]._icon) { L.DomUtil.remove(this.markerGroup[id]._icon); } console.log(this.markerGroup[id].attributes.realtimeLayer); this.realtimeMarkerLayerGroup.realtimeLayerGroup.removeLayer(this.markerGroup[id]); delete this.markerGroup[id]; } if (this.realtimeGJLayer.gj[id]) { this.realtimeGJLayer.layerGroup.removeLayer(this.realtimeGJLayer.gj[id]); delete this.realtimeGJLayer.gj[id]; } if (this.realtimeGJLayer.gjCircleMarker[id]) { this.realtimeGJLayer.layerGroup.removeLayer(this.realtimeGJLayer.gjCircleMarker[id]); delete this.realtimeGJLayer.gjCircleMarker[id]; } }, removeOutTime: function () { var datatime = Math.ceil(new Date().getTime() / 1000) - this.options.time; var m; var size = 0 for (var k in this.markerGroup) { m = this.markerGroup[k]; if (m.attributes && parseInt(m.attributes.time) < datatime) { this.removeMarker(k); m = null; } size++; } console.log(this.options.realtimeLayer, ":", size); }, removeOutBounds: function () { var bound = window.map.getBounds(); var m; for (var k in this.markerGroup) { m = this.markerGroup[k]; if (!bound.contains(m.getLatLng())) { this.removeMarker(k); m = null; } } }, getFanweiConfig: function () { var minx = window.map.getBounds().getSouthWest().lng , maxx = window.map.getBounds().getNorthEast().lng , miny = window.map.getBounds().getSouthWest().lat , maxy = window.map.getBounds().getNorthEast().lat; var options = this.options var fanweiConfig = '' if (options.point) { fanweiConfig = this.getParamString({ point: options.point, radius: options.radius }) } else if (options.polygon) { fanweiConfig = this.getParamString({ polygon: options.polygon }) } else if (options.bbox) { fanweiConfig = this.getParamString({ bbox: options.bbox }) } else { fanweiConfig = "?bbox=" + encodeURIComponent("BBOX(" + minx + "," + maxx + "," + maxy + "," + miny + ")") } fanweiConfig = '&' + fanweiConfig.substr(1) return fanweiConfig }, clearSsgjOnMap: function (shipId) { var obj = this.realtimeGJLayer.ssgjOnMap[shipId] if (!obj) { return } if (obj.line) { this.realtimeGJLayer.layerGroup.removeLayer(obj.line); delete obj.line } if (obj.point) { obj.point.forEach((e) => { this.realtimeGJLayer.layerGroup.removeLayer(e); }) delete obj.point } }, setSsgjOnMapStatus: function (shipId, val) { // 设置实时图标是否进行轮询记录 var status = !!val var obj = this.realtimeGJLayer.ssgjOnMap[shipId] if (!obj) { this.realtimeGJLayer.ssgjOnMap[shipId] = {} obj = this.realtimeGJLayer.ssgjOnMap[shipId] } this.realtimeGJLayer.ssgjOnMap[shipId].on = status if (status) { this.setMarkerSsgjOnMap(shipId) } else { this.clearSsgjOnMap(shipId) } }, setMarkerSsgjOnMap: function (shipId) { // 记录轮询时图标的点位和线段,形成轨迹 var ship = this.currentRealTimeListObj[shipId] var obj = this.realtimeGJLayer.ssgjOnMap[shipId] if (obj && obj.on) { var point = L.circleMarker([ship.lat, ship.lon], { radius: 3, color: '#00f' }) point.addTo(this.realtimeGJLayer.layerGroup); if (obj.point && obj.point.length) { obj.point.push(point) obj.line.addLatLng([ship.lat, ship.lon]) } else { obj.line = L.polyline([[ship.lat, ship.lon]], { color: 'red' }) obj.line.addTo(this.realtimeGJLayer.layerGroup) obj.point = [point] } } }, realtimeUpdate: function (callback) { if (window.map.getZoom() < this.options.showrealtimelevel || this.gjPaly.isPlay) { this.sendRemoveLayerMsg(); for (var k in this.markerGroup) { let m = this.markerGroup[k]; this.removeMarker(k); m = null; } this.clearMarker(); return; } /*if( this.realtimeMarkerLayerGroup.curZoom != window.map.getZoom() ){ this.clearMarker(); this.realtimeMarkerLayerGroup.curZoom = window.map.getZoom(); }*/ /*this.wmtsParams.format = "realtimejson"; this.wmtsParams.layer = this.options.realtimeLayer; this.wmtsParams.tilematrix = window.map.getZoom();*/ // let url = this.getParamString(this.wmtsParams, this._jsonUrl); // 实时船舶变成三角形图标后的查询接口 /** * 实时websocket连接对象: * { * realtimeWebsocket: * { * websocket:new WebSocket("ws://localhost:8080/websocket/{layername}/{filterjson}") * layername:this.options.realtimeLayer * param:{bbox:'minx,maxx,maxy,miny'---矩形边界查询条件 * ,cicle:point,radius ----圆圈查询条件,point:圆心,radius:半径 * ,polygon:polygon ----多边形查询条件,polygon:多边形边界坐标 * ,time:10 } ----在线时间,单位秒,10秒 * } */ if ((this.options.realtimeLayer in websocket_layername)) { if (this.messageType != "http") { //websocket连接方式 this.realtimeWebsocket = createWebSocket(this); } } else { this.messageType = "http" } if (this.realtimeWebsocket && this.messageType == "websocket") { if (window.realtimeWebsocketCreated) { let newParam = JSON.stringify(this.getParam()); if (this.realtimeParam !== newParam) { this.realtimeParam = newParam; this.sendWebsocketMsg() } } } else { this.messageType = "http"; console.log('当前浏览器 Not support websocket'); var datatime = new Date().getTime(); var endTimeSecond = Math.ceil(datatime / 1000) var startTimeSecond = Math.ceil(datatime / 1000) - this.options.time; let url = this._jsonUrl + "?format=realtimejson&layer=" + this.options.realtimeLayer + "&tilematrix=" + window.map.getZoom() + this.getFanweiConfig() + "&customsQuery=" + encodeURIComponent("{\"must\":[{\"range\":{\"attributes.collecTime\":{\"lte\":" + endTimeSecond + ",\"gt\":" + startTimeSecond + "}}}]}"); /*if( this.wmtsParams.keyworks ){ url += this.getParamString({ keyworks:this.wmtsParams.keyworks },url) }*/ //"107.85003662109375,18.973388671875,111.36566162109375,20.5609130859375" //bbox:"BBOX(109.6875,111.12671,20.17639,19.44031)", //BBOX:"BBOX(minx,maxx,maxy,miny) var _this = this; window.doXHR(url, function (data) { _this.realtimeMessageCallback(data, _this); }); } }, //发送消息 sendWebsocketMsg: function () { // console.log(this.realtimeWebsocket,",",this.realtimeWebsocket.ready); this.realtimeWebsocket.send(this.realtimeParam); }, getParam: function () { var options = this.options var param = {}; param.sessionToken = options.sessionToken; let bounds = window.map.getBounds(); if (options.point) { let circle = L.circle(options.point.split(','), { radius: options.radius }).addTo(window.map); //处理圆圈获取边界报错问题 //circle._project(); bounds = circle.getBounds(); window.map.removeLayer(circle); // param.cicle = options.point+","+options.radius; } else if (options.polygon) { // param.polygon = options.polygon; let polygonStr = options.polygon.replaceAll('[', '') .replaceAll('{', '') .replaceAll('}', '') .replaceAll(']', '') .replaceAll('lat:', '') .replaceAll('lon:', ''); let latlonStr = polygonStr.split(','); let latlons = []; for (let i = 0; i < latlonStr.length; i += 2) { latlons.push([parseFloat(latlonStr[i]), parseFloat(latlonStr[i + 1])]); } bounds = L.polygon(latlons).getBounds(); // param.bbox= {minlon:minx,minlat:miny,maxlon:maxx,maxlat:maxy}; // return param; } else if (options.bbox) { //"BBOX(110.02455711364746,110.0778579711914,20.0075626373291,19.979496002197266)" let latlonStr = options.bbox.replaceAll('BBOX(', '').replaceAll(')', '').split(','); bounds = L.latLngBounds([parseFloat(latlonStr[2]), parseFloat(latlonStr[0])], [parseFloat(latlonStr[3]), parseFloat(latlonStr[1])]); // param.bbox = options.bbox; } var minx = bounds.getSouthWest().lng , maxx = bounds.getNorthEast().lng , miny = bounds.getSouthWest().lat , maxy = bounds.getNorthEast().lat; param.bbox = { minlon: minx, minlat: miny, maxlon: maxx, maxlat: maxy }; if (options.time) { param.time = options.time; } else { param.time = 10; } param.layername = options.realtimeLayer; return param }, realtimeMessageCallback: function (data, _this) { if (data && data.resultList && data.resultList.length && data.resultList.length > 0) { var icon; let id; _this.currentRealTimeListObj = {} let showTitle = true; if (window.map.getZoom() < _this.options.showLabellevel) { showTitle = false; } let m; for (var i in data.resultList) { if(data.resultList[i].layerAliseName === 'cz_czlltc_wgy'){ let wgyInfo = {} let id = data.resultList[i].attributes._targetID if(_this.wgyInfoMap.get(id)){ wgyInfo = _this.wgyInfoMap.get(id) }else{ wgyInfo = window.getWgyInfoById(id) _this.wgyInfoMap.set(id,wgyInfo) } // let wgyInfo = window.getWgyInfoById(data.resultList[i].attributes._targetID) data.resultList[i].name = wgyInfo.displayName ? wgyInfo.displayName : "-" data.resultList[i].attributes.ouDirectory = wgyInfo.ouDirectory ? wgyInfo.ouDirectory : "-" data.resultList[i].attributes.email = wgyInfo.email ? wgyInfo.email : "-" data.resultList[i].attributes.ename = wgyInfo.ename ? wgyInfo.ename : "-" data.resultList[i].attributes.phoneNumber = wgyInfo.phoneNumber ? wgyInfo.phoneNumber : "-" } //icon = L.icon({iconUrl: data.resultList[i].markerPath, iconSize: [32, 32],iconAnchor: [16, 8]}); if (_this.options.realtimeLayer != data.resultList[i].layername && _this.options.realtimeLayer != data.resultList[i].layerAliseName) { console.log(_this.options.realtimeLayer, '....', data.resultList[i].layername); continue; } id = data.resultList[i].attributes._targetID; _this.currentRealTimeListObj[id] = data.resultList[i] if (_this.markerGroup[id]) { //console.log(data.resultList[i].id); _this.markerGroup[id].attributes = data.resultList[i]; _this.markerGroup[id].attributes.realtimeLayer = _this.options.realtimeLayer; _this.markerGroup[id].attributes.gjLayer = _this.options.gjLayer; _this.markerGroup[id].attributes.layername = _this.options.realtimeLayer; _this.markerGroup[id].off(); if (!_this.markerGroup[id].getLatLng().equals(L.latLng([data.resultList[i].lat, data.resultList[i].lon]))) { _this.markerGroup[id].updatePosAndIcon(L.latLng([data.resultList[i].lat, data.resultList[i].lon]), data.resultList[i]); } _this.markerGroup[id].unbindPopup().bindPopup(_this.options.markerPopup(_this.markerGroup[id].attributes), { autoPan: false, closeButton: false, offset: L.point(_this.options.pointX, _this.options.pointY) }); _this.markerGroup[id].on('click', function () { _this.markerClick && _this.markerClick({ func: _this.goOpenGJByUrl.bind(_this), markerInfo: this.attributes }) }).on('mouseover', function (ev) { if (_this.pupopOpenHander) { clearTimeout(_this.pupopOpenHander); } _this.pupopOpenHander = setTimeout(function () { ev.target.openPopup(); }, 500); if (_this.markerDrawJ) { if (_this.markerDrawJ.getLayers().length > 0) { _this.markerDrawJ.getLayers()[0].off(); } _this.markerDrawJ.clearLayers(); } let jmarker = L.marker(ev.target.getLatLng(), { icon: new L.AngleIcon({ iconSize: new L.Point(32, 32) }) }).addTo(_this.markerDrawJ); jmarker.options.icon.drawJ(); jmarker.attributes = this.attributes; jmarker.off().on('click', function (ev) { _this.markerClick && _this.markerClick({ func: _this.goOpenGJByUrl.bind(_this), markerInfo: this.attributes }) }) }); // 根据ID画线画点,记录到每艘船舶下面,等关闭按钮时统一清除 //_this.realtimeGJLayer.gj[id].addLatLng([data.resultList[i].lat, data.resultList[i].lon]); //_this.realtimeGJLayer.gjCircleMarker[data.resultList[i].id] = L.circleMarker([data.resultList[i].lat, data.resultList[i].lon],{radius:1,color:data.resultList[i].pcolor}).addTo(_this.realtimeGJLayer.layerGroup); } else if (!_this.markerGroup[id]) { //var m = L.marker([data.resultList[i].lat, data.resultList[i].lon],{icon:icon,title:data.resultList[i].attributes._targetID,showTitle:true}); m = L.angleMarker([data.resultList[i].lat, data.resultList[i].lon] , { title: data.resultList[i].name , showTitle: showTitle , course: data.resultList[i].attributes.course , speed: data.resultList[i].attributes.speed , iconUrl: data.resultList[i].markerPath+"?sessionToken="+window.sessionToken , labelPosition: 'topleft' }); m.showTitle = showTitle; m.id = id; m.attributes = data.resultList[i]; m.attributes.realtimeLayer = _this.options.realtimeLayer; m.attributes.gjLayer = _this.options.gjLayer; // m.attributes.layername = _this.options.realtimeLayer; // console.log(_this.options.markerPopup.apply(_this,m.attributes)); m.bindPopup(_this.options.markerPopup(m.attributes), { autoPan: false, closeButton: false, offset: L.point(_this.options.pointX, _this.options.pointY) }); //autoPanPaddingBottomRight ,,{autoPan:false,closeButton:false,offset:L.point(120,185)} // var url = _this._jsonUrl+"?format=json&layer="+_this.options.gjLayer+"&customsQuery="+encodeURIComponent("{\"must\":[{\"term\":{\"attributes._targetID\":\""+attr.attributes._targetID+"\"}},{\"range\":{\"attributes.collectime\":{\"lte\":"+endTime+",\"gt\":"+startTime+"}}}]}")+"&sort=collectime:asc"; m.on('click', function () { _this.markerClick && _this.markerClick({ func: _this.goOpenGJByUrl.bind(_this), markerInfo: this.attributes }) }) _this.markerGroup[id] = m; _this.realtimeMarkerLayerGroup.realtimeLayerGroup.addLayer(_this.markerGroup[id]); m.on('mouseover', function (ev) { if (_this.pupopOpenHander) { clearTimeout(_this.pupopOpenHander); } _this.pupopOpenHander = setTimeout(function () { ev.target.openPopup(); }, 500); if (_this.markerDrawJ) { if (_this.markerDrawJ.getLayers().length > 0) { _this.markerDrawJ.getLayers()[0].off(); } _this.markerDrawJ.clearLayers(); } let jmarker = L.marker(ev.target.getLatLng(), { icon: new L.AngleIcon({ iconSize: new L.Point(32, 32) }) }).addTo(_this.markerDrawJ); jmarker.options.icon.drawJ(); jmarker.attributes = this.attributes; jmarker.on('click', function (ev) { _this.markerClick && _this.markerClick({ func: _this.goOpenGJByUrl.bind(_this), markerInfo: this.attributes }) }) }); //_this.realtimeGJLayer.gj[id] = L.polyline([[data.resultList[i].lat, data.resultList[i].lon]], {color: 'red'}).addTo(_this.realtimeGJLayer.layerGroup); // _this.realtimeGJLayer.gjCircleMarker[id] = L.circleMarker([data.resultList[i].lat, data.resultList[i].lon],{radius:1,color:data.resultList[i].pcolor}).addTo(_this.realtimeGJLayer.layerGroup); } _this.setMarkerSsgjOnMap(id) //L.circleMarker([data.resultList[i].lat, data.resultList[i].lon],{radius:1,color:data.resultList[i].pcolor,title:data.resultList[i].attributes._targetID,showTitle:true}).addTo(window.map); } } }, goOpenGJByUrl: function ({ startTime, endTime, targetID }) { // console.log(startTime,endTime,targetID) var url = this._jsonUrl + "?format=json&layer=" + this.options.gjLayer + "&customsQuery=" + encodeURIComponent("{\"must\":[{\"term\":{\"attributes._targetID\":\"" + targetID + "\"}},{\"range\":{\"attributes.collecTime\":{\"lte\":" + endTime + ",\"gt\":" + startTime + "}}}]}") + "&sort=collecTime:asc"; this.goOpenGJ(url) }, goOpenGJ: function (url) { var _this = window.gjThis; window.doXHR(url, function (data) { if (data && data.resultList && data.resultList.length && data.resultList.length > 0) { var icon; if (_this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID]) { for (let i in _this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID]) { _this.gjLayer.layerGroup.removeLayer(_this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID][i]); } _this.gjLayer.layerGroup.removeLayer(_this.gjLayer.seMarker['s']); _this.gjLayer.layerGroup.removeLayer(_this.gjLayer.seMarker['e']); for (var i in _this.gjLayer.gjCircleMarker[data.resultList[0].attributes._targetID]) { _this.gjLayer.layerGroup.removeLayer(_this.gjLayer.gjCircleMarker[data.resultList[0].attributes._targetID][i]); } _this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID] = {}; _this.gjLayer.gjCircleMarker[data.resultList[0].attributes._targetID] = []; _this.gjLayer.seMarker = {}; } var lanlats = [], courses = [], speeds = [], collectimes = []; for (var i in data.resultList) { collectimes.push(data.resultList[i].time); courses.push(data.resultList[i].attributes.course); speeds.push(data.resultList[i].attributes.speeds); lanlats.push([data.resultList[i].lat, data.resultList[i].lon]); if (!_this.gjLayer.gjCircleMarker[data.resultList[i].attributes._targetID]) { _this.gjLayer.gjCircleMarker[data.resultList[i].attributes._targetID] = []; } //_this.gjLayer.gjCircleMarker[data.resultList[i].attributes._targetID].push(L.circleMarker([data.resultList[i].lat, data.resultList[i].lon],{radius:2,color:data.resultList[i].pcolor}).addTo(_this.gjLayer.layerGroup)); } _this.saveGjPlayCtx(); _this.realtimeUpdate(); _this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID] = L.polyline(lanlats, { color: 'red' }).addTo(_this.gjLayer.layerGroup); var sicon = L.icon({ iconUrl: window.EASYMAP_CONFIG.myUrl + 'map-easy-client/track_start.png', iconSize: [25, 39], iconAnchor: [12, 39] }); var eicon = L.icon({ iconUrl: window.EASYMAP_CONFIG.myUrl + 'map-easy-client/track_end.png', iconSize: [25, 39], iconAnchor: [12, 39] }); var stitle = formatDate(data.resultList[0].time * 1000); _this.gjLayer.seMarker['s'] = L.marker([data.resultList[0].lat, data.resultList[0].lon], { icon: sicon, title: stitle }).addTo(_this.gjLayer.layerGroup); //console.log(data.resultList[data.resultList.length-1].attributes.collectime); var eTitle = formatDate(data.resultList[data.resultList.length - 1].attributes.time * 1000); _this.gjLayer.seMarker['e'] = L.marker([data.resultList[data.resultList.length - 1].lat, data.resultList[data.resultList.length - 1].lon], { icon: eicon, title: eTitle }).addTo(_this.gjLayer.layerGroup); window.map.fitBounds(_this.gjLayer.gjPoyline[data.resultList[0].attributes._targetID].getBounds()); var marker1 = L.Marker.movingMarker(lanlats, 10000, { autostart: true , course: data.resultList[data.resultList.length - 1].attributes.course , speed: data.resultList[data.resultList.length - 1].attributes.speed , courses: courses , speeds: speeds , collectimes: collectimes , iconUrl: data.resultList[0].markerPath+"?sessionToken="+ window.sessionToken , title: data.resultList[0].name , showTitle: true , markerPopup: this.options.markerPopup }).addTo(window.map); marker1.on('click', function () { if (marker1.isRunning()) { marker1.pause(); } else if (marker1.isEnded()) { _this.resumeGjPlayCtx(data.resultList[0].attributes._targetID); window.map.removeLayer(marker1); marker1.off('click'); } else { marker1.start(); } }); /* var i = 2 while( i < data.resultList.length-1 ){ if(marker1.isEnded()){ marker1.addLatLng([data.resultList[i].lat, data.resultList[i].lon],10000); marker1.setIcon(new L.AngleIcon({ course:data.resultList[i].attributes.course ,speed:data.resultList[i].attributes.speed ,iconUrl: data.resultList[i].markerPath })); i++; } } */ } else { _this.bindPopup('没有轨迹数据!', { closeOnClick: true }); _this.openPopup(window.map.getCenter()); console.log('没有轨迹数据!'); } }); }, saveGjPlayCtx: function () { this.gjPaly.isPlay = true; this.gjPaly.mapCenter = window.map.getCenter(); this.gjPaly.zoom = window.map.getZoom(); }, resumeGjPlayCtx: function (_targetID) { this.gjPaly.isPlay = false; window.map.setView(this.gjPaly.mapCenter, this.gjPaly.zoom); this.gjPaly.mapCenter = null; this.gjPaly.zoom = null; this.gjLayer.layerGroup.clearLayers(); delete this.gjLayer.gjPoyline[_targetID]; this.realtimeUpdate(); }, getTileUrl: function (coords) { // (Point, Number) -> String var url = L.Util.template(this._url, { s: this._getSubdomain(coords) }); //argis版本的要-1 // url += this.getParamString(this.wmtsParams, url) + "&tilematrix=" + (coords.z) + "&tilerow=" + coords.y + "&tilecol=" + coords.x; url += this.getParamString(this.wmtsParams, url) + "&tilematrix=" + (coords.z) + "&tilerow=" + coords.y + "&tilecol=" + coords.x + "&sessionToken=" + window.sessionToken; if (this.wmtsParams.hnjhpt_rid) { var date = new Date(); var time = date.getTime(); var message = this.wmtsParams.hnjhpt_sid + this.wmtsParams.hnjhpt_rid + time; var hash = CryptoJS.HmacSHA256(message, this.wmtsParams.secret); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); url += "&hnjhpt_sign=" + encodeURIComponent(hashInBase64) + "&hnjhpt_rtime=" + time } return url; }, getJsonTileUrl: function (coords) { // (Point, Number) -> String var url = L.Util.template(this._jsonUrl, { s: this._getSubdomain(coords) }); var param = L.extend({}, this.wmtsParams); param.format = "realtime"; url += this.getParamString(param, url) + "&tilematrix=" + (coords.z) + "&tilerow=" + coords.y + "&tilecol=" + coords.x; if (this.wmtsParams.hnjhpt_rid) { var date = new Date(); var time = date.getTime(); var message = this.wmtsParams.hnjhpt_sid + this.wmtsParams.hnjhpt_rid + time; var hash = CryptoJS.HmacSHA256(message, this.wmtsParams.secret); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); url += "&hnjhpt_sign=" + encodeURIComponent(hashInBase64) + "&hnjhpt_rtime=" + time } return url; }, getJsonMarker: function (coords, callback) { var _this = this; window.doXHR(this.getJsonTileUrl(coords), function (data) { if (data && data.resultList && data.resultList.length && data.resultList.length > 0) { if (callback) { callback(data.resultList); } } }); }, }); L.tileLayer.wmts.realtime = function (url, jsonUrl, options, markerClick) { return new L.TileLayer.WMTS.REALTIME(url, jsonUrl, options, markerClick); }; L.REALTIMEGJ = L.Layer.extend({ options: { targetIDField: 'attributes._targetID', timeField: 'attributes.collecTime', sort: 'collecTime:asc', playSpeed: 10000, markerPopup: window.getMarkerPopup, routeLine: '' }, url: '', layername: '', startTime: null, endTime: null, targetList: [], realtimeIcon: {}, markerGroup: {}, realtimeGJLayer: {}, markerDrawJ: null, pupopOpenHander: null, gjLayer: {}, gjPaly: {}, gjData: {}, eventMap: {}, pupopOpenHander: null, markerDrawJ: null, initialize: function (url, options) { this.url = url; this.gjLayer.layerGroup = L.layerGroup().addTo(window.map); this.gjLayer.gjCircleMarker = {}; this.gjLayer.gjTimeMarker = {}; this.gjLayer.gjPoyline = {}; this.gjLayer.seMarker = {}; this.gjLayer.movingMarker = {}; L.setOptions(this, options); }, getGJUrl: function () { //{\"terms\":{\""+this.options.targetIDField+"\":["+ids.join(',')+"]}}, console.log(this.url + "?format=json&layer=" + this.layername + "&customsQuery=" + encodeURIComponent("{\"must\":[{\"terms\":{\"" + this.options.targetIDField + "\":[" + this.targetList.join(',') + "]}},{\"range\":{\"" + this.options.timeField + "\":{\"lte\":" + this.endTime + ",\"gt\":" + this.startTime + "}}}]}") + "&sort=" + this.options.sort) //,{\"range\":{\""+this.options.timeField+"\":{\"lte\":"+this.endTime+",\"gte\":"+this.startTime+"}}} // return this.url + "?format=json&layer=" + this.layername // + "&customsQuery=" + encodeURIComponent("{\"must\":[{\"terms\":{\"" + (this.layername.indexOf("zt_clzt") !== -1 ? this.options.CarTargetIDField : this.options.targetIDField) + "\":[" + "\"" + this.targetList.join(',') + "\"" + "]}},{\"range\":{\"" + this.options.timeField + "\":{\"lte\":" + this.endTime + ",\"gt\":" + this.startTime + "}}}]}") + "&sort=" + this.options.sort; return this.url + "?format=json&layer=" + this.layername + "&customsQuery=" + encodeURIComponent("{\"must\":[{\"terms\":{\"" + this.options.targetIDField + "\":[" + this.targetList.join(',') + "]}},{\"range\":{\"" + this.options.timeField + "\":{\"lte\":" + this.endTime + ",\"gt\":" + this.startTime + "}}}]}") + "&sort=" + this.options.sort; }, clearGjLayerLayerGroup: function (_targetID) { if (this.gjLayer.gjPoyline[_targetID]) { for (let i in this.gjLayer.gjPoyline[_targetID]) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.gjPoyline[_targetID][i]); } this.gjLayer.layerGroup.removeLayer(this.gjLayer.gjPoyline[_targetID]); } if (this.gjLayer.seMarker[_targetID] && this.gjLayer.seMarker[_targetID]['s']) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.seMarker[_targetID]['s']); } if (this.gjLayer.seMarker[_targetID] && this.gjLayer.seMarker[_targetID]['e']) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.seMarker[_targetID]['e']); } for (var i in this.gjLayer.gjCircleMarker[_targetID]) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.gjCircleMarker[_targetID][i]); } for (var i in this.gjLayer.gjTimeMarker[_targetID]) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.gjTimeMarker[_targetID][i]); } let movingMarker = this.gjLayer.movingMarker[_targetID] if (movingMarker) { movingMarker.del() this.gjLayer.layerGroup.removeLayer(movingMarker); } // this.gjLayer.layerGroup.clearLayers(); delete this.gjLayer.movingMarker[_targetID] this.gjLayer.gjPoyline[_targetID] = []; this.gjLayer.gjCircleMarker[_targetID] = []; this.gjLayer.gjTimeMarker[_targetID] = []; this.gjLayer.seMarker[_targetID] = {}; }, stopGuiji: function (targetList) { targetList.forEach((e) => { this.clearGjLayerLayerGroup(e); }) }, pauseGuiji: function (targetList) { targetList.forEach((e) => { this.gjLayer.movingMarker[e].pause() }) }, jixuHuifang: function (targetList) { targetList.forEach((e) => { this.gjLayer.movingMarker[e].start() }) }, followMarker(targetId) { Object.keys(this.gjLayer.movingMarker).forEach((id) => { let marker = this.gjLayer.movingMarker[id] console.log(id, targetId) if (id === targetId) { if (marker.isFollow) { marker.stopFollow() } else { marker.follow() } } else { marker.stopFollow() } }) // let marker = this.gjLayer.movingMarker[targetId] // marker.follow() }, showGJTime: function (show) { for (let i in this.gjLayer.gjTimeMarker) { for (let j in this.gjLayer.gjTimeMarker[i]) { if (!this.gjLayer.layerGroup.hasLayer(this.gjLayer.gjTimeMarker[i][j])) { if (show) { this.gjLayer.gjTimeMarker[i][j].addTo(this.gjLayer.layerGroup) } } else { if (!show) { this.gjLayer.layerGroup.removeLayer(this.gjLayer.gjTimeMarker[i][j]); } } } } }, startPlayGJ: function (_targetID, gjData) { this.clearGjLayerLayerGroup(_targetID); var lanlats = [], courses = [], speeds = [], collectimes = []; if (!this.gjLayer.gjCircleMarker[_targetID]) { this.gjLayer.gjCircleMarker[_targetID] = []; } if (!this.gjLayer.seMarker[_targetID]) { this.gjLayer.seMarker[_targetID] = {}; } let iconAnchor, noRealtimeGjList = {}; this.gjLayer.gjPoyline[_targetID] = {}; for (var i in gjData) { collectimes.push(gjData[i].attributes.collecTime); courses.push(gjData[i].attributes.course); speeds.push(gjData[i].attributes.speed); lanlats.push([gjData[i].lat, gjData[i].lon]); // this.gjLayer.gjCircleMarker[_targetID].push(L.circleMarker([gjData[i].lat, gjData[i].lon],{radius:4,color:'#f00'}).addTo(this.gjLayer.layerGroup)); // this.gjLayer.gjPoyline[_targetID] = L.polyline(lanlats, {color: 'red',dashArray:'10',dashOffset:'2'}).addTo(this.gjLayer.layerGroup); //处理过虚拟位置不打点 if (gjData[i].attributes.no_realtime_gj && gjData[i].attributes.no_realtime_gj === 'no_realtime_gj') { noRealtimeGjList[i] = i; if (i !== 0 && !(gjData[i].lat + "_" + gjData[i].lon in (this.gjLayer.gjPoyline[_targetID]))) { this.gjLayer.gjPoyline[_targetID][gjData[i].lat + "_" + gjData[i].lon] = L.polyline([[gjData[i - 1].lat, gjData[i - 1].lon] , [gjData[i].lat, gjData[i].lon]], { color: 'red', dashArray: '10' }).addTo(this.gjLayer.layerGroup); } continue; } if (i !== "0" && !(gjData[i].lat + "_" + gjData[i].lon in (this.gjLayer.gjPoyline[_targetID]))) { this.gjLayer.gjPoyline[_targetID][gjData[i].lat + "_" + gjData[i].lon] = L.polyline([[gjData[i - 1].lat, gjData[i - 1].lon] , [gjData[i].lat, gjData[i].lon]], { color: 'red' }).addTo(this.gjLayer.layerGroup); } let m = L.circleMarker([gjData[i].lat, gjData[i].lon], { zIndexOffset: 10, radius: 2, color: '#f00' }).addTo(this.gjLayer.layerGroup); this.gjLayer.gjCircleMarker[_targetID].push(m); m.attributes = gjData[i]; m.bindPopup(this.options.markerPopup(m.attributes), { autoPan: false, closeButton: false, offset: L.point(130, 315) }); //autoPanPaddingBottomRight ,,{autoPan:false,closeButton:false,offset:L.point(120,185)} // var url = _this._jsonUrl+"?format=json&layer="+_this.options.gjLayer+"&customsQuery="+encodeURIComponent("{\"must\":[{\"term\":{\"attributes._targetID\":\""+attr.attributes._targetID+"\"}},{\"range\":{\"attributes.collectime\":{\"lte\":"+endTime+",\"gt\":"+startTime+"}}}]}")+"&sort=collectime:asc"; let _this = this; m.on('mouseover', function (ev) { if (_this.pupopOpenHander) { clearTimeout(_this.pupopOpenHander); } _this.pupopOpenHander = setTimeout(function () { ev.target.openPopup(); }, 500); if (_this.markerDrawJ) { _this.gjLayer.layerGroup.removeLayer(_this.markerDrawJ) } _this.markerDrawJ = L.marker(ev.target.getLatLng(), { zIndexOffset: 12, icon: new L.AngleIcon({ iconSize: new L.Point(32, 32) }) }).addTo(_this.gjLayer.layerGroup); _this.markerDrawJ.options.icon.drawJ(); }); iconAnchor = [-70, 10]; let pos = 'right'; if (i % 2 == 0) { iconAnchor = [120, 10] pos = 'left'; } var title = '-' var len = gjData[i].time.length; if(len === 13){ title = formatDate(gjData[i].time * 1); }else if(len === 10){ title = formatDate(gjData[i].time * 1000); } // this.gjLayer.gjTimeMarker[_targetID].push(L.marker([gjData[i].lat, gjData[i].lon],{zIndexOffset:-10,icon:L.divIcon({iconSize: [120, 18] ,iconAnchor:iconAnchor,html:''+formatDate(gjData[i].attributes.collecTime*1000)+''})}).addTo(this.gjLayer.layerGroup)); this.gjLayer.gjTimeMarker[_targetID][i] = L.marker([gjData[i].lat, gjData[i].lon], { zIndexOffset: -10, icon: L.iconWithLine({ pos: pos, iconSize: [120, 18], iconAnchor: iconAnchor, html: '' + i+':'+title + '' }) }); //).addTo(this.gjLayer.layerGroup)); } var sicon = L.icon({ iconUrl: window.EASYMAP_CONFIG.myUrl + 'map-easy-client/track_start.png', iconSize: [25, 39], iconAnchor: [12, 39] }); var eicon = L.icon({ iconUrl: window.EASYMAP_CONFIG.myUrl + 'map-easy-client/track_end.png', iconSize: [25, 39], iconAnchor: [12, 39] }); var stitle = formatDate(gjData[0].time * 1000); this.gjLayer.seMarker[_targetID]['s'] = L.marker([gjData[0].lat, gjData[0].lon], { icon: sicon, title: stitle }).addTo(this.gjLayer.layerGroup); //console.log(data.resultList[data.resultList.length-1].attributes.collectime); var eTitle = formatDate(gjData[gjData.length - 1].time * 1000); this.gjLayer.seMarker[_targetID]['e'] = L.marker([gjData[gjData.length - 1].lat, gjData[gjData.length - 1].lon], { icon: eicon, title: eTitle }).addTo(this.gjLayer.layerGroup); var marker1 = L.Marker.movingMarker(lanlats, this.options.playSpeed, { autostart: true , course: gjData[gjData.length - 1].attributes.course , speed: gjData[gjData.length - 1].attributes.speed , courses: courses , speeds: speeds , collectimes: collectimes , iconUrl: gjData[0].markerPath+"?sessionToken="+ window.sessionToken , zIndexOffset: 100 , title: gjData[gjData.length - 1].name , showTitle: true , labelPosition: 'topleft' , noRealtimeGjList: noRealtimeGjList , gjTimeMarker: this.gjLayer.gjTimeMarker[_targetID] , layerGroup: this.gjLayer.layerGroup , markerDrawJ: this.markerDrawJ , gjData: gjData , pupopOpenHander: this.pupopOpenHander , markerPopup: this.options.markerPopup }).addTo(this.gjLayer.layerGroup); /* marker1.on('click', function() { if (marker1.isRunning()) { marker1.pause(); } else if(marker1.isEnded()){ //_this.resumeGjPlayCtx(gjData[0].attributes._targetID); //window.map.removeLayer(marker1); //marker1.off('click'); } else{ marker1.start(); } });*/ this.gjLayer.movingMarker[_targetID] = marker1; this.gjLayer.shipOne = marker1 }, _playGJ: function () { for (var target in this.gjData) { let _this = this; setTimeout(function (data) { _this.startPlayGJ(data.target, data.data) }, 100, { target: target, data: this.gjData[target] }) } }, playGJ: function (layername, targetList, startTime, endTime, noDataPalyCallBack) { if (layername) { this.layername = layername } if (targetList && targetList.length > 0) { this.targetList = targetList } if (startTime) { this.startTime = startTime } if (endTime) { this.endTime = endTime } var _this = this; window.doXHR(this.getGJUrl(), function (data) { //console.log(data) if (data && data.resultList && data.resultList.length && data.resultList.length > 0) { let obj = {} data.resultList.forEach((e) => { let id = e.attributes._targetID if (id in obj) { obj[id].push(e) } else { obj[id] = [e] } }) _this.gjData = obj // for( var i in data.resultList ){ // if( data.resultList[i].attributes._targetID in _this.gjData ){ // _this.gjData[data.resultList[i].attributes._targetID].push(data.resultList[i]); // }else{ // _this.gjData[data.resultList[i].attributes._targetID] = []; // _this.gjData[data.resultList[i].attributes._targetID].push(data.resultList[i]); // } // } _this._playGJ(); } else { if (noDataPalyCallBack) { noDataPalyCallBack(); } //window.$message.error('没有轨迹数据!') // L.marker(window.map.getCenter()).addTo(_this.gjLayer.layerGroup).bindTooltip('没有轨迹数据!').openTooltip(window.map.getCenter()); console.log('没有轨迹数据!'); } }); } }); L.realtimeGj = function (url, layername, targetList, startTime, endTime, options) { return new L.REALTIMEGJ(url, layername, targetList, startTime, endTime, options); }; /* Angle ICON */ L.AngleIcon = L.Icon.extend({ // default value options: { angle: 0, iconSize: new L.Point(62, 62), // canvas size className: "leaflet-boat-icon", course: 0, // angle labelAnchor: [0, 26], // test loaction pointType: 0, // pointType showTitle: false, label: 'wwwwwwwwwww', labelPosition: 'topleft',//topleft , topright , bottomleft,bottomright textColor: 'red', img: null, }, createIcon: function () { var div = document.createElement("div"); var e = document.createElement("canvas"); div.appendChild(e); var nameDiv = document.createElement("div"); div.appendChild(nameDiv); this._setIconStyles(div, "icon"); var s = this.options.iconSize; e.width = s.x; e.height = s.y; this.ctx = e.getContext("2d"); if (this.options.iconUrl) { this.draw(s.x, s.y); } if (this.options.showTitle && this.options.label != '') { let style = "opacity: 0.8;position: relative;background-color: #fff;padding-left: 3px;padding-right: 3px;border-radius: 2px;white-space: nowrap;z-index:-3000;"; if (this.options.labelPosition === 'bottomleft') { nameDiv.style = "bottom:15px;left: 52px;float: left;" + style; // nameDiv.innerHTML = ""+this.options.label+""; } else if (this.options.labelPosition === 'bottomright') { nameDiv.style = "bottom:15px;right: 62px;float: right;" + style; // nameDiv.innerHTML = ""+this.options.label+""; } else if (this.options.labelPosition === 'topleft') { nameDiv.style = "top:-70px;left: 62px;float: left;" + style; // nameDiv.innerHTML = ""+this.options.label+""; } else if (this.options.labelPosition === 'topright') { nameDiv.style = "top:-70px;right: 62px;float: right;" + style; } nameDiv.innerHTML = "" + this.options.label + ""; this.drawLabelLine(); } return div; }, drawLabelLine: function () { //画线,指向label this.ctx.beginPath(); let moveTo = [32, 32], lineTo = [52, 52] if (this.options.labelPosition === 'bottomleft') { moveTo = [32, 32], lineTo = [52, 52] } else if (this.options.labelPosition === 'bottomright') { moveTo = [32, 32], lineTo = [0, 52] } else if (this.options.labelPosition === 'topleft') { moveTo = [32, 32], lineTo = [62, 12] } else if (this.options.labelPosition === 'topright') { moveTo = [32, 32], lineTo = [0, 12] } this.ctx.moveTo(moveTo[0], moveTo[1]); this.ctx.lineTo(lineTo[0], lineTo[1]); this.ctx.strokeStyle = '#83988acc'; this.ctx.lineWidth = "1"; this.ctx.stroke(); this.ctx.closePath(); }, draw: function (w, h) { if (!this.ctx) return; var course = this.options.course; var img = this._createImg(this.options.iconUrl, img); var _this = this; img.onload = function () { //平移坐标原点 _this.ctx.translate(w / 2, h / 2); //旋转画布 //var course = _this.options.course - 90; /*if(course < 0 ){ course *= -1; } */ var rotate = ((Math.PI * 2) / 360) * course; /*if(_this.options.course > 180){ course = -360 + _this.options.course }*/ //console.log(rotate); _this.ctx.rotate(rotate); _this.ctx.translate(-w / 2, -h / 2); //画图 //_this.ctx.drawImage(img,0,0,32,32); 42/2=21 , _this.ctx.drawImage(img, 18, 18, 26, 26); _this.ctx.beginPath(); _this.ctx.moveTo(31, 18); _this.ctx.lineTo(31, 18.0 - (26.0 * _this.options.speed / 10.0)); //console.log(Math.abs(_this.options.angle)); if ((_this.options.speed <= 1 && _this.options.course > 0) || Math.abs(_this.options.angle) > 1) { _this.ctx.lineTo(38, 18.0 - (26.0 * _this.options.speed / 10.0)); } _this.ctx.strokeStyle = '#000';//'#83988acc'; _this.ctx.lineJoin = "round"; _this.ctx.lineWidth = "1"; _this.ctx.stroke(); _this.ctx.closePath(); //console.log(img.src) } }, drawJ() { var ctx = this.ctx; var lefttop = [4, 10], leftbuttom = [4, 24], righttop = [28, 10], rightbuttom = [28, 24]; var offset = 6; //左上角 ctx.beginPath(); ctx.moveTo(lefttop[0], lefttop[1]); ctx.lineTo(lefttop[0], lefttop[1] - offset); ctx.lineTo(lefttop[0] + offset, lefttop[1] - offset); ctx.strokeStyle = 'red'; ctx.lineJoin = "round"; ctx.lineWidth = "3"; ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(lefttop[0], lefttop[1]); ctx.lineTo(lefttop[0], lefttop[1] - offset); ctx.lineTo(lefttop[0] + offset, lefttop[1] - offset); ctx.strokeStyle = '#000'; ctx.lineJoin = "round"; ctx.lineWidth = "1"; ctx.stroke(); ctx.closePath(); //左下角 //drawJ(ctx,2,42,2,14,8,14); 46 leftbuttom=[2,40] ctx.beginPath(); ctx.moveTo(leftbuttom[0], leftbuttom[1]); ctx.lineTo(leftbuttom[0], leftbuttom[1] + offset); ctx.lineTo(leftbuttom[0] + offset, leftbuttom[1] + offset); ctx.strokeStyle = 'red'; ctx.lineJoin = "round"; ctx.lineWidth = "3"; ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(leftbuttom[0], leftbuttom[1]); ctx.lineTo(leftbuttom[0], leftbuttom[1] + offset); ctx.lineTo(leftbuttom[0] + offset, leftbuttom[1] + offset); ctx.strokeStyle = '#000'; ctx.lineJoin = "round"; ctx.lineWidth = "1"; ctx.stroke(); ctx.closePath(); //右上角 //drawJ(ctx,2,42,2,14,8,14); 30,24 righttop = [30,20],rightbuttom=[30,40]; ctx.beginPath(); ctx.moveTo(righttop[0], righttop[1]); ctx.lineTo(righttop[0], righttop[1] - offset); ctx.lineTo(righttop[0] - offset, righttop[1] - offset); ctx.strokeStyle = 'red'; ctx.lineJoin = "round"; ctx.lineWidth = "3"; ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(righttop[0], righttop[1]); ctx.lineTo(righttop[0], righttop[1] - offset); ctx.lineTo(righttop[0] - offset, righttop[1] - offset); ctx.strokeStyle = '#000'; ctx.lineJoin = "round"; ctx.lineWidth = "1"; ctx.stroke(); ctx.closePath(); //右下角 //drawJ(ctx,2,42,2,14,8,14); 30,24 rightbuttom=[30,40]; ctx.beginPath(); ctx.moveTo(rightbuttom[0], rightbuttom[1]); ctx.lineTo(rightbuttom[0], rightbuttom[1] + offset); ctx.lineTo(rightbuttom[0] - offset, rightbuttom[1] + offset); ctx.strokeStyle = 'red'; ctx.lineJoin = "round"; ctx.lineWidth = "3"; ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(rightbuttom[0], rightbuttom[1]); ctx.lineTo(rightbuttom[0], rightbuttom[1] + offset); ctx.lineTo(rightbuttom[0] - offset, rightbuttom[1] + offset); ctx.strokeStyle = '#000'; ctx.lineJoin = "round"; ctx.lineWidth = "1"; ctx.stroke(); ctx.closePath(); }, /** * 获得两点之间方向角 (Get the direction angle between two points) * 根据地球上两点之间的经纬度计算两点之间与正北方向的夹角 * (According to the latitude and longitude between two points on earth, * calculate the angle between two points and the direction of the north) * * @param 点A(L.Latlng) PointA * @param 点B(L.Latlng) PointB * @return result: AB角度 (the angle of AB (calculated result degree)) * * @version 2016-08-19 * * @see Math.atan2()用于返回从x轴到指定坐标点(x, y)的角度(以弧度为单位);y/x = tan# * Math.atan2 () returns the angle (in radians) from the x-axis to the specified coordinate point (x, y); y / x = tan # * @version 2016-08-19 */ getAngle: function (A, B) { var angle = null; var latA = A.lat; var lonA = A.lng; var latB = B.lat; var lonB = B.lng; // 注意经度或者纬度相等 (when longitude or latitude is equal) if (lonA == lonB && latA > latB) { angle = Math.PI; } else if (lonA == lonB && latA < latB) { angle = 0; } else if (lonA > lonB && latA == latB) { angle = -(Math.PI / 2); } else if (lonA < lonB && latA == latB) { angle = Math.PI / 2; } // 注意经度或者纬度都不相等 (Longitude and latitude are not equal) else { var x1 = latA * Math.pow(10, 12); var x2 = latB * Math.pow(10, 12); var y1 = lonA * Math.pow(10, 12); var y2 = lonB * Math.pow(10, 12); angle = Math.atan2(y2 - y1, x2 - x1) } this.options.angle = angle; return angle; }, }); // AngleMarker继承Marker并添加setHeading 和 getAngle 方法 // AngleMarker extends from Marker and adds the setHeading and getAngle methods L.AngleMarker = L.Marker.extend({ initialize: function (latlngs, options) { options.icon = new L.AngleIcon({ showTitle: options.showTitle, label: options.title, labelPosition: options.labelPosition, textColor: options.labelColor, img: options.img, course: options.course, speed: options.speed, angle: options.angle, iconUrl: options.iconUrl }) L.Marker.prototype.initialize.call(this, latlngs, options); }, getAngle: function (A, B) { return this.options.icon.getAngle(A, B); }, setHeading: function (heading) { this.options.icon.setHeading(heading); }, updatePosAndIcon: function (newLanlng, attributes, icon) { if (this._icon) { L.DomUtil.remove(this._icon); } //layerGroup.removeLayer(this); var angle = ''; if (newLanlng) { angle = this.options.angle = this.getAngle(this.getLatLng(), newLanlng); //console.log(this.options.angle); this.setLatLng(newLanlng); } if (!icon) { this.setIcon(new L.AngleIcon({ course: attributes.attributes.course, speed: attributes.attributes.speed, iconUrl: this.options.iconUrl, angle: angle, label: attributes.name, showTitle: this.showTitle, labelPosition: this.options.labelPosition })); } else { this.setIcon(icon); } //layerGroup.addLayer(this); } }); L.angleMarker = function (pos, options) { return new L.AngleMarker(pos, options); }; L.iconWithLine = function (options) { return new L.IconWithLine(options); }; L.IconWithLine = L.Icon.extend({ options: { html: '', pos: 'left' }, createIcon: function () { var div = document.createElement("div"); var e = document.createElement("canvas"); var timeDiv = document.createElement("div"); div.appendChild(e); div.appendChild(timeDiv); let estyle = "left:-7px;top:9px;float:right;position: relative;"; let timeDivstyle = "float:left;left: -29px;opacity: 0.8;position: relative;background-color: #fff;padding-left: 3px;padding-right: 3px;border-radius: 2px;white-space: nowrap;z-index:-3000;"; e.width = 25; e.height = 4; if (this.options.pos === 'right') { estyle = "left:-62px;top:9px;float:left;position: relative;"; timeDivstyle = "float:right;left: -37px;opacity: 0.8;position: relative;background-color: #fff;padding-left: 3px;padding-right: 3px;border-radius: 2px;white-space: nowrap;z-index:-3000;"; e.width = 25; e.height = 4; } else if (this.options.pos === 'top') { estyle = "left:-71px;top:17px;float:left;position: relative;"; timeDivstyle = "float:right;top:17px;left: -75px;opacity: 0.8;position: relative;background-color: #fff;padding-left: 3px;padding-right: 3px;border-radius: 2px;white-space: nowrap;z-index:-3000;"; e.width = 4; e.height = 25; } else if (this.options.pos === 'bottom') { estyle = "left:-62px;top:9px;float:left;position: relative;"; timeDivstyle = "float:right;left: -37px;opacity: 0.8;position: relative;background-color: #fff;padding-left: 3px;padding-right: 3px;border-radius: 2px;white-space: nowrap;z-index:-3000;"; e.width = 4; e.height = 25; } timeDiv.style = timeDivstyle; e.style = estyle; timeDiv.innerHTML = this.options.html this._setIconStyles(div, "icon"); this.ctx = e.getContext("2d"); this.drawLabelLine(this.options.pos); return div; }, drawLabelLine: function (pos) { //画线,指向label this.ctx.beginPath(); if (pos === 'right' || pos === 'left') { this.ctx.moveTo(0, 2); this.ctx.lineTo(25, 2); } else { this.ctx.moveTo(2, 0); this.ctx.lineTo(2, 25); } this.ctx.strokeStyle = '#83988acc'; this.ctx.lineWidth = "0.5"; this.ctx.stroke(); this.ctx.closePath(); }, }); Date.prototype.Format = function (fmt) { //author: meizz if (!fmt) { fmt = 'yyyy-MM-dd hh:mm:ss'; } var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 //"h+": this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } window.formatDate = function (time, format) { if (!time) { return ''; } return new Date(time).Format(format); } window.doXHR = function (url, callback) { var httpXml = window.createXMLHttpRequest(); httpXml.open('get', url, true); httpXml.setRequestHeader("sessionToken",window.sessionToken) httpXml.send(null); httpXml.onreadystatechange = function () { if (httpXml.readyState == 4 && httpXml.status == 200) { var data = JSON.parse(httpXml.responseText); if (callback) { callback(data); } } }; } window.createXMLHttpRequest = function () { var xmlHttp; try { xmlHttp = new XMLHttpRequest(); } catch (e) { // 适用于IE6 try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { // 适用于IE5.5,以及IE更早版本 try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } } } return xmlHttp; } window.createWebSocket = function (handle) { //第一次连接,创建websocket连接 // messageType:"websocket", // realtimeWebsocket:null, //判断当前浏览器是否支持WebSocket if (!window.realtimeWebsocket && ('WebSocket' in window)) { //经过nginx代理转发websocket,需要对参数进行两次解码,否则无法通过nginx window.realtimeWebsocket = new WebSocket(handle.options.websocketUrl + encodeURIComponent(encodeURIComponent(JSON.stringify(handle.getParam())))); if (!window.realtimeWebsocketHandle) { window.realtimeWebsocketHandle = {}; } //连接成功建立的回调方法 window.realtimeWebsocket.onopen = function () { window.realtimeWebsocketCreated = true; window.realtimeWebsocketCreatedOnerror = false; handle.messageType = 'websocket'; console.log("WebSocket连接成功"); } //连接发生错误的回调方法 window.realtimeWebsocket.onerror = function () { window.realtimeWebsocket = null; window.realtimeWebsocketCreated = null; window.realtimeWebsocketCreatedOnerror = true; handle.messageType = 'http'; console.log("WebSocket连接发生错误"); }; //接收到消息的回调方法 window.realtimeWebsocket.onmessage = function (event) { let handle; for (let layername in window.realtimeWebsocketHandle) { handle = window.realtimeWebsocketHandle[layername]; if (handle && event && event.data) { let data = JSON.parse(event.data); if (data && data.layername === layername) { handle.realtimeMessageCallback(data, handle); } } } } //连接关闭的回调方法 window.realtimeWebsocket.onclose = function () { window.realtimeWebsocket = null; window.realtimeWebsocketHandle = null; window.realtimeWebsocketCreated = null; console.log("WebSocket连接关闭"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { window.realtimeWebsocket.close(); } } if (window.realtimeWebsocket == null) { handle.messageType = "http"; return null; } if (!window.realtimeWebsocketHandle[handle.options.realtimeLayer]) { handle.messageType = "websocket"; window.realtimeWebsocketHandle[handle.options.realtimeLayer] = handle; } return window.realtimeWebsocket; }