layui.use(function () {
|
let $ = layui.jquery,
|
layer = layui.layer,
|
laydate = layui.laydate,
|
element = layui.element,
|
laytpl = layui.laytpl;
|
|
// 左侧宽度
|
const leftWidth = $('.left-cards').width();
|
|
// 地图样式
|
const BAIDU_MAP_WHITE_STYLE = [
|
{
|
"featureType": "water",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"color": "#ccd6d7ff"
|
}
|
}, {
|
"featureType": "green",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"color": "#dee5e5ff"
|
}
|
}, {
|
"featureType": "building",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "building",
|
"elementType": "geometry.topfill",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "building",
|
"elementType": "geometry.sidefill",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "building",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#aab6b6ff"
|
}
|
}, {
|
"featureType": "subwaystation",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"color": "#888fa0ff"
|
}
|
}, {
|
"featureType": "education",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"color": "#e1e7e7ff"
|
}
|
}, {
|
"featureType": "medical",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "scenicspots",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"weight": 4
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"weight": 2
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "arterial",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "on",
|
"weight": 1
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "local",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "railway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"weight": 1
|
}
|
}, {
|
"featureType": "railway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#9494941a"
|
}
|
}, {
|
"featureType": "railway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#ffffff1a"
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"weight": 1
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#c3bed433"
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#ffffff33"
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#979c9aff"
|
}
|
}, {
|
"featureType": "subway",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "continent",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "continent",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "continent",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#333333ff"
|
}
|
}, {
|
"featureType": "continent",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "city",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "city",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "city",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#454d50ff"
|
}
|
}, {
|
"featureType": "city",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "town",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "on"
|
}
|
}, {
|
"featureType": "town",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "town",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#454d50ff"
|
}
|
}, {
|
"featureType": "town",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "road",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "road",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "poilabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "districtlabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "poilabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "districtlabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#888fa0ff"
|
}
|
}, {
|
"featureType": "transportation",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "companylabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "restaurantlabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "lifeservicelabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "carservicelabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "financelabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "otherlabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "village",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "district",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "land",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#edf3f3ff"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "provincialway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "road",
|
"elementType": "geometry.stroke",
|
"stylers": {
|
"color": "#cacfcfff"
|
}
|
}, {
|
"featureType": "subwaylabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "subwaylabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "tertiarywaysign",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "tertiarywaysign",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "provincialwaysign",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "provincialwaysign",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "nationalwaysign",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "nationalwaysign",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "highwaysign",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "highwaysign",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "provincialway",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "highway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "highway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "highway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "highway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "nationalway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "nationalway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "nationalway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "nationalway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "provincialway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "8,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "provincialway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "8,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "provincialway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "8,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"stylers": {
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "geometry",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "6"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "7"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off",
|
"curZoomRegionId": "0",
|
"curZoomRegion": "6,8",
|
"level": "8"
|
}
|
}, {
|
"featureType": "cityhighway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "water",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#8f5a33ff"
|
}
|
}, {
|
"featureType": "water",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "country",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#8f5a33ff"
|
}
|
}, {
|
"featureType": "country",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "country",
|
"elementType": "labels.text",
|
"stylers": {
|
"fontsize": 28
|
}
|
}, {
|
"featureType": "manmade",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#dfe7e7ff"
|
}
|
}, {
|
"featureType": "provincialway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "tertiaryway",
|
"elementType": "geometry.fill",
|
"stylers": {
|
"color": "#fbfffeff"
|
}
|
}, {
|
"featureType": "manmade",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "manmade",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "scenicspots",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "scenicspots",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "airportlabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "airportlabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "scenicspotslabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "scenicspotslabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "educationlabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "educationlabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "medicallabel",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "medicallabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "companylabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "restaurantlabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "hotellabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "hotellabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "shoppinglabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "shoppinglabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "lifeservicelabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "carservicelabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "transportationlabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "transportationlabel",
|
"elementType": "labels",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "financelabel",
|
"elementType": "labels.icon",
|
"stylers": {
|
"visibility": "off"
|
}
|
}, {
|
"featureType": "entertainment",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "estate",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "shopping",
|
"elementType": "geometry",
|
"stylers": {
|
"color": "#d1dbdbff"
|
}
|
}, {
|
"featureType": "education",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "education",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "medical",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "medical",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}, {
|
"featureType": "transportation",
|
"elementType": "labels.text.fill",
|
"stylers": {
|
"color": "#999999ff"
|
}
|
}, {
|
"featureType": "transportation",
|
"elementType": "labels.text.stroke",
|
"stylers": {
|
"color": "#ffffffff"
|
}
|
}
|
];
|
|
// 船只类型图片
|
const SHIP_IMAGE = {
|
"0": "备用",
|
"20": "地效飞行器",
|
"21": "地效飞行器(危险品A类)",
|
"22": "地效飞行器(危险品B类)",
|
"23": "地效飞行器(危险品C类)",
|
"24": "地效飞行器(危险品D类)",
|
"25": "地效飞行器(保留)",
|
"29": "地效飞行器(无额外信息)",
|
"30": "渔船",
|
"31": "拖轮",
|
"32": "拖轮(拖带长度超过200米)",
|
"33": "挖泥船或水下作业船",
|
"34": "潜水作业船",
|
"35": "军用舰船",
|
"36": "帆船",
|
"37": "游艇",
|
"40": "高速船",
|
"41": "高速船(危险品A类)",
|
"42": "高速船(危险品B类)",
|
"43": "高速船(危险品C类)",
|
"44": "高速船(危险品D类)",
|
"45": "高速船(保留)",
|
"49": "高速船(无额外信息)",
|
"50": "引航船",
|
"51": "搜救船",
|
"52": "拖轮",
|
"53": "港口供应船",
|
"54": "防污染设备船",
|
"55": "执法船",
|
"56": "备用",
|
"58": "医疗运输船",
|
"59": "非战斗舰船",
|
"60": "客船",
|
"61": "客船(危险品A类)",
|
"62": "客船(危险品B类)",
|
"63": "客船(危险品C类)",
|
"64": "客船(危险品D类)",
|
"65": "客船(保留)",
|
"69": "客船(无额外信息)",
|
"70": "货船",
|
"71": "货船(危险品A类)",
|
"72": "货船(危险品B类)",
|
"73": "货船(危险品C类)",
|
"74": "货船(危险品D类)",
|
"75": "货船(保留)",
|
"79": "货船(无额外信息)",
|
"80": "液货船",
|
"81": "液货船(危险品A类)",
|
"82": "液货船(危险品B类)",
|
"83": "液货船(危险品C类)",
|
"84": "液货船(危险品D类)",
|
"85": "液货船(保留)",
|
"89": "液货船(无额外信息)",
|
"90": "其他类型",
|
"91": "其他类型(危险品A类)",
|
"92": "其他类型(危险品B类)",
|
"93": "其他类型(危险品C类)",
|
"94": "其他类型(危险品D类)",
|
"95": "其他类型(保留)",
|
"99": "其他类型(无额外信息)"
|
};
|
|
// 航道信息
|
const SHIP_CHANNEL = {
|
current: 'chengyuan',
|
chengyuan: {
|
id: 1,
|
name: '宬苑',
|
nameEn: 'cy',
|
lng: 121.510884,
|
lat: 31.219752,
|
wgsLng: 121.511941,
|
wgsLat: 31.199828
|
},
|
dufeng: {
|
id: 0,
|
name: '杜丰',
|
nameEn: 'df',
|
lng: 121.4780419,
|
lat: 31.078778,
|
wgsLng: 121.47786,
|
wgsLat: 31.061703
|
}
|
};
|
|
// 电子围栏配置项
|
const FENCE_AREA_OPTIONS = {
|
strokeColor:"red", //边线颜色。
|
fillColor:"red", //填充颜色。当参数为空时,圆形将没有填充效果。
|
strokeWeight: 2, //边线的宽度,以像素为单位。
|
strokeOpacity: 0.5, //边线透明度,取值范围0 - 1。
|
fillOpacity: 0.03, //填充的透明度,取值范围0 - 1。
|
strokeStyle: 'solid' //边线的样式,solid或dashed。
|
};
|
|
// mqtt实时船只信息
|
const ALL_SHIP = deepObserve({});
|
|
// 船只选中,水波纹扩散样式
|
let canvasLayer = null;
|
|
// 请求后台数据
|
const REQUEST = {
|
// 封装ajax请求
|
ajax({ url, type = 'GET', params, success, isLoading = true, isAlert = true }) {
|
let layerIndex = null;
|
let rootPath = document.domain === '10.5.226.53' ? '/tggz' : '';
|
return $.ajax({
|
url: `${rootPath}/tg${url}`,
|
type,
|
data: params,
|
timeout: 1000 * 60 * 5,
|
headers: type.toUpperCase() === 'POST' ? {
|
'Content-Type': 'application/json'
|
} : undefined,
|
beforeSend() {
|
if (isLoading) {
|
layerIndex = showLoading();
|
}
|
},
|
complete() {
|
isLoading && closeLoading(layerIndex);
|
},
|
success(result) {
|
let { code, data } = result;
|
if (code === 0) {
|
success && success(data);
|
} else {
|
isAlert && layer.alert('操作失败...', {
|
icon: 2,
|
anim: 1
|
});
|
}
|
},
|
error() {
|
isAlert && layer.alert('服务器异常,请稍后再试...', {
|
icon: 2,
|
anim: 1
|
});
|
}
|
});
|
}
|
};
|
|
// 页面操作事件
|
const PAGE_EVENT = {
|
shipId: null,
|
map: {
|
// marker移动定时器
|
moveTimer: {},
|
// 创建Map实例
|
init() {
|
let _this = this;
|
let { lng, lat } = SHIP_CHANNEL[SHIP_CHANNEL.current];
|
window.baiduMap = new BMap.Map('map-container', {
|
minZoom: 12,
|
maxZoom: 20,
|
enableMapClick: false
|
});
|
baiduMap.centerAndZoom(new BMap.Point(lng, lat), 17);
|
// baiduMap.panBy(leftWidth);
|
baiduMap.enableKeyboard();
|
baiduMap.enableScrollWheelZoom();
|
baiduMap.enableInertialDragging();
|
baiduMap.enableContinuousZoom();
|
// 设置地图样式`
|
baiduMap.setMapStyle({
|
styleJson: BAIDU_MAP_WHITE_STYLE
|
});
|
// 添加缩放控件
|
let zoomCtrl = new BMap.NavigationControl({
|
anchor: BMAP_ANCHOR_TOP_RIGHT,
|
type: BMAP_NAVIGATION_CONTROL_SMALL,
|
offset: {
|
width: 25,
|
height: 70
|
}
|
});
|
baiduMap.addControl(zoomCtrl);
|
|
// 监听页面的缩放事件
|
baiduMap.addEventListener('zoomend', function () {
|
_this.markerSize();
|
});
|
|
// 实例化鼠标绘制工具
|
let drawingManager = new BMapLib.DrawingManager(baiduMap, {
|
isOpen: false, //是否开启绘制模式
|
enableDrawingTool: true, //是否显示工具栏
|
drawingToolOptions: {
|
anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
|
offset: new BMap.Size(10, 10), //偏离值
|
},
|
polygonOptions: FENCE_AREA_OPTIONS, //多边形的样式
|
rectangleOptions: FENCE_AREA_OPTIONS //矩形的样式
|
});
|
|
// 监听绘画工具事件
|
drawingManager.addEventListener('overlaycomplete', function (e) {
|
let { overlay } = e;
|
drawingManager.close();
|
overlay.data = { type: 'fenceArea' };
|
overlay.addContextMenu(contextMenu(overlay));
|
});
|
},
|
// 添加船只
|
addShipMarker(data) {
|
let _this = this;
|
let { object_id, bdLng, bdLat, direction, type } = data;
|
let point = new BMap.Point(bdLng, bdLat);
|
|
// 查询船只信息获取船只类型,根据类型显示相应的图片
|
// PAGE_EVENT.shipInfo(object_id, d => {
|
// let { shipType } = d || {};
|
|
let shipType = type === 'uav' ? '20' : null;
|
_this.imageSize(shipType, ({name, width, height}) => {
|
let icon = new BMap.Icon(`./image/船只/${name}.png`, new BMap.Size(width, height));
|
icon.imageOriginalSize = { width, height};
|
|
// 船
|
let shipMarker = new BMap.Marker(point, {
|
rotation: direction,
|
icon: icon
|
});
|
shipMarker.data = data;
|
|
// 监听点击事件
|
// 移动的时候点击click事件不触发,改为mouseup
|
shipMarker.addEventListener('mouseup', () => {
|
PAGE_EVENT.shipId = object_id;
|
_this.shipActivate([shipMarker]);
|
PAGE_EVENT.shipInfo(object_id);
|
|
// 隐藏时间表单
|
// 清除历史轨迹/轨迹预测
|
// $('#time-query-form').addClass('layui-hide');
|
// PAGE_EVENT.map.removeLineLayer();
|
|
// 点击船只后继续执行历史轨迹/轨迹预测事件
|
let activeType = $('.line-info .line-info-item.active').data('type');
|
if (['history', 'prediction'].includes(activeType)) {
|
PAGE_EVENT[activeType]();
|
}
|
});
|
|
// 添加船只时调整图片大小
|
_this.markerSize(shipMarker)
|
baiduMap.addOverlay(shipMarker);
|
|
// 首次在地图上添加船只时,获取第一条船的信息
|
if (!_this.shipId || !ALL_SHIP[_this.shipId]) {
|
_this.shipId = object_id;
|
_this.shipActivate([shipMarker]);
|
PAGE_EVENT.realTimeShipInfo(data);
|
}
|
|
// 添加船只后调整视角
|
// let layers = baiduMap.getOverlays();
|
// let points = [];
|
// layers.forEach(item => {
|
// if (item instanceof BMap.Marker) {
|
// points.push(item.getPosition());
|
// }
|
// });
|
// baiduMap.setViewport(points);
|
});
|
// });
|
},
|
// 移除船只
|
removeShipMarker(id) {
|
let _this = this;
|
// 根据id找到指定的船只marker
|
let shipMarker = _this.getShipMarker(id);
|
if (shipMarker) {
|
// 地图上移除船只
|
baiduMap.removeOverlay(shipMarker);
|
// 移除船只移动时记录的定时器
|
delete _this.moveTimer[id];
|
}
|
|
// 如果移除是当前选中的船只,重新获取一条船的信息,更新左侧信息
|
if (id == PAGE_EVENT.shipId || !ALL_SHIP[PAGE_EVENT.shipId]) {
|
baiduMap.removeOverlay(canvasLayer);
|
|
let newKey = null;
|
// let bounds = baiduMap.getBounds();
|
for (let key in ALL_SHIP) {
|
let item = ALL_SHIP[key];
|
// let shipObj = item.find(obj => {
|
// let { object_id, bdLng, bdLat, type } = obj;
|
// let p = new BMap.Point(bdLng, bdLat);
|
// return object_id != id && type !== 'uav' && bounds.containsPoint(p);
|
// });
|
let shipObj = item.find(obj => obj.object_id != id && obj.type !== 'uav');
|
if (shipObj) {
|
newKey = key;
|
break;
|
}
|
}
|
|
if (newKey) {
|
let length = ALL_SHIP[newKey].length;
|
PAGE_EVENT.shipId = newKey;
|
PAGE_EVENT.realTimeShipInfo(ALL_SHIP[newKey][length - 1]);
|
shipMarker = _this.getShipMarker(newKey);
|
_this.shipActivate([shipMarker]);
|
PAGE_EVENT.shipInfo(newKey);
|
}
|
}
|
},
|
// 移动船只
|
moveShipMarker(data) {
|
let _this = this;
|
let { object_id: id, bdLng, bdLat, direction } = data;
|
// 根据id找到指定的船只marker
|
let shipMarker = _this.getShipMarker(id);
|
if (!shipMarker) {
|
return;
|
}
|
|
let length = ALL_SHIP[id].length;
|
if (length > 1) {
|
let lastData = ALL_SHIP[id][length - 1];
|
let p1 = new BMap.Point(lastData.bdLng, lastData.bdLat);
|
let p2 = new BMap.Point(bdLng, bdLat);
|
shipMarker.data = lastData;
|
shipMarker.setRotation(direction);
|
// 两次经纬度一致,不再移动位置
|
if (p1.equals(p2)) {
|
return;
|
}
|
_this.move(p1, p2, shipMarker);
|
}
|
|
// 更新当前船只的移动信息
|
if (id == PAGE_EVENT.shipId) {
|
let currentShipMarker = _this.getShipMarker(PAGE_EVENT.shipId);
|
if (currentShipMarker) {
|
PAGE_EVENT.realTimeShipInfo(data);
|
// 更新水波纹样式位置
|
canvasLayer && canvasLayer.draw();
|
}
|
}
|
},
|
// 获取指定船只marker
|
getShipMarker(id) {
|
// 获取所有覆盖物
|
let layers = baiduMap.getOverlays();
|
// 根据id找到指定的船只marker
|
return layers.find(item => item instanceof BMap.Marker && item.data && item.data.object_id == id);
|
},
|
// 添加轨迹路线
|
addLineLayer({data, color = '#00ff00', lineStyle = 'solid', isCircle}) {
|
let _this = this;
|
// 添加路线之前先清除上次添加的路线
|
_this.removeLineLayer();
|
|
if (!data && data.length) {
|
return;
|
}
|
|
// 根据经纬度去重
|
let d = uniqueArray(data, ['lng', 'lat']);
|
|
let points = [];
|
d.forEach(({lng, lat, dateTime}) => {
|
// gps坐标转百度
|
let bd09 = coordinateUtils.wgs84tobd09(parseFloat(lng), parseFloat(lat));
|
let p = new BMap.Point(bd09[0], bd09[1]);
|
points.push(p);
|
|
if (!isCircle) {
|
return;
|
}
|
// 绘制圆点
|
let marker = new BMap.Marker(p, {
|
icon: new BMap.Symbol(BMap_Symbol_SHAPE_CIRCLE, {
|
fillColor: color,
|
fillOpacity: 1,
|
strokeColor: color,
|
strokeOpacity: 1,
|
scale: 3
|
})
|
});
|
// 文字标注
|
let label = new BMap.Label(dateTime, {
|
position: p,
|
offset: new BMap.Size(15, -10)
|
});
|
label.setStyle({
|
border: 'none',
|
fontSize: '14px',
|
backgroundColor: 'transparent'
|
});
|
marker.addEventListener('mouseover', () => {
|
baiduMap.addOverlay(label);
|
});
|
marker.addEventListener('mouseout', () => {
|
baiduMap.removeOverlay(label);
|
});
|
baiduMap.addOverlay(marker);
|
});
|
|
// 绘制连接线
|
let polyline = new BMap.Polyline(points, {
|
strokeStyle: lineStyle,
|
strokeColor: color,
|
strokeOpacity: 1,
|
strokeWeight: 3
|
});
|
baiduMap.addOverlay(polyline);
|
// baiduMap.setViewport(points);
|
},
|
// 移除轨迹路线
|
removeLineLayer() {
|
let layers = baiduMap.getOverlays();
|
layers.forEach(item => {
|
// 移除圆
|
if (item instanceof BMap.Marker) {
|
let icon = item.getIcon();
|
if (icon instanceof BMap.Symbol) {
|
baiduMap.removeOverlay(item);
|
}
|
}
|
// 移除线、文字
|
if (item instanceof BMap.Polyline || item instanceof BMap.Label ) {
|
baiduMap.removeOverlay(item);
|
}
|
});
|
},
|
// 动态获取图片原始大小
|
imageSize(type = '53', callback) {
|
let name = SHIP_IMAGE[type] || '港口供应船';
|
let div = name && name.includes('飞行器') ? 2 : 4;
|
let img = new Image();
|
img.src = `./image/船只/${name}.png`;
|
img.onload = () => {
|
let width = (img.naturalWidth / div).toFixed(2);
|
let height = (img.naturalHeight / div).toFixed(2);
|
img = null;
|
callback && callback({name, width, height});
|
}
|
},
|
// 根据实际需求调整大小,例如缩放级别越大,图片越大
|
markerSize(marker) {
|
let setSize = _marker => {
|
if (_marker instanceof BMap.Marker) {
|
let icon = _marker.getIcon();
|
if (icon instanceof BMap.Symbol) {
|
return;
|
}
|
|
let zoom = baiduMap.getZoom();
|
let { width, height } = icon.imageOriginalSize;
|
let scale = (zoom - 12) / (19 - 12);
|
let newWidth = width * scale;
|
let newHeight = height * scale;
|
|
let size = new BMap.Size(newWidth, newHeight);
|
icon.setSize(size);
|
icon.setImageSize(size);
|
icon.setAnchor({
|
width: newWidth / 2,
|
height: newHeight / 2
|
})
|
_marker.setIcon(icon);
|
}
|
};
|
|
if (marker) {
|
setSize(marker);
|
} else {
|
let layers = baiduMap.getOverlays();
|
layers.forEach(item => setSize(item));
|
}
|
},
|
// 船只移动轨迹路线
|
move(prvePoint, newPoint, marker, polyline) {
|
let _this = this;
|
// 当前帧数
|
let currentCount = 0
|
// _当前的坐标,把球面坐标坐标转化为平面坐标
|
let _prvePoint = baiduMap.getMapType().getProjection().lngLatToPoint(prvePoint)
|
// _终点的坐标,把球面坐标坐标转化为平面坐标
|
let _newPoint = baiduMap.getMapType().getProjection().lngLatToPoint(newPoint)
|
// 运行的状态
|
let runTime = 800
|
// 每隔多长时间执行一次
|
let intervalTimer = 10
|
// 两点之间要循环定位的次数
|
let count = runTime / intervalTimer
|
|
// 记录每条船的定时器,第二次移动时移除上次未执行完的定时,防止鬼畜
|
let { object_id } = marker.data;
|
let timer = _this.moveTimer[object_id];
|
if (timer) {
|
clearInterval(timer);
|
_this.moveTimer[object_id] = null;
|
}
|
//设置定时器
|
_this.moveTimer[object_id] = setInterval(function () {
|
// 防止便利完后maker不在了
|
if (currentCount > count) {
|
clearInterval(_this.moveTimer[object_id])
|
} else {
|
currentCount++
|
let x = linear(_prvePoint.x, _newPoint.x, currentCount, count),
|
y = linear(_prvePoint.y, _newPoint.y, currentCount, count);
|
let pos = baiduMap.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
|
|
//设置marker角度(两点之间的距离车的角度保持一致)
|
if (currentCount === 1) {
|
//转换角度
|
// setRotation(prvePoint, newPoint, marker)
|
}
|
//最后一次的pos等于0
|
marker.setPosition(pos);
|
if (polyline) {
|
// 移动的时候绘制线路
|
let path = polyline.getPath();
|
path.push(pos);
|
polyline.setPath(path);
|
}
|
}
|
}, intervalTimer);
|
/*
|
*缓动效果
|
*初始坐标,目标坐标,当前的步长,总的步长
|
*@param{BMap.Pixel} initPos 初始平面坐标
|
*@parm{BMap.Pixel} targetPos 目标平面坐标
|
*@param{number} 当前帧数
|
*@param {number} count 总帧数
|
*/
|
let linear = function (initPos, targetPos, currentCount, count) {
|
let b = initPos,
|
c = targetPos - initPos,
|
t = currentCount,
|
d = count;
|
return c * t / d + b;
|
}
|
|
/**
|
*在每个点的真实步骤中设置小车转动的角度
|
*/
|
let setRotation = function(curPos, targetPos, marker) {
|
let deg = 0
|
curPos = baiduMap.pointToPixel(curPos)
|
targetPos = baiduMap.pointToPixel(targetPos)
|
if (targetPos.x !== curPos.x) {
|
let tan = (targetPos.y - curPos.y) / (targetPos.x - curPos.x),
|
atan = Math.atan(tan);
|
deg = atan * 360 / (2 * Math.PI);
|
if (targetPos.x < curPos.x) {
|
deg = -deg + 90 + 90;
|
} else {
|
deg = -deg;
|
}
|
deg = -90 + deg
|
marker.setRotation(-deg);
|
|
} else {
|
let disy = targetPos.y - curPos.y;
|
let bias = 0;
|
if (disy > 0)
|
bias = -1
|
else
|
bias = 1
|
marker.setRotation(-bias * 90);
|
}
|
}
|
},
|
// 船只选中效果
|
shipActivate(markers) {
|
// 存储绘图状态和波纹数据
|
let drawingState = {
|
ctx: null,
|
canvas: null,
|
pixelPoints: [], // 存储 { x, y, name, radius, alpha }
|
animationFrameId: null,
|
lastTime: 0,
|
maxRadius: 50, // 波纹最大半径
|
rippleSpeed: 30, // 波纹扩散速度 (像素/秒)
|
startAlpha: 1 // 波纹初始透明度
|
};
|
|
// 创建 CanvasLayer 实例
|
if (canvasLayer) {
|
baiduMap.removeOverlay(canvasLayer);
|
}
|
canvasLayer = new BMap.CanvasLayer({
|
paneName: 'vertexPane',
|
update: function () {
|
let canvas = this.canvas;
|
let ctx = canvas.getContext('2d');
|
|
drawingState.ctx = ctx;
|
drawingState.canvas = canvas;
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
// 获取现有的 radius/alpha 数据,以便在移动时保留状态
|
const existingState = {};
|
drawingState.pixelPoints.forEach(p => {
|
existingState[p.id] = { radius: p.radius, alpha: p.alpha };
|
});
|
|
drawingState.pixelPoints = markers.filter(marker => !!marker).map(marker => {
|
let { object_id } = marker.data;
|
let point = marker.getPosition();
|
let pixel = baiduMap.pointToPixel(point);
|
const oldState = existingState[object_id];
|
return {
|
x: pixel.x,
|
y: pixel.y,
|
// 保留旧的状态或创建新的,初始半径以错开动画
|
id: object_id,
|
radius: oldState ? oldState.radius : drawingState.maxRadius,
|
alpha: oldState ? oldState.alpha : drawingState.startAlpha
|
};
|
});
|
|
if (!drawingState.animationFrameId) {
|
startAnimation();
|
}
|
|
return true;
|
}
|
});
|
|
baiduMap.addOverlay(canvasLayer);
|
// 设置canvasLayer父元素层级,防止阻挡绘制工具
|
$(canvasLayer.canvas).parent().css('z-index', 100);
|
|
// 定义并启动动画循环
|
function animate() {
|
drawingState.animationFrameId = requestAnimationFrame(animate);
|
|
if (!drawingState.ctx) return;
|
|
let ctx = drawingState.ctx;
|
let canvas = drawingState.canvas;
|
let now = performance.now();
|
let deltaTime = (now - drawingState.lastTime) / 1000;
|
drawingState.lastTime = now;
|
|
// 清空 Canvas
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
let maxRadius = drawingState.maxRadius;
|
let speed = drawingState.rippleSpeed;
|
let startAlpha = drawingState.startAlpha;
|
|
// 绘制每个点及其波纹
|
drawingState.pixelPoints.forEach(p => {
|
// 更新状态:半径变大
|
p.radius += speed * deltaTime;
|
|
// 如果半径超出范围,则重置
|
if (p.radius >= maxRadius) {
|
p.radius = 0; // 重置半径
|
p.alpha = startAlpha; // 重置透明度
|
} else {
|
// 透明度随半径变大而减小
|
p.alpha = startAlpha * (1 - (p.radius / maxRadius));
|
}
|
|
// 绘制扩散的实心圆
|
ctx.beginPath();
|
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
|
ctx.fillStyle = `rgba(0, 255, 0, ${p.alpha})`; // 使用计算出的透明度
|
ctx.fill();
|
});
|
}
|
|
// 启动动画
|
function startAnimation() {
|
if (!drawingState.animationFrameId) {
|
drawingState.lastTime = performance.now();
|
animate();
|
}
|
}
|
},
|
// 清除覆盖物
|
clearOverlays(type) {
|
let overlays = baiduMap.getOverlays();
|
overlays.forEach(item => {
|
if (item?.data?.type === type) {
|
baiduMap.removeOverlay(item);
|
}
|
});
|
}
|
},
|
// mqtt船只实时信息
|
realTime() {
|
// 根据mqtt订阅更新地图右下角服务器状态
|
const $status = $('#map-status .layui-badge-dot');
|
const statusColor = { good: 'layui-bg-green', bad: 'layui-bg-red'};
|
// mqtt配置信息
|
const host = 'ws://10.5.226.53:8083/mqtt';
|
const sendTopic = ['dfAddTrack','dfAddObj','dfRemoveObj','uavAddObj','uavAddTrack','uavRemoveObj'];
|
const qos = 0;
|
const mqttOptions = {
|
keepalive: 60,
|
clean: true,
|
username: 'eadpoint',
|
password: '321123',
|
connectTimeout: 10000,
|
reconnectPeriod: 3000
|
};
|
|
console.log('Connecting mqtt client')
|
const client = mqtt.connect(host, mqttOptions);
|
|
// 连接异常时触发
|
client.on('error', (err) => {
|
console.log('Connection error: ', err);
|
$status.removeClass(statusColor.good);
|
$status.addClass(statusColor.bad);
|
// client.end()
|
});
|
// 重新自动连接时触发
|
client.on('reconnect', () => {
|
console.log('Reconnecting...');
|
});
|
// 连接成功时触发
|
client.on('connect', () => {
|
$status.addClass(statusColor.good);
|
$status.removeClass(statusColor.bad);
|
client.subscribe(sendTopic, { qos }, (error) => {
|
if (error) {
|
console.log('Subscribe error:', error);
|
}
|
});
|
});
|
// 收到发布消息时触发
|
client.on('message', (topic, payload) => {
|
let resData = JSON.parse(payload.toString());
|
if ([sendTopic[0], sendTopic[1], sendTopic[3], sendTopic[4]].includes(topic)) {
|
let { object_id, lng, lat } = resData;
|
// gps坐标转百度
|
let bd09 = coordinateUtils.wgs84tobd09(lng, lat);
|
resData.bdLng = bd09[0];
|
resData.bdLat = bd09[1];
|
// 记录数据时间
|
resData.realTime = Date.now();
|
// 添加船只路径点
|
if (!ALL_SHIP[object_id]) {
|
ALL_SHIP[object_id] = [];
|
}
|
ALL_SHIP[object_id].push(resData);
|
if ([sendTopic[3], sendTopic[4]].includes(topic)) {
|
console.log('无人机信息', resData)
|
}
|
} else if ([sendTopic[2], sendTopic[5]].includes(topic)) {
|
// 移除船只
|
let object_id = typeof resData === 'object' ? resData.object_id : resData;
|
delete ALL_SHIP[object_id];
|
}
|
checkShip();
|
});
|
|
// mqtt移除事件可能会不及时反馈
|
// 检测船只是否长时间(30秒)未移动
|
let checkShip = layui.throttle(function() {
|
let layers = baiduMap.getOverlays();
|
layers.forEach(item => {
|
if (item instanceof BMap.Marker) {
|
let id = item?.data?.object_id;
|
if (!id) {
|
return;
|
}
|
|
let data = ALL_SHIP[id];
|
if (data) {
|
let length = data.length;
|
let { object_id, realTime } = data[length - 1];
|
let now = Date.now();
|
if ((now - realTime) > 1000 * 30) {
|
// 超过30秒没添加过数据,则移除该船只
|
console.log('超时未移动,移除船只:', object_id)
|
delete ALL_SHIP[object_id];
|
}
|
} else {
|
delete ALL_SHIP[id];
|
}
|
}
|
});
|
}, 1000 * 10);
|
},
|
// 查询船只信息
|
shipInfo(objectId, callback) {
|
REQUEST.ajax({
|
url: '/ship/findDtRadarBoatMsg',
|
params: {
|
objectId,
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id,
|
},
|
success(data) {
|
let renderHtml = d => {
|
if (d) {
|
let $shipInfo = $('.ship-info-card');
|
let tpl = shipInfoTpl.innerHTML;
|
laytpl(tpl).render(d, function(html) {
|
$shipInfo.replaceWith(html);
|
});
|
}
|
}
|
if (callback) {
|
callback(data);
|
} else {
|
renderHtml(data);
|
}
|
},
|
isLoading: false,
|
isAlert: false
|
});
|
},
|
// 船只移动实时信息
|
realTimeShipInfo: layui.debounce(function(data) {
|
let $locationInfo = $('.location-info-card');
|
let tpl = locationInfoTpl.innerHTML;
|
laytpl(tpl).render(data, function(html) {
|
$locationInfo.replaceWith(html);
|
});
|
}, 100),
|
// 实时监控画面
|
camera() {
|
let name = SHIP_CHANNEL[SHIP_CHANNEL.current].name;
|
this.open({
|
title: false,
|
content: `../a.html?site=${name}基站`
|
});
|
},
|
// 历史轨迹
|
history(params = {}) {
|
let _this = this;
|
let date = new Date();
|
let end = layui.util.toDateString(date, 'yyyy-MM-dd HH:mm:ss');
|
date.setDate(date.getDate() - 1);
|
let start = layui.util.toDateString(date, 'yyyy-MM-dd HH:mm:ss');
|
$('#start-time').val(start);
|
$('#end-time').val(end);
|
REQUEST.ajax({
|
url: '/ship/queryRadarBoatHistory',
|
params: {
|
objectId: _this.shipId,
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id,
|
startTime: $('#start-time').val(),
|
endTime: $('#end-time').val(),
|
...params
|
},
|
success(data) {
|
_this.map.addLineLayer({
|
data,
|
isCircle: true
|
});
|
}
|
});
|
},
|
// 预测
|
prediction() {
|
let _this = this;
|
REQUEST.ajax({
|
url: '/ship/trajectoryPrediction',
|
params: {
|
list: _this.shipId,
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id
|
},
|
success(data) {
|
_this.map.addLineLayer({
|
data: data[_this.shipId],
|
color: '#fff',
|
lineStyle: 'dashed'
|
});
|
}
|
});
|
},
|
// 3D全景视角
|
'3d'() {
|
this.open({
|
title: '3D全景视角',
|
content: '../index2.html',
|
success(layero, index) {
|
let current = SHIP_CHANNEL['current'];
|
let data = {
|
"lat": SHIP_CHANNEL[current].wgsLat,
|
"lng": SHIP_CHANNEL[current].wgsLng,
|
"alt": 445.6,
|
"heading": 341.8,
|
"pitch": -9.9,
|
"name": SHIP_CHANNEL[current].nameEn,
|
"object_id": PAGE_EVENT.shipId
|
};
|
console.log(SHIP_CHANNEL['current'], data)
|
let iframe = window[`layui-layer-iframe${index}`];
|
iframe.postMessage(data, '*');
|
},
|
});
|
},
|
// 整体三维视角
|
all3d() {
|
this.open({
|
title: '三维视角',
|
content: '../index2.html',
|
success(layero, index) {
|
let current = SHIP_CHANNEL['current'];
|
let data = {
|
"lat": SHIP_CHANNEL[current].wgsLat,
|
"lng": SHIP_CHANNEL[current].wgsLng,
|
"alt": 445.6,
|
"heading": 341.8,
|
"pitch": -9.9,
|
"name": SHIP_CHANNEL[current].nameEn
|
};
|
let iframe = window[`layui-layer-iframe${index}`];
|
iframe.postMessage(data, '*');
|
},
|
end() {
|
$('#map-type .map-type-item').eq(0).click();
|
}
|
});
|
},
|
// 打开弹框
|
open(options) {
|
layer.open({
|
type: 2,
|
area: ['1000px', '700px'],
|
...options
|
});
|
},
|
// 查询电子围栏
|
fenceArea() {
|
let _this = this;
|
REQUEST.ajax({
|
url: '/fenceArea/findList',
|
params: {
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id
|
},
|
success(data) {
|
if (!data?.length) {
|
return;
|
}
|
|
try {
|
let polygons = [];
|
let polygonType = 'fenceArea';
|
_this.map.clearOverlays(polygonType);
|
for (let d of data) {
|
let { id, coordinate } = d;
|
coordinate = JSON.parse(coordinate);
|
let points = [];
|
for (let item of coordinate) {
|
let { lng, lat } = item;
|
let bd09 = coordinateUtils.wgs84tobd09(lng, lat);
|
points.push(new BMap.Point(bd09[0], bd09[1]));
|
}
|
let polygon = new BMap.Polygon(points, FENCE_AREA_OPTIONS);
|
polygon.data = {
|
id,
|
type: polygonType
|
};
|
polygon.addContextMenu(contextMenu(polygon));
|
baiduMap.addOverlay(polygon);
|
polygons.push(polygon);
|
}
|
SHIP_CHANNEL[SHIP_CHANNEL.current].polygon = polygons;
|
} catch (e) {
|
console.error(e);
|
}
|
}
|
});
|
},
|
// 保存电子围栏
|
saveFenceArea(overlay) {
|
let path = overlay.getPath();
|
if (!path?.length) {
|
return;
|
}
|
|
// 清除之前保存的电子围栏
|
let polygon = SHIP_CHANNEL[SHIP_CHANNEL.current].polygon;
|
if (polygon?.length) {
|
polygon.forEach(item => this.deleteFenceArea(item));
|
}
|
|
// 百度经纬度转gps
|
let coordinates = [];
|
for (let i = 0; i < path.length; i++) {
|
let { lng, lat } = path[i];
|
let wgs = coordinateUtils.bd09towgs84(lng, lat);
|
coordinates[i] = {
|
lng: wgs[0],
|
lat: wgs[1]
|
}
|
}
|
|
REQUEST.ajax({
|
url: '/fenceArea/save',
|
type: 'POST',
|
params: JSON.stringify({
|
coordinates,
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id
|
}),
|
success(data) {
|
if (data) {
|
showMsg('保存成功');
|
overlay.data = {
|
id: data,
|
type: 'fenceArea'
|
};
|
overlay.removeContextMenu();
|
overlay.addContextMenu(contextMenu(overlay));
|
if (polygon?.length) {
|
SHIP_CHANNEL[SHIP_CHANNEL.current].polygon.push(overlay);
|
} else {
|
SHIP_CHANNEL[SHIP_CHANNEL.current].polygon = [overlay];
|
}
|
}
|
}
|
});
|
},
|
// 删除电子围栏
|
deleteFenceArea(overlay) {
|
let { id } = overlay.data;
|
REQUEST.ajax({
|
url: '/fenceArea/delete',
|
type: 'DELETE',
|
params: {
|
id
|
},
|
success(data) {
|
console.log(data);
|
let polygon = SHIP_CHANNEL[SHIP_CHANNEL.current].polygon;
|
SHIP_CHANNEL[SHIP_CHANNEL.current].polygon = polygon.filter(item => item.data.id !== id );
|
baiduMap.removeOverlay(overlay);
|
}
|
});
|
},
|
// 无人机信息
|
uavInfo() {
|
REQUEST.ajax({
|
url: '/uav/findUav',
|
params: {
|
stationId: SHIP_CHANNEL[SHIP_CHANNEL.current].id
|
},
|
success(data) {
|
if (!data?.length) {
|
return;
|
}
|
|
let { uavLng, uavLat } = data[0];
|
data[0].uavLng = uavLng.substr(0, 12);
|
data[0].uavLat = uavLat.substr(0, 11);
|
|
let $uavInfo = $('.uav-info-card');
|
let tpl = uavInfoTpl.innerHTML;
|
laytpl(tpl).render(data[0], function(html) {
|
$uavInfo.replaceWith(html);
|
});
|
}
|
});
|
}
|
};
|
|
// 历史轨迹时间选择
|
laydate.render({
|
elem: '#time-dom',
|
type: 'datetime',
|
rangeLinked: true,
|
range: ['#start-time', '#end-time'],
|
done(value) {
|
let times = value.split(' - ');
|
PAGE_EVENT.history({
|
startTime: times[0],
|
endTime: times[1]
|
});
|
}
|
});
|
|
// 子页面获取数据
|
window.addEventListener('message', e => {
|
let channel = e.data;
|
if (typeof channel === 'object') {
|
return;
|
}
|
|
$('.layui-header .layui-nav .layui-nav-item').each((index, item) => {
|
let text = $(item).text();
|
if(text.includes(channel)){
|
$(item).find('.channel').click();
|
}
|
});
|
});
|
|
// 页面加载完毕后执行
|
$(function () {
|
// 初始化地图
|
PAGE_EVENT.map.init();
|
// mqtt实时信息
|
PAGE_EVENT.realTime();
|
// 显示当前航道电子围栏
|
PAGE_EVENT.fenceArea();
|
// 显示无人机信息
|
PAGE_EVENT.uavInfo();
|
});
|
|
// 航道点击事件
|
element.on('nav(channel-nav)', function(elem){
|
let value = $(elem).data('value');
|
SHIP_CHANNEL.current = value;
|
let { lng, lat } = SHIP_CHANNEL[value];
|
baiduMap.panTo(new BMap.Point(lng, lat));
|
PAGE_EVENT.fenceArea();
|
PAGE_EVENT.uavInfo();
|
});
|
|
// 航线信息点击事件
|
$(document).on('click', '.line-info .line-info-item', function () {
|
let _this = this;
|
let activeClass = 'active';
|
let type = $(_this).data('type');
|
|
$('.line-info-item').removeClass(activeClass);
|
$(_this).addClass(activeClass);
|
if (type === 'history') {
|
$('#time-query-form').removeClass('layui-hide');
|
} else {
|
$('#time-query-form').addClass('layui-hide');
|
}
|
|
PAGE_EVENT.map.removeLineLayer();
|
PAGE_EVENT[type]();
|
});
|
|
// 地图类型切换事件
|
$(document).on('click', '#map-type .map-type-item', function () {
|
let _this = this;
|
let activeClass = 'active';
|
let toggleClass = 'toggle-active';
|
let type = $(_this).data('type');
|
|
$('#map-type .map-type-item').removeClass(activeClass);
|
$(_this).addClass(activeClass);
|
if (type === 'map') {
|
$('#map-type .map-type-slider').removeClass(toggleClass);
|
} else {
|
$('#map-type .map-type-slider').addClass(toggleClass);
|
PAGE_EVENT.all3d();
|
}
|
});
|
|
// 使用Proxy监视对象变化
|
function deepObserve(target) {
|
const handler = {
|
get(target, prop) {
|
const value = target[prop];
|
if (typeof value === 'object' && value !== null) {
|
return deepObserve(value);
|
}
|
return value;
|
},
|
set(target, prop, value) {
|
// 过滤掉对象数组 length 属性的设置
|
if (prop === 'length' && Array.isArray(target)) {
|
return Reflect.set(target, prop, value);
|
}
|
|
if (Array.isArray(target)) {
|
let length = target.length;
|
if (length === 1) {
|
// 只有一条数据,在地图上创建船只
|
PAGE_EVENT.map.addShipMarker(value);
|
} else {
|
// 移动船只
|
PAGE_EVENT.map.moveShipMarker(value);
|
}
|
}
|
|
return Reflect.set(target, prop, value);
|
},
|
deleteProperty(target, prop) {
|
// 移除船只
|
PAGE_EVENT.map.removeShipMarker(prop);
|
return Reflect.deleteProperty(target, prop);
|
}
|
};
|
|
return new Proxy(target, handler);
|
}
|
|
// 根据经纬度去重
|
function uniqueArray(data, keys) {
|
const map = new Map();
|
return data.filter(item => {
|
const key = keys.map(k => item[k]).join('|');
|
if (map.has(key)) {
|
return false;
|
}
|
map.set(key, true);
|
return true;
|
});
|
}
|
|
// 绘制电子围栏的右键菜单
|
function contextMenu(overlay) {
|
let contextMenu = new BMap.ContextMenu();
|
let id = overlay?.data?.id;
|
if (!id) {
|
contextMenu.addItem(new BMap.MenuItem('保存电子围栏', function () {
|
let polygon = SHIP_CHANNEL[SHIP_CHANNEL.current].polygon;
|
if (polygon?.length) {
|
layer.confirm(`当前航道已存在电子围栏,是否覆盖?`, function(index){
|
layer.close(index);
|
PAGE_EVENT.saveFenceArea(overlay);
|
}, function () {
|
baiduMap.removeOverlay(overlay);
|
});
|
} else {
|
PAGE_EVENT.saveFenceArea(overlay);
|
}
|
}));
|
contextMenu.addSeparator();
|
}
|
contextMenu.addItem(new BMap.MenuItem('删除电子围栏', function () {
|
if (id) {
|
PAGE_EVENT.deleteFenceArea(overlay);
|
} else {
|
baiduMap.removeOverlay(overlay);
|
}
|
}));
|
return contextMenu;
|
}
|
|
function showMsg(msg, type, callback) {
|
return layer.msg(msg, {
|
anim: type,
|
time: type !== 6 ? 1000 : 3000
|
}, callback);
|
}
|
|
function showLoading() {
|
return layer.load(2, {
|
shade: 0.1
|
});
|
}
|
|
function closeLoading(index) {
|
if (index) {
|
layer.close(index);
|
} else {
|
layer.closeAll();
|
}
|
}
|
|
})
|