diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/coordinate-utils.js b/sec-beidou/src/main/resources/static/js/device-overview-module/coordinate-utils.js index bbb4d1a8..8726cbb6 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/coordinate-utils.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/coordinate-utils.js @@ -36,12 +36,7 @@ var CoordinateUtils = (function() { return ret; } - /** - * WGS84转GCJ-02坐标系 - * @param {number} wgLat - WGS84纬度 - * @param {number} wgLon - WGS84经度 - * @returns {object} 转换后的坐标 {lat, lon} - */ + function transform(wgLat, wgLon) { var mars_point = {lon: 0, lat: 0}; if (outOfChina(wgLon, wgLat)) { @@ -62,13 +57,7 @@ var CoordinateUtils = (function() { return mars_point; } - /** - * 根据地图类型转换坐标 - * @param {number} lat - 纬度 - * @param {number} lon - 经度 - * @param {string} mapType - 地图类型 - * @returns {Array} OpenLayers坐标格式 - */ + function getMapCoordinates(lat, lon, mapType) { var coordinates; if (mapType === 'amap' || mapType === 'amap_satellite') { @@ -76,16 +65,16 @@ var CoordinateUtils = (function() { var gcjCoord = transform(lat, lon); coordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); } else if (mapType.startsWith('google_')) { - // Google地图使用WGS84坐标系,直接使用 + // Google地图使用WGS84坐标系 coordinates = ol.proj.fromLonLat([lon, lat]); } else { - // 天地图 CGCS2000,2000国家大地坐标系,与WGS84实质一样 + // 天地图 CGCS2000,与WGS84实质一样 coordinates = ol.proj.fromLonLat([lon, lat]); } return coordinates; } - // 公开API + return { transform: transform, getMapCoordinates: getMapCoordinates, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/device-markers.js b/sec-beidou/src/main/resources/static/js/device-overview-module/device-markers.js index b5aa41f0..e3e17f98 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/device-markers.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/device-markers.js @@ -5,7 +5,6 @@ var DeviceMarkers = (function() { 'use strict'; - // 私有变量 var greenFeatures = []; var orangeFeatures = []; var redFeatures = []; @@ -15,28 +14,19 @@ var DeviceMarkers = (function() { var showDeviceId = true; var minZoomForLabels = 4; - // 外部依赖的引用 + var map = null; var vectorSource = null; var vectorLayer = null; - /** - * 初始化设备标记管理器 - * @param {ol.Map} mapInstance - 地图实例 - * @param {ol.source.Vector} vectorSourceInstance - 矢量数据源 - * @param {ol.layer.Vector} vectorLayerInstance - 矢量图层 - */ + function init(mapInstance, vectorSourceInstance, vectorLayerInstance) { map = mapInstance; vectorSource = vectorSourceInstance; vectorLayer = vectorLayerInstance; } - /** - * 创建设备标记样式 - * @param {ol.Feature} feature - 要素对象 - * @returns {ol.style.Style} 样式对象 - */ + function createDeviceStyle(feature) { if (feature.get('isMyLocation')) { return new ol.style.Style({ @@ -92,24 +82,18 @@ var DeviceMarkers = (function() { return style; } - /** - * 添加设备标记到地图 - * @param {Array} deviceList - 设备列表 - */ + function addDeviceMarkers(deviceList) { if (!vectorSource || !deviceList) return; - // 保存当前位置标记 var savedMyLocationFeature = myLocationFeature; - // 清空现有标记 vectorSource.clear(); greenFeatures = []; orangeFeatures = []; redFeatures = []; allFeatures = []; - // 添加设备标记 for (var i = 0; i < deviceList.length; i++) { var device = deviceList[i]; var currentMapType = getCurrentMapType(); @@ -137,7 +121,6 @@ var DeviceMarkers = (function() { vectorSource.addFeature(feature); } - // 恢复位置标记 if (savedMyLocationFeature) { vectorSource.addFeature(savedMyLocationFeature); } @@ -148,18 +131,13 @@ var DeviceMarkers = (function() { } } - /** - * 获取当前地图类型 - * @returns {string} 地图类型 - */ + function getCurrentMapType() { var mapTypeSelect = document.getElementById('mapTypeSelectNew'); return mapTypeSelect ? mapTypeSelect.value : 'tianditu_satellite'; } - /** - * 显示所有设备 - */ + function showAllDevices() { if (!vectorSource) return; @@ -175,9 +153,6 @@ var DeviceMarkers = (function() { } } - /** - * 只显示一般告警设备 - */ function showWarning1Devices() { if (!vectorSource) return; @@ -196,9 +171,7 @@ var DeviceMarkers = (function() { hideRedFeatures(); } - /** - * 只显示严重告警设备 - */ + function showWarning2Devices() { if (!vectorSource) return; @@ -217,73 +190,47 @@ var DeviceMarkers = (function() { hideOrangeFeatures(); } - /** - * 隐藏绿色(正常)设备 - */ function hideGreenFeatures() { for (var i = 0; i < greenFeatures.length; i++) { vectorSource.removeFeature(greenFeatures[i]); } } - - /** - * 隐藏橙色(一般告警)设备 - */ + function hideOrangeFeatures() { for (var i = 0; i < orangeFeatures.length; i++) { vectorSource.removeFeature(orangeFeatures[i]); } } - /** - * 隐藏红色(严重告警)设备 - */ function hideRedFeatures() { for (var i = 0; i < redFeatures.length; i++) { vectorSource.removeFeature(redFeatures[i]); } } - /** - * 根据设备ID查找设备 - * @param {string} deviceId - 设备ID - * @returns {ol.Feature|null} 找到的设备要素 - */ function findDeviceById(deviceId) { for (var i = 0; i < allFeatures.length; i++) { var feature = allFeatures[i]; var deviceInfo = feature.get('deviceInfo'); - if (deviceInfo && deviceInfo.deviceid.includes(deviceId)) { + if (deviceInfo && deviceInfo.deviceid === deviceId) { return feature; } } return null; } - - /** - * 定位到指定设备 - * @param {string} deviceId - 设备ID - * @returns {boolean} 是否成功定位 - */ + function locateDevice(deviceId) { - var targetFeature = findDeviceById(deviceId); - - if (targetFeature) { - var geometry = targetFeature.getGeometry(); - var deviceCoord = geometry.getCoordinates(); + var feature = findDeviceById(deviceId); + if (feature && map) { + var geometry = feature.getGeometry(); + var coordinates = geometry.getCoordinates(); - if (map) { - map.getView().animate({ - center: deviceCoord, - zoom: 16, - duration: 800 - }); - } - - return true; + map.getView().animate({ + center: coordinates, + zoom: Math.max(map.getView().getZoom(), 15), + duration: 1000 + }); } - - return false; } /** @@ -291,49 +238,48 @@ var DeviceMarkers = (function() { */ function getMyLocation() { if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(function(position) { - var lon = position.coords.longitude; - var lat = position.coords.latitude; - var currentMapType = getCurrentMapType(); - var coordinates = CoordinateUtils.getMapCoordinates(lat, lon, currentMapType); - - // 如果已经存在位置标记,则先移除 - if (myLocationFeature) { - vectorSource.removeFeature(myLocationFeature); + navigator.geolocation.getCurrentPosition( + function(position) { + var lat = position.coords.latitude; + var lon = position.coords.longitude; + + var currentMapType = getCurrentMapType(); + var coordinates = CoordinateUtils.getMapCoordinates(lat, lon, currentMapType); + + if (myLocationFeature) { + vectorSource.removeFeature(myLocationFeature); + } + + myLocationFeature = new ol.Feature({ + geometry: new ol.geom.Point(coordinates), + isMyLocation: true + }); + + vectorSource.addFeature(myLocationFeature); + + map.getView().animate({ + center: coordinates, + zoom: 15, + duration: 1000 + }); + }, + function(error) { + console.error('获取位置失败:', error); } - - myLocationFeature = new ol.Feature({ - geometry: new ol.geom.Point(coordinates), - isMyLocation: true, - originalCoords: {lat: lat, lon: lon} - }); - - myLocationFeature.setStyle(createDeviceStyle(myLocationFeature)); - vectorSource.addFeature(myLocationFeature); - - if (map) { - map.getView().setCenter(coordinates); - } - }); + ); } } - /** - * 开始定期更新位置 - */ + function startLocationUpdates() { - if (myLocationInterval) { - clearInterval(myLocationInterval); + if (navigator.geolocation) { + myLocationInterval = setInterval(function() { + getMyLocation(); + }, 30000); } - - myLocationInterval = setInterval(function() { - getMyLocation(); - }, 10 * 60 * 1000); // 10分钟更新一次 } - /** - * 停止位置更新 - */ + function stopLocationUpdates() { if (myLocationInterval) { clearInterval(myLocationInterval); @@ -341,28 +287,19 @@ var DeviceMarkers = (function() { } } - /** - * 根据地图类型更新我的位置标记 - * @param {string} mapType - 地图类型 - */ + function updateMyLocationForMapType(mapType) { if (myLocationFeature) { - var originalCoords = myLocationFeature.get('originalCoords'); - if (originalCoords) { - var coordinates = CoordinateUtils.getMapCoordinates( - originalCoords.lat, - originalCoords.lon, - mapType - ); - myLocationFeature.getGeometry().setCoordinates(coordinates); - } + var geometry = myLocationFeature.getGeometry(); + var coordinates = geometry.getCoordinates(); + var lonLat = ol.proj.toLonLat(coordinates); + + var newCoordinates = CoordinateUtils.getMapCoordinates(lonLat[1], lonLat[0], mapType); + + myLocationFeature.setGeometry(new ol.geom.Point(newCoordinates)); } } - - /** - * 设置是否显示设备ID - * @param {boolean} show - 是否显示 - */ + function setShowDeviceId(show) { showDeviceId = show; if (vectorLayer) { @@ -370,10 +307,7 @@ var DeviceMarkers = (function() { } } - /** - * 获取各类设备数量统计 - * @returns {Object} 统计信息 - */ + function getDeviceStats() { return { total: allFeatures.length, @@ -382,8 +316,7 @@ var DeviceMarkers = (function() { red: redFeatures.length }; } - - // 公开API + return { init: init, createDeviceStyle: createDeviceStyle, @@ -403,7 +336,6 @@ var DeviceMarkers = (function() { setShowDeviceId: setShowDeviceId, getDeviceStats: getDeviceStats, - // 获取器方法 getAllFeatures: function() { return allFeatures; }, getGreenFeatures: function() { return greenFeatures; }, getOrangeFeatures: function() { return orangeFeatures; }, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/map-core.js b/sec-beidou/src/main/resources/static/js/device-overview-module/map-core.js index 6df0aa57..81c22c06 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/map-core.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/map-core.js @@ -5,7 +5,6 @@ var MapCore = (function() { 'use strict'; - // 私有变量 var map = null; var vectorSource = null; var vectorLayer = null; @@ -18,10 +17,7 @@ var MapCore = (function() { var maxZoomForClustering = 8; var hoveredFeature = null; - /** - * 初始化地图 - * @param {Array} deviceList - 设备列表 - */ + function initialize(deviceList) { // 创建矢量数据源和图层 vectorSource = new ol.source.Vector(); @@ -60,11 +56,9 @@ var MapCore = (function() { } }); - // 获取初始地图类型 var initialMapType = document.getElementById('mapTypeSelectNew').value || 'tianditu_satellite'; currentBaseLayer = MapLayers.getLayer(initialMapType); - // 创建地图 map = new ol.Map({ target: 'map-container', layers: [ @@ -78,50 +72,37 @@ var MapCore = (function() { }) }); - // 初始化各个模块 DeviceMarkers.init(map, vectorSource, vectorLayer); MeasureTools.init(map); WeatherForecast.init(); - // 添加比例尺控件 var scaleLineControl = new ol.control.ScaleLine(); map.addControl(scaleLineControl); - // 设置初始图层可见性 var initialZoom = map.getView().getZoom(); updateLayerVisibility(initialZoom); - // 绑定缩放变化事件 map.getView().on('change:resolution', function() { var zoom = map.getView().getZoom(); updateLayerVisibility(zoom); vectorLayer.changed(); }); - // 绑定鼠标事件 bindMouseEvents(); - // 设置地图中心点 if (deviceList && deviceList.length > 0) { setCenterFromDevices(deviceList); } - // 添加设备标记 DeviceMarkers.addDeviceMarkers(deviceList); - // 获取我的位置并开始位置更新 DeviceMarkers.getMyLocation(); DeviceMarkers.startLocationUpdates(); - // 设置初始开关状态 document.getElementById('showDeviceIdSwitch').checked = showDeviceId; document.getElementById('showClusterSwitch').checked = showCluster; } - /** - * 更新图层可见性 - * @param {number} zoom - 缩放级别 - */ function updateLayerVisibility(zoom) { if (showCluster) { if (zoom >= maxZoomForClustering) { @@ -137,11 +118,7 @@ var MapCore = (function() { } } - /** - * 绑定鼠标事件 - */ function bindMouseEvents() { - // 鼠标移动事件 map.on('pointermove', function(evt) { if (evt.dragging) { return; @@ -152,7 +129,6 @@ var MapCore = (function() { map.getTargetElement().style.cursor = hit ? 'pointer' : ''; - // 处理悬停效果 var feature = map.forEachFeatureAtPixel(pixel, function(feature) { return feature; }); @@ -176,7 +152,6 @@ var MapCore = (function() { vectorLayer.changed(); }); - // 点击事件 map.on('click', function(evt) { var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { return feature; @@ -202,7 +177,6 @@ var MapCore = (function() { } } } else if (feature.get('deviceInfo')) { - // 直接点击设备标记 var deviceInfo = feature.get('deviceInfo'); showDeviceInfo(deviceInfo); // 如果天气预测开启,显示天气卡片 @@ -214,64 +188,53 @@ var MapCore = (function() { }); } - /** - * 显示设备信息 - * @param {Object} deviceInfo - 设备信息 - */ + function showDeviceInfo(deviceInfo) { - var infoMsg = '
' + - '

设备编号: ' + deviceInfo.deviceid + '

' + - '

坐标: ' + deviceInfo.latitude.toFixed(6) + ', ' + deviceInfo.longitude.toFixed(6) + '

'; + var statusText = ''; if (deviceInfo.warning === 2) { - infoMsg += '

状态: 严重告警

'; + statusText = '严重告警'; } else if (deviceInfo.warning === 1) { - infoMsg += '

状态: 一般告警

'; + statusText = '一般告警'; } else { - infoMsg += '

状态: 正常

'; + statusText = '正常'; } - infoMsg += '
'; + var infoMsg = ' 设备: ' + deviceInfo.deviceid + + ' | 状态: ' + statusText + + ' | 坐标: ' + deviceInfo.latitude.toFixed(4) + ', ' + deviceInfo.longitude.toFixed(4); - if (window.layer && typeof window.layer.open === 'function') { - window.layer.open({ - type: 1, - title: '设备信息', - area: ['300px', 'auto'], - shade: 0, - offset: 'auto', - content: infoMsg, + if (window.layer && typeof window.layer.msg === 'function') { + window.layer.msg(infoMsg, { time: 3000, - anim: 2 + area: ['auto', 'auto'], + offset: 'auto' }); } } - /** - * 根据设备列表设置地图中心点 - * @param {Array} deviceList - 设备列表 - */ function setCenterFromDevices(deviceList) { if (!deviceList || deviceList.length === 0) return; - var centerLat = 0; - var centerLon = 0; - - for (var i = 0; i < deviceList.length; i++) { - centerLat += deviceList[i].latitude; - centerLon += deviceList[i].longitude; + var minLat = deviceList[0].latitude; + var maxLat = deviceList[0].latitude; + var minLon = deviceList[0].longitude; + var maxLon = deviceList[0].longitude; + + for (var i = 1; i < deviceList.length; i++) { + var device = deviceList[i]; + minLat = Math.min(minLat, device.latitude); + maxLat = Math.max(maxLat, device.latitude); + minLon = Math.min(minLon, device.longitude); + maxLon = Math.max(maxLon, device.longitude); } - - centerLat = centerLat / deviceList.length; - centerLon = centerLon / deviceList.length; - + + var centerLat = (minLat + maxLat) / 2; + var centerLon = (minLon + maxLon) / 2; + map.getView().setCenter(ol.proj.fromLonLat([centerLon, centerLat])); } - - /** - * 切换地图类型 - * @param {string} mapType - 地图类型 - */ + function switchMapType(mapType) { if (!MapLayers.hasLayer(mapType)) { console.error('未知的地图类型:', mapType); @@ -289,9 +252,6 @@ var MapCore = (function() { DeviceMarkers.addDeviceMarkers(deviceList); } - /** - * 切换设备ID显示 - */ function toggleDeviceId() { showDeviceId = document.getElementById('showDeviceIdSwitch').checked; DeviceMarkers.setShowDeviceId(showDeviceId); @@ -301,9 +261,6 @@ var MapCore = (function() { } } - /** - * 切换集群显示 - */ function toggleCluster() { showCluster = document.getElementById('showClusterSwitch').checked; var zoom = map.getView().getZoom(); @@ -314,9 +271,6 @@ var MapCore = (function() { } } - /** - * 切换地图功能菜单 - */ function toggleMapFunctionsMenu() { var menu = document.getElementById('mapFunctionsMenu'); if (menu) { @@ -349,62 +303,47 @@ var MapCore = (function() { switchMapType(mapType); } - /** - * 告警过滤变化处理 - */ function onWarningFilterChange() { var filterValue = document.getElementById('warningFilter').value; - - if (filterValue === 'all') { - SearchFilter.showAllDevices(); - } else if (filterValue === 'warning1') { - SearchFilter.showWarning1Devices(); - } else if (filterValue === 'warning2') { - SearchFilter.showWarning2Devices(); + switch(filterValue) { + case 'all': + SearchFilter.showAllDevices(); + break; + case 'warning1': + SearchFilter.showWarning1Devices(); + break; + case 'warning2': + SearchFilter.showWarning2Devices(); + break; } } - /** - * 搜索设备 - */ function searchDeviceNew() { - var deviceId = document.getElementById('deviceSearchNew').value.trim(); - - if (!deviceId) { - if (window.layer && typeof window.layer.msg === 'function') { - window.layer.msg('请输入设备编号'); + var searchInput = document.getElementById('deviceSearchNew'); + if (searchInput) { + var deviceId = searchInput.value.trim(); + if (deviceId) { + SearchFilter.searchDevice(deviceId); + } else { + if (window.layer && typeof window.layer.msg === 'function') { + window.layer.msg('请输入设备编号'); + } } - return; } - - SearchFilter.searchDevice(deviceId); } - /** - * 获取地图实例 - * @returns {ol.Map} 地图实例 - */ function getMap() { return map; } - - /** - * 获取矢量数据源 - * @returns {ol.source.Vector} 矢量数据源 - */ + function getVectorSource() { return vectorSource; } - /** - * 获取矢量图层 - * @returns {ol.layer.Vector} 矢量图层 - */ function getVectorLayer() { return vectorLayer; } - // 公开API return { initialize: initialize, switchMapType: switchMapType, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/map-layers.js b/sec-beidou/src/main/resources/static/js/device-overview-module/map-layers.js index e97161af..7dc97537 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/map-layers.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/map-layers.js @@ -5,12 +5,9 @@ var MapLayers = (function() { 'use strict'; - // 天地图 API 密钥 + // 天地图 API 密钥 (fengyarnom@gmail.com) var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac'; - /** - * 创建天地图瓦片加载函数,包含错误处理 - */ function createTiandituTileLoadFunction() { return function(imageTile, src) { imageTile.getImage().src = src; @@ -25,7 +22,6 @@ var MapLayers = (function() { if (window.layer && typeof window.layer.msg === 'function') { window.layer.msg('天地图加载失败,已自动切换到高德地图'); } - // 重新渲染layui表单 if (window.layui && window.layui.form) { window.layui.form.render('select'); } @@ -34,9 +30,7 @@ var MapLayers = (function() { }; } - /** - * 地图图层配置 - */ + var mapLayers = { // 高德地图 amap: new ol.layer.Tile({ @@ -160,33 +154,23 @@ var MapLayers = (function() { }) }; - /** - * 获取指定类型的地图图层 - * @param {string} mapType - 地图类型 - * @returns {ol.layer.Base} 地图图层 - */ + function getLayer(mapType) { return mapLayers[mapType]; } - /** - * 获取所有可用的地图图层 - * @returns {Object} 所有地图图层对象 - */ + + function getAllLayers() { return mapLayers; } - /** - * 检查地图类型是否存在 - * @param {string} mapType - 地图类型 - * @returns {boolean} 是否存在 - */ + function hasLayer(mapType) { return mapLayers.hasOwnProperty(mapType); } - // 公开API + return { getLayer: getLayer, getAllLayers: getAllLayers, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/measure-tools.js b/sec-beidou/src/main/resources/static/js/device-overview-module/measure-tools.js index 48d224d5..5a9c8fbc 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/measure-tools.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/measure-tools.js @@ -5,7 +5,6 @@ var MeasureTools = (function() { 'use strict'; - // 私有变量 var measureActive = false; var measureDraw = null; var measureSource = null; @@ -18,14 +17,10 @@ var MeasureTools = (function() { var segmentTooltips = []; var map = null; - /** - * 初始化测距工具 - * @param {ol.Map} mapInstance - 地图实例 - */ function init(mapInstance) { map = mapInstance; - // 创建测距专用图层 + // 测距专用图层 measureSource = new ol.source.Vector(); measureLayer = new ol.layer.Vector({ source: measureSource, @@ -47,9 +42,6 @@ var MeasureTools = (function() { } } - /** - * 切换测距功能 - */ function toggleMeasureDistance() { if (measureActive) { deactivateMeasure(); @@ -63,25 +55,18 @@ var MeasureTools = (function() { } } - // 关闭地图功能菜单 var menu = document.getElementById('mapFunctionsMenu'); if (menu) { menu.classList.remove('show'); } } - /** - * 完成当前测量 - */ function finishMeasuring() { if (measureActive && currentSketch && measureDraw) { measureDraw.finishDrawing(); } } - /** - * 激活测距功能 - */ function activateMeasure() { if (!map || !measureSource) return; @@ -93,7 +78,6 @@ var MeasureTools = (function() { measureStatus.style.display = 'flex'; } - // 创建绘制交互 measureDraw = new ol.interaction.Draw({ source: measureSource, type: 'LineString', @@ -112,7 +96,6 @@ var MeasureTools = (function() { map.addInteraction(measureDraw); - // 添加右键菜单事件监听 map.getViewport().addEventListener('contextmenu', function(e) { if (measureActive && currentSketch) { e.preventDefault(); @@ -120,13 +103,11 @@ var MeasureTools = (function() { } }); - // 绘制开始事件 measureDraw.on('drawstart', function(evt) { currentSketch = evt.feature; currentMeasureTooltips = []; segmentTooltips = []; - // 监听几何变化 currentListener = currentSketch.getGeometry().on('change', function(e) { var geom = e.target; var coords = geom.getCoordinates(); @@ -160,14 +141,13 @@ var MeasureTools = (function() { }); }); - // 绘制结束事件 + // 绘制结束 measureDraw.on('drawend', function(evt) { var coords = evt.feature.getGeometry().getCoordinates(); clearTemporaryTooltips(); clearSegmentTooltips(); - // 创建永久性的测量标记 var total = 0; for (var i = 0; i < coords.length; i++) { if (i === 0) { @@ -185,20 +165,17 @@ var MeasureTools = (function() { measureFeatures.push(evt.feature); - // 清理监听器 if (currentListener) { ol.Observable.unByKey(currentListener); } currentSketch = null; currentListener = null; - // 隐藏测量状态指示器 var measureStatus = document.getElementById('measureStatus'); if (measureStatus) { measureStatus.style.display = 'none'; } - // 移除绘制交互 map.removeInteraction(measureDraw); measureActive = false; @@ -208,13 +185,9 @@ var MeasureTools = (function() { }); } - /** - * 停用测距功能 - */ function deactivateMeasure() { measureActive = false; - // 隐藏测量状态指示器 var measureStatus = document.getElementById('measureStatus'); if (measureStatus) { measureStatus.style.display = 'none'; @@ -235,13 +208,6 @@ var MeasureTools = (function() { clearSegmentTooltips(); } - /** - * 创建测量提示框 - * @param {Array} coord - 坐标 - * @param {string} text - 显示文本 - * @param {boolean} isStatic - 是否为静态提示框 - * @returns {ol.Overlay} 覆盖层对象 - */ function createMeasureTooltip(coord, text, isStatic) { var elem = document.createElement('div'); elem.className = isStatic ? 'ol-tooltip ol-tooltip-static' : 'ol-tooltip ol-tooltip-measure'; @@ -262,11 +228,6 @@ var MeasureTools = (function() { return overlay; } - /** - * 格式化长度显示 - * @param {number} length - 长度(米) - * @returns {string} 格式化后的长度字符串 - */ function formatLength(length) { if (length > 1000) { return (Math.round(length / 100) / 10) + ' km'; @@ -275,9 +236,6 @@ var MeasureTools = (function() { } } - /** - * 清除所有测量提示框 - */ function clearAllMeasureTooltips() { if (!map) return; @@ -289,9 +247,6 @@ var MeasureTools = (function() { clearTemporaryTooltips(); } - /** - * 清除临时提示框 - */ function clearTemporaryTooltips() { if (!map) return; @@ -301,9 +256,6 @@ var MeasureTools = (function() { currentMeasureTooltips = []; } - /** - * 清除段落提示框 - */ function clearSegmentTooltips() { if (!map) return; @@ -313,9 +265,6 @@ var MeasureTools = (function() { segmentTooltips = []; } - /** - * 清除所有测量标记 - */ function clearMeasure() { if (measureSource) { measureSource.clear(); @@ -335,23 +284,14 @@ var MeasureTools = (function() { } } - /** - * 检查测距功能是否激活 - * @returns {boolean} 是否激活 - */ function isActive() { return measureActive; } - /** - * 获取测量结果数量 - * @returns {number} 测量结果数量 - */ function getMeasureCount() { return measureFeatures.length; } - // 公开API return { init: init, toggleMeasureDistance: toggleMeasureDistance, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/search-filter.js b/sec-beidou/src/main/resources/static/js/device-overview-module/search-filter.js index a0cd12fe..235ea94d 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/search-filter.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/search-filter.js @@ -5,15 +5,9 @@ var SearchFilter = (function() { 'use strict'; - // 私有变量 var currentSearchedDevice = null; var markerState = 3; // 1:all; 2:orange; 3:red - /** - * 搜索设备 - * @param {string} deviceId - 设备ID - * @returns {boolean} 是否找到设备 - */ function searchDevice(deviceId) { if (!deviceId || !deviceId.trim()) { clearSearch(); @@ -47,9 +41,6 @@ var SearchFilter = (function() { return success; } - /** - * 清除搜索 - */ function clearSearch() { currentSearchedDevice = null; var searchInput = document.getElementById('deviceSearchNew'); @@ -61,9 +52,6 @@ var SearchFilter = (function() { applyCurrentFilter(); } - /** - * 应用当前过滤状态 - */ function applyCurrentFilter() { switch(markerState) { case 1: @@ -78,9 +66,6 @@ var SearchFilter = (function() { } } - /** - * 显示所有设备 - */ function showAllDevices() { currentSearchedDevice = null; clearSearchInput(); @@ -89,9 +74,6 @@ var SearchFilter = (function() { updateFilterSelect('all'); } - /** - * 显示一般告警设备 - */ function showWarning1Devices() { currentSearchedDevice = null; clearSearchInput(); @@ -99,10 +81,6 @@ var SearchFilter = (function() { markerState = 2; updateFilterSelect('warning1'); } - - /** - * 显示严重告警设备 - */ function showWarning2Devices() { currentSearchedDevice = null; clearSearchInput(); @@ -110,10 +88,6 @@ var SearchFilter = (function() { markerState = 3; updateFilterSelect('warning2'); } - - /** - * 清除搜索输入框 - */ function clearSearchInput() { var searchInput = document.getElementById('deviceSearchNew'); if (searchInput) { @@ -121,10 +95,6 @@ var SearchFilter = (function() { } } - /** - * 更新过滤选择器 - * @param {string} filterValue - 过滤值 - */ function updateFilterSelect(filterValue) { var filterSelect = document.getElementById('warningFilter'); if (filterSelect) { @@ -132,10 +102,6 @@ var SearchFilter = (function() { } } - /** - * 根据状态过滤设备 - * @param {string} statusType - 状态类型 - */ function filterDevicesByStatus(statusType) { switch(statusType) { case 'warning1': @@ -157,12 +123,7 @@ var SearchFilter = (function() { } } - /** - * 查询设备并打开列表页面 - * @param {string} statusType - 状态类型 - */ function queryDevices(statusType) { - // 首先过滤地图上的设备显示 filterDevicesByStatus(statusType); // 打开设备列表弹窗 @@ -181,12 +142,6 @@ var SearchFilter = (function() { } } - /** - * 直接定位到设备(用于外部调用) - * @param {string} deviceId - 设备ID - * @param {number} latitude - 纬度(可选) - * @param {number} longitude - 经度(可选) - */ function locateDeviceOnMap(deviceId, latitude, longitude) { currentSearchedDevice = deviceId; var success = DeviceMarkers.locateDevice(deviceId); @@ -198,40 +153,23 @@ var SearchFilter = (function() { return success; } - /** - * 直接定位设备(简化版) - * @param {string} deviceId - 设备ID - */ function locateDeviceDirectly(deviceId) { currentSearchedDevice = deviceId; return DeviceMarkers.locateDevice(deviceId); } - /** - * 获取当前搜索的设备ID - * @returns {string|null} 当前搜索的设备ID - */ function getCurrentSearchedDevice() { return currentSearchedDevice; } - /** - * 获取当前标记状态 - * @returns {number} 标记状态 - */ function getMarkerState() { return markerState; } - /** - * 设置标记状态 - * @param {number} state - 标记状态 - */ function setMarkerState(state) { markerState = state; } - // 公开API return { searchDevice: searchDevice, clearSearch: clearSearch, diff --git a/sec-beidou/src/main/resources/static/js/device-overview-module/weather-forecast.js b/sec-beidou/src/main/resources/static/js/device-overview-module/weather-forecast.js index 57fde0d6..e9cf8d2a 100644 --- a/sec-beidou/src/main/resources/static/js/device-overview-module/weather-forecast.js +++ b/sec-beidou/src/main/resources/static/js/device-overview-module/weather-forecast.js @@ -1,31 +1,18 @@ -/** - * 天气预报模块 - * 提供Windy天气API调用和天气卡片显示功能 - */ var WeatherForecast = (function() { 'use strict'; - // 私有变量 var weatherApiKey = 'Uxh4IdMuAvhSiBnsf4UUDVGF4e3YAp2B'; var weatherEnabled = false; var weatherData = null; var currentForecastIndex = 0; var currentWeatherDevice = null; - var isDragging = false; - /** - * 初始化天气预报模块 - */ function init() { - initWeatherCardDrag(); + // 天气预报模块初始化完成 } - /** - * 切换天气预报功能 - */ function toggleWeatherForecast() { - // 权限检查 - var role = window.userRole || 'USER'; // 从全局变量获取角色 + var role = window.userRole || 'USER'; if (role !== 'SUPER_ADMIN') { if (window.layer && typeof window.layer.msg === 'function') { window.layer.msg('您没有权限使用此功能'); @@ -50,22 +37,16 @@ var WeatherForecast = (function() { closeWeatherCard(); } - // 关闭地图功能菜单 var menu = document.getElementById('mapFunctionsMenu'); if (menu) { menu.classList.remove('show'); } } - /** - * 显示天气预报卡片 - * @param {Object} deviceInfo - 设备信息 - */ function showWeatherForecast(deviceInfo) { currentWeatherDevice = deviceInfo; weatherData = null; - // 权限检查 var role = window.userRole || 'USER'; if (role !== 'SUPER_ADMIN') { return; @@ -78,7 +59,6 @@ var WeatherForecast = (function() { return; } - // 更新设备信息显示 var deviceIdElement = document.getElementById('weatherDeviceId'); var deviceCoordsElement = document.getElementById('weatherDeviceCoords'); @@ -91,15 +71,11 @@ var WeatherForecast = (function() { '坐标: ' + deviceInfo.latitude.toFixed(4) + ', ' + deviceInfo.longitude.toFixed(4); } - // 显示天气卡片 var weatherCard = document.getElementById('weatherForecastCard'); if (weatherCard) { weatherCard.style.display = 'block'; } - - initWeatherCardDrag(); - // 显示加载状态 var contentElement = document.getElementById('weatherForecastContent'); if (contentElement) { contentElement.innerHTML = @@ -110,7 +86,6 @@ var WeatherForecast = (function() { ''; } - // 重置翻页按钮 var prevBtn = document.getElementById('prevForecast'); var nextBtn = document.getElementById('nextForecast'); var timeDisplay = document.getElementById('forecastTimeDisplay'); @@ -119,13 +94,9 @@ var WeatherForecast = (function() { if (nextBtn) nextBtn.disabled = true; if (timeDisplay) timeDisplay.textContent = '--:--'; - // 调用天气API fetchWeatherData(deviceInfo.latitude, deviceInfo.longitude); } - /** - * 关闭天气卡片 - */ function closeWeatherCard() { var weatherCard = document.getElementById('weatherForecastCard'); if (weatherCard) { @@ -135,9 +106,6 @@ var WeatherForecast = (function() { weatherData = null; } - /** - * 显示上一个预报 - */ function showPrevForecast() { if (!weatherData || currentForecastIndex <= 0) return; @@ -146,9 +114,6 @@ var WeatherForecast = (function() { updateForecastNavigation(); } - /** - * 显示下一个预报 - */ function showNextForecast() { if (!weatherData || !weatherData.ts || currentForecastIndex >= weatherData.ts.length - 1) return; @@ -157,9 +122,6 @@ var WeatherForecast = (function() { updateForecastNavigation(); } - /** - * 更新预报导航按钮 - */ function updateForecastNavigation() { if (!weatherData || !weatherData.ts) return; @@ -177,20 +139,15 @@ var WeatherForecast = (function() { } } - /** - * 获取天气数据 - * @param {number} lat - 纬度 - * @param {number} lon - 经度 - */ function fetchWeatherData(lat, lon) { var requestBody = { "lat": parseFloat(lat.toFixed(2)), "lon": parseFloat(lon.toFixed(2)), - "model": "gfs", // 使用全球预报系统模型 + "model": "gfs", "parameters": ["temp", "wind", "precip", "pressure", "rh", "windGust"], "levels": ["surface"], "key": weatherApiKey, - "hours": 72 // 请求未来72小时的预报数据 + "hours": 72 }; fetch('https://api.windy.com/api/point-forecast/v2', { @@ -210,13 +167,11 @@ var WeatherForecast = (function() { .then(function(data) { weatherData = data; - // 找到最接近当前时间的预报索引,优先选择未来时间点 var currentTime = new Date().getTime(); var closestIndex = 0; var futureIndex = -1; if (weatherData.ts && weatherData.ts.length > 0) { - // 首先尝试找到第一个未来时间点 for (var i = 0; i < weatherData.ts.length; i++) { if (weatherData.ts[i] > currentTime) { futureIndex = i; @@ -224,11 +179,9 @@ var WeatherForecast = (function() { } } - // 如果找到了未来时间点,直接使用 if (futureIndex >= 0) { closestIndex = futureIndex; } else { - // 否则找最接近的时间点 var smallestDiff = Number.MAX_VALUE; for (var i = 0; i < weatherData.ts.length; i++) { var diff = Math.abs(weatherData.ts[i] - currentTime); @@ -250,9 +203,6 @@ var WeatherForecast = (function() { }); } - /** - * 显示当前预报 - */ function displayCurrentForecast() { if (!weatherData || !weatherData.ts || weatherData.ts.length === 0) { displayWeatherError('无可用的天气预测数据'); @@ -262,13 +212,11 @@ var WeatherForecast = (function() { var i = currentForecastIndex; var forecastHtml = '
'; - // 温度 if (weatherData['temp-surface'] && weatherData['temp-surface'][i] !== null) { - var temp = (weatherData['temp-surface'][i] - 273.15).toFixed(1); // 转换为摄氏度 + var temp = (weatherData['temp-surface'][i] - 273.15).toFixed(1); forecastHtml += createWeatherParam('温度', temp + '°C'); } - // 风速和风向 if (weatherData['wind_u-surface'] && weatherData['wind_v-surface'] && weatherData['wind_u-surface'][i] !== null && weatherData['wind_v-surface'][i] !== null) { var windU = weatherData['wind_u-surface'][i]; @@ -279,25 +227,21 @@ var WeatherForecast = (function() { forecastHtml += createWeatherParam('风向', windDir); } - // 降水 if (weatherData['past3hprecip-surface'] && weatherData['past3hprecip-surface'][i] !== null) { var precip = weatherData['past3hprecip-surface'][i].toFixed(1); forecastHtml += createWeatherParam('降水', precip + ' mm'); } - // 湿度 if (weatherData['rh-surface'] && weatherData['rh-surface'][i] !== null) { var humidity = weatherData['rh-surface'][i].toFixed(0); forecastHtml += createWeatherParam('湿度', humidity + '%'); } - // 气压 if (weatherData['pressure-surface'] && weatherData['pressure-surface'][i] !== null) { - var pressure = (weatherData['pressure-surface'][i] / 100).toFixed(0); // 转换为百帕 + var pressure = (weatherData['pressure-surface'][i] / 100).toFixed(0); forecastHtml += createWeatherParam('气压', pressure + ' hPa'); } - // 阵风 if (weatherData['gust-surface'] && weatherData['gust-surface'][i] !== null) { var gust = weatherData['gust-surface'][i].toFixed(1); forecastHtml += createWeatherParam('阵风', gust + ' m/s'); @@ -311,10 +255,6 @@ var WeatherForecast = (function() { } } - /** - * 显示天气错误信息 - * @param {string} message - 错误消息 - */ function displayWeatherError(message) { var contentElement = document.getElementById('weatherForecastContent'); if (contentElement) { @@ -326,12 +266,6 @@ var WeatherForecast = (function() { } } - /** - * 创建天气参数HTML - * @param {string} label - 参数标签 - * @param {string} value - 参数值 - * @returns {string} HTML字符串 - */ function createWeatherParam(label, value) { return '
' + '' + label + '' + @@ -339,11 +273,6 @@ var WeatherForecast = (function() { '
'; } - /** - * 格式化日期时间 - * @param {Date} date - 日期对象 - * @returns {string} 格式化后的日期时间字符串 - */ function formatDateTime(date) { var month = (date.getMonth() + 1).toString().padStart(2, '0'); var day = date.getDate().toString().padStart(2, '0'); @@ -353,12 +282,6 @@ var WeatherForecast = (function() { return month + '-' + day + ' ' + hours + ':' + minutes; } - /** - * 获取风向 - * @param {number} u - U分量 - * @param {number} v - V分量 - * @returns {string} 风向字符串 - */ function getWindDirection(u, v) { var angle = Math.atan2(-u, -v) * 180 / Math.PI; angle = (angle + 360) % 360; @@ -367,140 +290,11 @@ var WeatherForecast = (function() { var index = Math.round(angle / 45) % 8; return directions[index]; } - - /** - * 初始化天气卡片拖拽功能 - */ - function initWeatherCardDrag() { - var weatherCard = document.getElementById('weatherForecastCard'); - if (!weatherCard) return; - - var startX, startY; - var startLeft, startTop; - - var originalStyles = { - top: '55%', - right: '20px', - left: 'auto', - transform: 'translateY(-50%)' - }; - - var cardHeader = weatherCard.querySelector('.weather-card-header'); - if (!cardHeader) return; - - // 双击重置位置 - cardHeader.addEventListener('dblclick', function() { - weatherCard.style.top = originalStyles.top; - weatherCard.style.right = originalStyles.right; - weatherCard.style.left = originalStyles.left; - weatherCard.style.transform = originalStyles.transform; - }); - - // 鼠标拖拽 - cardHeader.addEventListener('mousedown', function(e) { - if (e.target.tagName === 'BUTTON' || - e.target.classList.contains('weather-nav-btn') || - e.target.classList.contains('weather-close-btn')) { - return; - } - - e.preventDefault(); - startDrag(e.clientX, e.clientY); - }); - - // 触摸拖拽 - cardHeader.addEventListener('touchstart', function(e) { - if (e.target.tagName === 'BUTTON' || - e.target.classList.contains('weather-nav-btn') || - e.target.classList.contains('weather-close-btn')) { - return; - } - - e.preventDefault(); - var touch = e.touches[0]; - startDrag(touch.clientX, touch.clientY); - }); - - function startDrag(clientX, clientY) { - startX = clientX; - startY = clientY; - - var rect = weatherCard.getBoundingClientRect(); - startLeft = rect.left; - startTop = rect.top; - - isDragging = true; - - // 设置为绝对定位 - if (getComputedStyle(weatherCard).position !== 'absolute') { - weatherCard.style.position = 'absolute'; - weatherCard.style.top = rect.top + 'px'; - weatherCard.style.left = rect.left + 'px'; - weatherCard.style.right = 'auto'; - weatherCard.style.transform = 'none'; - } - - weatherCard.style.opacity = '0.9'; - weatherCard.style.boxShadow = '0 12px 48px rgba(0, 0, 0, 0.25)'; - weatherCard.style.zIndex = '1200'; - document.body.style.userSelect = 'none'; - } - - // 鼠标移动事件 - document.addEventListener('mousemove', function(e) { - if (!isDragging) return; - moveDrag(e.clientX, e.clientY); - }); - - // 触摸移动事件 - document.addEventListener('touchmove', function(e) { - if (!isDragging) return; - e.preventDefault(); - var touch = e.touches[0]; - moveDrag(touch.clientX, touch.clientY); - }); - - function moveDrag(clientX, clientY) { - var dx = clientX - startX; - var dy = clientY - startY; - - var newLeft = startLeft + dx; - var newTop = startTop + dy; - - // 限制在视口内 - var maxX = window.innerWidth - weatherCard.offsetWidth; - var maxY = window.innerHeight - weatherCard.offsetHeight; - - newLeft = Math.max(0, Math.min(newLeft, maxX)); - newTop = Math.max(0, Math.min(newTop, maxY)); - - weatherCard.style.left = newLeft + 'px'; - weatherCard.style.top = newTop + 'px'; - } - - // 结束拖拽 - document.addEventListener('mouseup', endDrag); - document.addEventListener('touchend', endDrag); - - function endDrag() { - if (!isDragging) return; - - isDragging = false; - weatherCard.style.opacity = '1'; - weatherCard.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.15)'; - document.body.style.userSelect = ''; - } - } - /** - * 检查天气功能是否启用 - * @returns {boolean} 是否启用 - */ function isEnabled() { return weatherEnabled; } - // 公开API return { init: init, toggleWeatherForecast: toggleWeatherForecast, diff --git a/sec-beidou/src/main/resources/static/js/device-overview.js b/sec-beidou/src/main/resources/static/js/device-overview.js deleted file mode 100644 index c6447ab7..00000000 --- a/sec-beidou/src/main/resources/static/js/device-overview.js +++ /dev/null @@ -1,755 +0,0 @@ -(function() { - var map, vectorSource, vectorLayer, currentBaseLayer; - var greenFeatures = [], orangeFeatures = [], redFeatures = [], allFeatures = []; - var marker_state = 3, currentSearchedDevice = null, myLocationFeature = null, myLocationInterval; - var clusterSource, clusterLayer, showDeviceId = true, showCluster = true; - var minZoomForLabels = 4, maxZoomForClustering = 8; - var measureDraw, measureLayer, measureSource, measureTooltipElement, measureTooltip, sketch; - - // 天地图的Key - var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac'; - // 设备列表 - var deviceList = window.deviceList || []; - var pi = 3.14159265358979324, a = 6378245.0, ee = 0.00669342162296594323; - - // 判断是否超出中国,如果超出那么就不用转换坐标了 - function outOfChina(lon, lat) { - return (lon < 72.004 || lon > 137.8347) && (lat < 0.8293 || lat > 55.8271); - } - - function transformLat(x, y) { - var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); - ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; - ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; - ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; - return ret; - } - - function transformLon(x, y) { - var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); - ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; - ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; - ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0; - return ret; - } - - function transform(wgLat, wgLon) { - var mars_point = { lon: 0, lat: 0 }; - if (outOfChina(wgLon, wgLat)) { - mars_point.lat = wgLat; - mars_point.lon = wgLon; - return mars_point; - } - var dLat = transformLat(wgLon - 105.0, wgLat - 35.0); - var dLon = transformLon(wgLon - 105.0, wgLat - 35.0); - var radLat = wgLat / 180.0 * pi; - var magic = Math.sin(radLat); - magic = 1 - ee * magic * magic; - var sqrtMagic = Math.sqrt(magic); - dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); - dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); - mars_point.lat = wgLat + dLat; - mars_point.lon = wgLon + dLon; - return mars_point; - } - - var mapLayers = { - amap: new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}' - }) - }), - amap_satellite: new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}' - }) - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}' - }) - }) - ] - }), - tianditu_satellite: new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }) - ] - }), - tianditu_normal: new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }) - ] - }), - tianditu_terrain: new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }) - ] - }), - tianditu_terrain_hybrid: new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - url: 'https://t{0-7}.tianditu.gov.cn/cta_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + TIANDITU_KEY, - tileLoadFunction: tileLoadErrorHandler - }) - }) - ] - }) - }; - - function tileLoadErrorHandler(imageTile, src) { - imageTile.getImage().src = src; - imageTile.getImage().onerror = function() { - var mapTypeSelect = document.getElementById('mapTypeSelect'); - if (mapTypeSelect.value.startsWith('tianditu_')) { - mapTypeSelect.value = 'amap'; - switchMapType('amap'); - layer.msg('天地图加载失败,已自动切换到高德地图'); - layui.form.render('select'); - } - }; - } - - 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, 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 }) - }); - - 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; - } - }); - - measureSource = new ol.source.Vector(); - measureLayer = new ol.layer.Vector({ - source: measureSource, - style: new ol.style.Style({ - fill: new ol.style.Fill({ color: 'rgba(255,255,255,0.2)' }), - stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 }), - image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: '#ffcc33' }) }) - }) - }); - - 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; - return 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' }) }) - }); - } - }); - - var initialMapType = document.getElementById('mapTypeSelect').value; - currentBaseLayer = mapLayers[initialMapType]; - - map = new ol.Map({ - target: 'map-container', - layers: [currentBaseLayer, measureLayer, clusterLayer, vectorLayer], - view: new ol.View({ center: ol.proj.fromLonLat([116.404, 39.915]), zoom: 7 }) - }); - - var scaleLineControl = new ol.control.ScaleLine({ units: 'metric', bar: true, steps: 4, text: true, minWidth: 140 }); - map.addControl(scaleLineControl); - - function updateMapSize() { - map.updateSize(); - } - - setTimeout(updateMapSize, 200); - window.addEventListener('resize', function() { - setTimeout(updateMapSize, 200); - }); - window.addEventListener('load', function() { - setTimeout(updateMapSize, 500); - }); - - var measureDistanceBtn = document.getElementById('measure-distance'); - var clearMeasureBtn = document.getElementById('clear-measure'); - - measureDistanceBtn.addEventListener('click', function() { - this.classList.toggle('active'); - if (this.classList.contains('active')) { - addMeasureInteraction(); - document.getElementById('clear-measure').classList.remove('active'); - layer.msg('双击以结束测量'); - } else { - map.removeInteraction(measureDraw); - measureSource.clear(); - if (measureTooltipElement) measureTooltipElement.parentNode.removeChild(measureTooltipElement); - } - }); - - clearMeasureBtn.addEventListener('click', function() { - measureSource.clear(); - if (measureTooltipElement) measureTooltipElement.parentNode.removeChild(measureTooltipElement); - var overlays = map.getOverlays().getArray(); - var measureOverlays = overlays.filter(function(overlay) { - return overlay.getElement() && overlay.getElement().className && overlay.getElement().className.indexOf('ol-tooltip') !== -1; - }); - measureOverlays.forEach(function(overlay) { - map.removeOverlay(overlay); - }); - measureTooltipElement = null; - measureDistanceBtn.classList.remove('active'); - this.classList.add('active'); - setTimeout(function() { - document.getElementById('clear-measure').classList.remove('active'); - }, 300); - map.removeInteraction(measureDraw); - }); - - 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, centerLon = 0; - for (var i = 0; i < deviceList.length; i++) { - centerLat += deviceList[i].latitude; - centerLon += deviceList[i].longitude; - } - centerLat = centerLat / deviceList.length; - centerLon = centerLon / deviceList.length; - map.getView().setCenter(ol.proj.fromLonLat([centerLon, centerLat])); - } - - addDeviceMarkers(); - myLocation(); - startLocationUpdates(); - } - - function switchMapType(mapType) { - map.removeLayer(currentBaseLayer); - currentBaseLayer = mapLayers[mapType]; - map.getLayers().insertAt(0, currentBaseLayer); - updateMyLocationForMapType(mapType); - addDeviceMarkers(); - } - - function updateMyLocationForMapType(mapType) { - if (myLocationFeature) { - var originalCoords = myLocationFeature.get('originalCoords'); - if (originalCoords) { - var lat = originalCoords.lat, lon = originalCoords.lon, coordinates; - if (mapType === 'amap' || mapType === 'amap_satellite') { - var gcjCoord = transform(lat, lon); - coordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); - } else { - coordinates = ol.proj.fromLonLat([lon, lat]); - } - myLocationFeature.getGeometry().setCoordinates(coordinates); - } - } - } - - function addDeviceMarkers() { - var savedMyLocationFeature = myLocationFeature; - vectorSource.clear(); - greenFeatures = []; - orangeFeatures = []; - redFeatures = []; - allFeatures = []; - - for (var i = 0; i < deviceList.length; i++) { - var device = deviceList[i]; - var mapCoordinates; - var currentMapType = document.getElementById('mapTypeSelect').value; - if (currentMapType === 'amap' || currentMapType === 'amap_satellite') { - var gcjCoord = transform(device.latitude, device.longitude); - mapCoordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); - } else { - mapCoordinates = ol.proj.fromLonLat([device.longitude, device.latitude]); - } - - var feature = new ol.Feature({ - geometry: new ol.geom.Point(mapCoordinates), - deviceInfo: device - }); - - if (device.warning == 2) redFeatures.push(feature); - else if (device.warning == 1) orangeFeatures.push(feature); - else greenFeatures.push(feature); - - allFeatures.push(feature); - vectorSource.addFeature(feature); - } - - if (savedMyLocationFeature) vectorSource.addFeature(savedMyLocationFeature); - - if (currentSearchedDevice) { - filterByDeviceId(currentSearchedDevice); - } else { - if (marker_state === 2) { - hideGreen(); - hideRed(); - } else if (marker_state === 3) { - hideGreen(); - hideOrange(); - } - } - vectorLayer.changed(); - } - - function myLocation() { - if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(function(position) { - var lon = position.coords.longitude; - var lat = position.coords.latitude; - var currentMapType = document.getElementById('mapTypeSelect').value; - var coordinates; - - if (currentMapType === 'amap' || currentMapType === 'amap_satellite') { - var gcjCoord = transform(lat, lon); - coordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); - } else { - coordinates = ol.proj.fromLonLat([lon, lat]); - } - - if (myLocationFeature) { - vectorSource.removeFeature(myLocationFeature); - } - - myLocationFeature = new ol.Feature({ - geometry: new ol.geom.Point(coordinates), - isMyLocation: true, - originalCoords: { lat: lat, lon: lon } - }); - - var style = new ol.style.Style({ - image: new ol.style.Icon({ - anchor: [0.5, 1], - src: '../images/loc_blue.png', - scale: 0.7 - }) - }); - - myLocationFeature.setStyle(style); - vectorSource.addFeature(myLocationFeature); - map.getView().setCenter(coordinates); - }); - } - } - - function startLocationUpdates() { - if (myLocationInterval) { - clearInterval(myLocationInterval); - } - myLocationInterval = setInterval(function() { - myLocation(); - }, 10 * 60 * 1000); - } - - function showAll() { - document.getElementById('btn-all').classList.add('active'); - document.getElementById('btn-warning1').classList.remove('active'); - document.getElementById('btn-warning2').classList.remove('active'); - document.getElementById('btn-device-locate').classList.remove('active'); - document.getElementById('btn-device-locate').style.display = 'none'; - - currentSearchedDevice = null; - document.getElementById('deviceSearch').value = ''; - var savedMyLocationFeature = myLocationFeature; - vectorSource.clear(); - - if (savedMyLocationFeature) { - vectorSource.addFeature(savedMyLocationFeature); - } - for (var i = 0; i < allFeatures.length; i++) { - vectorSource.addFeature(allFeatures[i]); - } - marker_state = 1; - } - - function showWarning1() { - document.getElementById('btn-all').classList.remove('active'); - document.getElementById('btn-warning1').classList.add('active'); - document.getElementById('btn-warning2').classList.remove('active'); - document.getElementById('btn-device-locate').classList.remove('active'); - document.getElementById('btn-device-locate').style.display = 'none'; - - currentSearchedDevice = null; - document.getElementById('deviceSearch').value = ''; - var savedMyLocationFeature = myLocationFeature; - vectorSource.clear(); - - if (savedMyLocationFeature) { - vectorSource.addFeature(savedMyLocationFeature); - } - for (var i = 0; i < allFeatures.length; i++) { - vectorSource.addFeature(allFeatures[i]); - } - hideGreen(); - hideRed(); - marker_state = 2; - } - - function showWarning2() { - document.getElementById('btn-all').classList.remove('active'); - document.getElementById('btn-warning1').classList.remove('active'); - document.getElementById('btn-warning2').classList.add('active'); - document.getElementById('btn-device-locate').classList.remove('active'); - document.getElementById('btn-device-locate').style.display = 'none'; - - currentSearchedDevice = null; - document.getElementById('deviceSearch').value = ''; - var savedMyLocationFeature = myLocationFeature; - vectorSource.clear(); - - if (savedMyLocationFeature) { - vectorSource.addFeature(savedMyLocationFeature); - } - for (var i = 0; i < allFeatures.length; i++) { - vectorSource.addFeature(allFeatures[i]); - } - hideGreen(); - hideOrange(); - marker_state = 3; - } - - function showGreen() { - for (var i = 0; i < greenFeatures.length; i++) { - if (!vectorSource.hasFeature(greenFeatures[i])) { - vectorSource.addFeature(greenFeatures[i]); - } - } - } - - function showOrange() { - for (var i = 0; i < orangeFeatures.length; i++) { - if (!vectorSource.hasFeature(orangeFeatures[i])) { - vectorSource.addFeature(orangeFeatures[i]); - } - } - } - - function showRed() { - for (var i = 0; i < redFeatures.length; i++) { - if (!vectorSource.hasFeature(redFeatures[i])) { - vectorSource.addFeature(redFeatures[i]); - } - } - } - - function hideGreen() { - for (var i = 0; i < greenFeatures.length; i++) { - vectorSource.removeFeature(greenFeatures[i]); - } - } - - function hideOrange() { - for (var i = 0; i < orangeFeatures.length; i++) { - vectorSource.removeFeature(orangeFeatures[i]); - } - } - - function hideRed() { - for (var i = 0; i < redFeatures.length; i++) { - vectorSource.removeFeature(redFeatures[i]); - } - } - - function searchDevice() { - var deviceId = document.getElementById('deviceSearch').value.trim(); - if (!deviceId) { - currentSearchedDevice = null; - vectorSource.clear(); - for (var i = 0; i < allFeatures.length; i++) { - vectorSource.addFeature(allFeatures[i]); - } - if (marker_state === 2) { - hideGreen(); - hideRed(); - } else if (marker_state === 3) { - hideGreen(); - hideOrange(); - } - document.getElementById('btn-device-locate').style.display = 'none'; - updateFilterButtonsState(marker_state); - return; - } - currentSearchedDevice = deviceId; - filterByDeviceId(deviceId); - } - - function locateDeviceOnMap(deviceId, latitude, longitude) { - currentSearchedDevice = deviceId; - filterByDeviceId(deviceId); - layer.open({ - title: '', - type: 2, - shade: 0.2, - maxmin: true, - shadeClose: true, - anim: 2, - offset: 'rb', - area: ['100%', '50%'], - content: '../page/gnss_q_status?query=' + deviceId - }); - } - - function updateFilterButtonsState(state) { - document.getElementById('btn-all').classList.remove('active'); - document.getElementById('btn-warning1').classList.remove('active'); - document.getElementById('btn-warning2').classList.remove('active'); - if (state === 1) { - document.getElementById('btn-all').classList.add('active'); - } else if (state === 2) { - document.getElementById('btn-warning1').classList.add('active'); - } else if (state === 3) { - document.getElementById('btn-warning2').classList.add('active'); - } - } - - function filterByDeviceId(deviceId) { - var savedMyLocationFeature = myLocationFeature; - vectorSource.clear(); - if (savedMyLocationFeature) { - vectorSource.addFeature(savedMyLocationFeature); - } - var found = false; - for (var i = 0; i < allFeatures.length; i++) { - var feature = allFeatures[i]; - var deviceInfo = feature.get('deviceInfo'); - if (deviceInfo && deviceInfo.deviceid.includes(deviceId)) { - vectorSource.addFeature(feature); - found = true; - var geometry = feature.getGeometry(); - var deviceCoord = geometry.getCoordinates(); - map.getView().setCenter(deviceCoord); - map.getView().setZoom(15); - } - } - if (!found) { - layer.msg('未找到设备: ' + deviceId); - if (marker_state === 1) { - showAll(); - } else if (marker_state === 2) { - showWarning1(); - } else if (marker_state === 3) { - showWarning2(); - } - } - document.getElementById('current-device-id').textContent = deviceId; - document.getElementById('btn-device-locate').style.display = 'block'; - document.getElementById('btn-device-locate').classList.add('active'); - document.getElementById('btn-all').classList.remove('active'); - document.getElementById('btn-warning1').classList.remove('active'); - document.getElementById('btn-warning2').classList.remove('active'); - } - - function addMeasureInteraction() { - var type = 'LineString'; - measureDraw = new ol.interaction.Draw({ - source: measureSource, - type: type, - style: new ol.style.Style({ - fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' }), - stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 0, 0.5)', lineDash: [10, 10], width: 2 }), - image: new ol.style.Circle({ - radius: 5, - stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 0, 0.7)' }), - fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' }) - }) - }) - }); - map.addInteraction(measureDraw); - createMeasureTooltip(); - var listener; - measureDraw.on('drawstart', function(evt) { - sketch = evt.feature; - listener = sketch.getGeometry().on('change', function(evt) { - var geom = evt.target; - var output = formatLength(geom); - measureTooltipElement.innerHTML = output; - measureTooltip.setPosition(geom.getLastCoordinate()); - }); - }); - measureDraw.on('drawend', function() { - measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'; - measureTooltip.setOffset([0, -7]); - sketch = null; - measureTooltipElement = null; - createMeasureTooltip(); - ol.Observable.unByKey(listener); - }); - } - - function createMeasureTooltip() { - if (measureTooltipElement) { - measureTooltipElement.parentNode.removeChild(measureTooltipElement); - } - measureTooltipElement = document.createElement('div'); - measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'; - measureTooltip = new ol.Overlay({ - element: measureTooltipElement, - offset: [0, -15], - positioning: 'bottom-center', - stopEvent: false - }); - map.addOverlay(measureTooltip); - } - - function formatLength(line) { - var coordinates = line.getCoordinates(); - var length = 0; - for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) { - var c1 = ol.proj.transform(coordinates[i], 'EPSG:3857', 'EPSG:4326'); - var c2 = ol.proj.transform(coordinates[i + 1], 'EPSG:3857', 'EPSG:4326'); - length += haversineDistance(c1, c2); - } - return length > 1000 ? Math.round((length / 1000) * 100) / 100 + ' 公里' : Math.round(length * 100) / 100 + ' 米'; - } - - function haversineDistance(coord1, coord2) { - var R = 6371000; - var dLat = (coord2[1] - coord1[1]) * Math.PI / 180; - var dLon = (coord2[0] - coord1[0]) * Math.PI / 180; - var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(coord1[1] * Math.PI / 180) * Math.cos(coord2[1] * Math.PI / 180) * - Math.sin(dLon / 2) * Math.sin(dLon / 2); - var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - return R * c; - } - - 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; - var zoom = map.getView().getZoom(); - if (showCluster) { - if (zoom < maxZoomForClustering) { - clusterLayer.setVisible(true); - vectorLayer.setVisible(false); - } else { - clusterLayer.setVisible(false); - vectorLayer.setVisible(true); - } - } else { - clusterLayer.setVisible(false); - vectorLayer.setVisible(true); - } - }); - initialize(); - showAll(); - }); - - window.searchDevice = searchDevice; - window.showAll = showAll; - window.showWarning1 = showWarning1; - window.showWarning2 = showWarning2; - window.locateDeviceOnMap = locateDeviceOnMap; - window.queryDevices = function(status_type) { - layer.open({ - title: '', - type: 2, - shade: 0.2, - maxmin: true, - shadeClose: true, - anim: 2, - offset: 'rb', - area: ['100%', '50%'], - content: '../page/gnss_q_status?query=' + status_type - }); - }; - -})(); 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 5fa39e60..42589726 100644 --- a/sec-beidou/src/main/resources/templates/page/device_overview.html +++ b/sec-beidou/src/main/resources/templates/page/device_overview.html @@ -254,7 +254,7 @@ /* 由于不使用layui的元素,所以这边还得适配手机端 */ @media screen and (max-width: 768px) { .layuimini-main { - height: 108vh; + height: 120vh; overflow: hidden; } @@ -570,13 +570,11 @@ justify-content: space-between; align-items: center; margin-bottom: 12px; - cursor: move; padding: 10px 20px; border-bottom: 1px solid rgba(0, 0, 0, 0.05); border-radius: 8px 8px 0 0; transition: background-color 0.2s ease; margin: -16px -16px 12px -16px; - user-select: none; } .weather-card-header:hover { @@ -796,182 +794,182 @@ -
-
-
-
- - 设备数量 - 1101 -
-
- - 装机量 - 1123 -
-
- - 掉线数 - 22 -
-
- - 未推送数 - 11 -
-
- - 长期无效解 - 10 -
-
- - 严重告警 - 40 -
-
- - 一般告警 - 79 -
-
- - 无GGA告警 - 4 -
+
+
+
+
+ + 设备数量 + 1101 +
+
+ + 装机量 + 1123 +
+
+ + 掉线数 + 22 +
+
+ + 未推送数 + 11 +
+
+ + 长期无效解 + 10 +
+
+ + 严重告警 + 40 +
+
+ + 一般告警 + 79 +
+
+ + 无GGA告警 + 4
- -
-
- -
-