diff --git a/sec-beidou/src/main/resources/templates/page/device_overview.html b/sec-beidou/src/main/resources/templates/page/device_overview.html index bc1619fe..8cc3d97b 100644 --- a/sec-beidou/src/main/resources/templates/page/device_overview.html +++ b/sec-beidou/src/main/resources/templates/page/device_overview.html @@ -34,7 +34,6 @@ } .top-panel-number { - /* line-height: 60px; */ font-size: 30px; border-right: 1px solid #eceff9; height: 100%; @@ -89,6 +88,8 @@ margin: 0 5px; text-align: center; line-height: 30px; + cursor: pointer; + transition: all 0.3s ease; } .btn:hover, .btn.active { background-color: rgba(27, 142, 236, 0.8); @@ -120,6 +121,7 @@ .search-box { display: flex; margin-bottom: 10px; + align-items: center; } .search-box input { flex: 1; @@ -145,6 +147,18 @@ border: 1px solid #e6e6e6; height: 30px; } + .switch-box { + margin-top: 10px; + } + .switch-box .layui-form-item { + display: flex; + justify-content: space-around; + padding: 0 5px; + } + .switch-box .layui-form-switch { + margin-top: 0; + border-radius: 6px; + } @@ -201,7 +215,6 @@
-
@@ -218,6 +231,14 @@
+
+ +
+ + +
+ +
@@ -240,6 +261,12 @@ var currentSearchedDevice = null; // 当前搜索的设备ID var myLocationFeature = null; // 存储"我的位置"标记 var myLocationInterval; // 存储定时更新位置的interval对象 + var clusterSource; + var clusterLayer; + var showDeviceId = true; + var showCluster = true; + var minZoomForLabels = 4; + var maxZoomForClustering = 8; // 天地图 API 密钥(fengyarnom@gmail.com) var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac'; @@ -357,9 +384,73 @@ function initialize() { vectorSource = new ol.source.Vector(); vectorLayer = new ol.layer.Vector({ + source: vectorSource, + style: function(feature) { + if (!feature.get('isMyLocation')) { + var deviceInfo = feature.get('deviceInfo'); + var iconSrc; + var color = '#000'; + + if (deviceInfo.warning == 2) { + iconSrc = '../images/loc1_red.png'; + } else if (deviceInfo.warning == 1) { + iconSrc = '../images/loc1_orange.png'; + } else { + iconSrc = '../images/loc1_green.png'; + } + + var style = new ol.style.Style({ + image: new ol.style.Icon({ + anchor: [0.5, 1], + src: iconSrc, + scale: 0.7 + }) + }); + + // 根据缩放级别和设置决定是否显示设备ID + if (showDeviceId && map.getView().getZoom() >= minZoomForLabels) { + style.setText(new ol.style.Text({ + text: deviceInfo.deviceid, + offsetY: -30, + fill: new ol.style.Fill({ color: color }), + stroke: new ol.style.Stroke({ color: '#fff', width: 2 }), + font: '12px Arial' + })); + } + + return style; + } + return null; + } + }); + + clusterSource = new ol.source.Cluster({ + distance: 40, source: vectorSource }); + clusterLayer = new ol.layer.Vector({ + source: clusterSource, + style: function(feature) { + var size = feature.get('features').length; + var style = new ol.style.Style({ + image: new ol.style.Circle({ + radius: 15, + fill: new ol.style.Fill({ + color: '#3399CC' + }) + }), + text: new ol.style.Text({ + text: size.toString(), + fill: new ol.style.Fill({ + color: '#fff' + }) + }) + }); + return style; + } + }); + var initialMapType = document.getElementById('mapTypeSelect').value; currentBaseLayer = mapLayers[initialMapType]; @@ -367,6 +458,7 @@ target: 'map-container', layers: [ currentBaseLayer, + clusterLayer, vectorLayer ], view: new ol.View({ @@ -374,6 +466,48 @@ zoom: 7 }) }); + + // 设置初始可见性状态 + var initialZoom = map.getView().getZoom(); + if (showCluster && initialZoom < maxZoomForClustering) { + clusterLayer.setVisible(true); + vectorLayer.setVisible(false); + } else { + clusterLayer.setVisible(false); + vectorLayer.setVisible(true); + } + + map.getView().on('change:resolution', function() { + var zoom = map.getView().getZoom(); + if (showCluster) { + if (zoom >= maxZoomForClustering) { + clusterLayer.setVisible(false); + vectorLayer.setVisible(true); + } else { + clusterLayer.setVisible(true); + vectorLayer.setVisible(false); + } + } + vectorLayer.changed(); + }); + + map.on('click', function(evt) { + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + + if (feature) { + var features = feature.get('features'); + if (features && features.length > 1) { + var extent = vectorSource.getExtent(); + map.getView().fit(extent, { + padding: [50, 50, 50, 50], + duration: 1000 + }); + } + } + }); + if (deviceList.length > 0) { var centerLat = 0; var centerLon = 0; @@ -391,10 +525,10 @@ addDeviceMarkers(); myLocation(); - startLocationUpdates(); // 启动位置定时更新 + startLocationUpdates(); } + function switchMapType(mapType) { - console.log('切换地图类型到:', mapType); map.removeLayer(currentBaseLayer); currentBaseLayer = mapLayers[mapType]; map.getLayers().insertAt(0, currentBaseLayer); @@ -402,7 +536,7 @@ updateMyLocationForMapType(mapType); addDeviceMarkers(); } - + // 根据地图类型更新我的位置标记 function updateMyLocationForMapType(mapType) { if (myLocationFeature) { @@ -426,6 +560,7 @@ } } + // 设备定位标志 function addDeviceMarkers() { var savedMyLocationFeature = myLocationFeature; @@ -453,36 +588,14 @@ deviceInfo: device }); - var iconSrc; - var color = '#000'; - if (device.warning == 2) { - iconSrc = '../images/loc1_red.png'; redFeatures.push(feature); } else if (device.warning == 1) { - iconSrc = '../images/loc1_orange.png'; orangeFeatures.push(feature); } else { - iconSrc = '../images/loc1_green.png'; greenFeatures.push(feature); } - var style = new ol.style.Style({ - image: new ol.style.Icon({ - anchor: [0.5, 1], - src: iconSrc, - scale: 1 - }), - text: new ol.style.Text({ - text: device.deviceid, - offsetY: -30, - fill: new ol.style.Fill({ color: color }), - stroke: new ol.style.Stroke({ color: '#fff', width: 2 }), - font: '12px Arial' - }) - }); - - feature.setStyle(style); allFeatures.push(feature); vectorSource.addFeature(feature); } @@ -502,6 +615,9 @@ hideOrange(); } } + + // 强制更新样式 + vectorLayer.changed(); } function myLocation() { @@ -536,7 +652,7 @@ image: new ol.style.Icon({ anchor: [0.5, 1], src: '../images/loc_blue.png', - scale: 1 + scale: 0.7 }) }); @@ -778,13 +894,36 @@ } layui.use(['form'], function(){ var form = layui.form; + form.on('select(mapType)', function(data){ switchMapType(data.value); }); + form.on('switch(showDeviceId)', function(data){ + showDeviceId = data.elem.checked; + vectorLayer.changed(); + }); + + // 聚合显示 + form.on('switch(showCluster)', function(data){ + showCluster = data.elem.checked; + if (showCluster) { + var zoom = map.getView().getZoom(); + if (zoom < maxZoomForClustering) { + clusterLayer.setVisible(true); + vectorLayer.setVisible(false); + } else { + clusterLayer.setVisible(false); + vectorLayer.setVisible(true); + } + } else { + clusterLayer.setVisible(false); + vectorLayer.setVisible(true); + } + }); + initialize(); - - showWarning2(); + showAll(); }); function queryDevices(status_type) {