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 95752d25..c3d8a838 100644
--- a/sec-beidou/src/main/resources/templates/page/device_overview.html
+++ b/sec-beidou/src/main/resources/templates/page/device_overview.html
@@ -190,6 +190,54 @@
background: rgba(230, 230, 230, 0.6);
}
+ /* 比例尺样式 */
+ .map-scale {
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+ z-index: 1000;
+ background: rgba(255, 255, 255, 0.9);
+ padding: 8px 12px;
+ border-radius: 6px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ font-size: 12px;
+ color: #333;
+ font-weight: bold;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ }
+
+ /* 测距工具样式 */
+ .measure-tooltip {
+ position: relative;
+ background: rgba(0, 0, 0, 0.8);
+ border-radius: 4px;
+ color: white;
+ padding: 4px 8px;
+ opacity: 0.8;
+ white-space: nowrap;
+ font-size: 12px;
+ }
+
+ .measure-tooltip-measure {
+ opacity: 1;
+ font-weight: bold;
+ }
+
+ .measure-tooltip-static {
+ background-color: #ffcc33;
+ color: black;
+ border: 1px solid white;
+ }
+
+ .help-tooltip {
+ background: rgba(0, 0, 0, 0.8);
+ color: white;
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ white-space: nowrap;
+ }
+
.overview-stats {
@@ -450,20 +498,21 @@
-
@@ -473,6 +522,8 @@
+
+ 比例尺 1:1000
@@ -490,7 +541,7 @@
var greenFeatures = [];
var orangeFeatures = [];
var redFeatures = [];
- var marker_state = 3; // 1:all; 2:orange; 3:red
+ var marker_state = 1; // 1:all; 2:orange; 3:red
var allFeatures = []; // 存储所有设备标记,用于搜索功能
var currentSearchedDevice = null; // 当前搜索的设备ID
var myLocationFeature = null; // 存储"我的位置"标记
@@ -501,6 +552,16 @@
var showCluster = true;
var minZoomForLabels = 4;
var maxZoomForClustering = 8;
+
+ // 测距相关变量
+ var measureSource;
+ var measureVector;
+ var measureTooltipElement;
+ var measureTooltip;
+ var helpTooltipElement;
+ var helpTooltip;
+ var draw;
+ var measuring = false;
// 天地图 API 密钥(fengyarnom@gmail.com)
var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac';
@@ -589,38 +650,12 @@
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: function(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');
- }
- };
- }
+ 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
})
}),
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: function(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');
- }
- };
- }
+ 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
})
})
]
@@ -629,38 +664,12 @@
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: function(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');
- }
- };
- }
+ 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
})
}),
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: function(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');
- }
- };
- }
+ 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
})
})
]
@@ -669,20 +678,7 @@
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: function(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');
- }
- };
- }
+ 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
})
})
]
@@ -691,38 +687,12 @@
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: function(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');
- }
- };
- }
+ 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
})
}),
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: function(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');
- }
- };
- }
+ 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
})
})
]
@@ -837,6 +807,7 @@
}
}
vectorLayer.changed();
+ updateScale(); // 更新比例尺
});
map.on('click', function(evt) {
@@ -874,6 +845,7 @@
addDeviceMarkers();
myLocation();
startLocationUpdates();
+ updateScale(); // 初始化比例尺
}
function switchMapType(mapType) {
@@ -970,6 +942,229 @@
+ // 新的地图功能事件处理
+ function onMapFeaturesChange() {
+ var selectElement = document.getElementById('mapFeatures');
+ var value = selectElement.value;
+
+ switch(value) {
+ case 'toggle_labels':
+ showDeviceId = !showDeviceId;
+ vectorLayer.changed();
+ break;
+ case 'toggle_cluster':
+ showCluster = !showCluster;
+ var zoom = map.getView().getZoom();
+ if (showCluster) {
+ if (zoom >= maxZoomForClustering) {
+ clusterLayer.setVisible(false);
+ vectorLayer.setVisible(true);
+ } else {
+ clusterLayer.setVisible(true);
+ vectorLayer.setVisible(false);
+ }
+ } else {
+ clusterLayer.setVisible(false);
+ vectorLayer.setVisible(true);
+ }
+ break;
+ case 'measure_distance':
+ startMeasuring();
+ break;
+ case 'clear_measure':
+ clearMeasurements();
+ break;
+ }
+
+ // 重置下拉框到默认状态
+ selectElement.value = '';
+ }
+
+ // 测距功能
+ function startMeasuring() {
+ if (measuring) return;
+
+ measuring = true;
+
+ // 创建测距图层
+ if (!measureSource) {
+ measureSource = new ol.source.Vector();
+ measureVector = 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'
+ })
+ })
+ })
+ });
+ map.addLayer(measureVector);
+ }
+
+ // 创建绘制交互
+ draw = new ol.interaction.Draw({
+ source: measureSource,
+ type: 'LineString',
+ 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(draw);
+
+ createMeasureTooltip();
+ createHelpTooltip();
+
+ var listener;
+ draw.on('drawstart', function(evt) {
+ var sketch = evt.feature;
+ var tooltipCoord = evt.coordinate;
+
+ listener = sketch.getGeometry().on('change', function(evt) {
+ var geom = evt.target;
+ var output;
+ if (geom instanceof ol.geom.LineString) {
+ output = formatLength(geom);
+ tooltipCoord = geom.getLastCoordinate();
+ }
+ measureTooltipElement.innerHTML = output;
+ measureTooltip.setPosition(tooltipCoord);
+ });
+ });
+
+ draw.on('drawend', function() {
+ measureTooltipElement.className = 'measure-tooltip measure-tooltip-static';
+ measureTooltip.setOffset([0, -7]);
+ measureTooltipElement = null;
+ createMeasureTooltip();
+ ol.Observable.unByKey(listener);
+
+ // 结束测距
+ map.removeInteraction(draw);
+ measuring = false;
+
+ // 移除帮助提示
+ if (helpTooltip) {
+ map.removeOverlay(helpTooltip);
+ helpTooltip = null;
+ helpTooltipElement = null;
+ }
+ });
+ }
+
+ function clearMeasurements() {
+ if (measureSource) {
+ measureSource.clear();
+ }
+
+ if (draw) {
+ map.removeInteraction(draw);
+ draw = null;
+ }
+
+ measuring = false;
+
+ // 清除所有测距相关的覆盖物
+ var overlays = map.getOverlays().getArray().slice();
+ overlays.forEach(function(overlay) {
+ if (overlay.getElement() &&
+ (overlay.getElement().classList.contains('measure-tooltip') ||
+ overlay.getElement().classList.contains('help-tooltip'))) {
+ map.removeOverlay(overlay);
+ }
+ });
+
+ measureTooltip = null;
+ measureTooltipElement = null;
+ helpTooltip = null;
+ helpTooltipElement = null;
+ }
+
+ function createMeasureTooltip() {
+ if (measureTooltipElement) {
+ measureTooltipElement.parentNode.removeChild(measureTooltipElement);
+ }
+ measureTooltipElement = document.createElement('div');
+ measureTooltipElement.className = 'measure-tooltip measure-tooltip-measure';
+ measureTooltip = new ol.Overlay({
+ element: measureTooltipElement,
+ offset: [0, -15],
+ positioning: 'bottom-center'
+ });
+ map.addOverlay(measureTooltip);
+ }
+
+ function createHelpTooltip() {
+ if (helpTooltipElement) {
+ helpTooltipElement.parentNode.removeChild(helpTooltipElement);
+ }
+ helpTooltipElement = document.createElement('div');
+ helpTooltipElement.className = 'measure-tooltip help-tooltip';
+ helpTooltipElement.innerHTML = '点击开始测距,双击结束';
+ helpTooltip = new ol.Overlay({
+ element: helpTooltipElement,
+ offset: [15, 0],
+ positioning: 'center-left'
+ });
+ map.addOverlay(helpTooltip);
+ }
+
+ function formatLength(line) {
+ var length = ol.Sphere.getLength(line);
+ var output;
+ if (length > 100) {
+ output = (Math.round(length / 1000 * 100) / 100) + ' km';
+ } else {
+ output = (Math.round(length * 100) / 100) + ' m';
+ }
+ return output;
+ }
+
+ // 比例尺更新功能
+ function updateScale() {
+ var view = map.getView();
+ var resolution = view.getResolution();
+ var units = view.getProjection().getUnits();
+ var dpi = 25.4 / 0.28;
+ var mpu = ol.proj.METERS_PER_UNIT[units];
+ var scale = resolution * mpu * 39.37 * dpi;
+
+ if (scale >= 9500 && scale <= 950000) {
+ scale = Math.round(scale / 1000) * 1000;
+ } else if (scale >= 950000) {
+ scale = Math.round(scale / 100000) * 100000;
+ } else {
+ scale = Math.round(scale);
+ }
+
+ document.getElementById('map-scale').textContent = '比例尺 1:' + scale.toLocaleString();
+ }
+
function onMapTypeChange() {
var mapType = document.getElementById('mapTypeSelectNew').value;
switchMapType(mapType);
@@ -1032,7 +1227,7 @@
navigator.geolocation.getCurrentPosition(function(position) {
var lon = position.coords.longitude;
var lat = position.coords.latitude;
- var currentMapType = document.getElementById('mapTypeSelect').value;
+ var currentMapType = document.getElementById('mapTypeSelectNew').value;
var coordinates;
if (currentMapType === 'amap' || currentMapType === 'amap_satellite') {
@@ -1390,47 +1585,6 @@
showWarning2();
}
}
-
- function onDisplayOptionsChange() {
- var optionValue = document.getElementById('displayOptions').value;
-
- switch(optionValue) {
- case 'both':
- showDeviceId = true;
- showCluster = true;
- break;
- case 'device':
- showDeviceId = true;
- showCluster = false;
- break;
- case 'cluster':
- showDeviceId = false;
- showCluster = true;
- break;
- case 'none':
- showDeviceId = false;
- showCluster = false;
- break;
- }
-
- // 更新图层可见性
- var zoom = map.getView().getZoom();
- if (showCluster) {
- if (zoom >= maxZoomForClustering) {
- clusterLayer.setVisible(false);
- vectorLayer.setVisible(true);
- } else {
- clusterLayer.setVisible(true);
- vectorLayer.setVisible(false);
- }
- } else {
- clusterLayer.setVisible(false);
- vectorLayer.setVisible(true);
- }
-
- // 强制更新样式
- vectorLayer.changed();
- }