feat: 新增测距和比例尺
This commit is contained in:
parent
a70852fdc9
commit
1336bb16e6
@ -190,54 +190,6 @@
|
|||||||
background: rgba(230, 230, 230, 0.6);
|
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 {
|
.overview-stats {
|
||||||
@ -416,6 +368,24 @@
|
|||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ol-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(255,255,255,0.8);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
color: #333;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
.ol-tooltip-static {
|
||||||
|
background: #ffcc33;
|
||||||
|
color: #222;
|
||||||
|
border: 1px solid #ffcc33;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="../js/ol.js"></script>
|
<script src="../js/ol.js"></script>
|
||||||
@ -498,21 +468,20 @@
|
|||||||
|
|
||||||
<div class="toolbar-item">
|
<div class="toolbar-item">
|
||||||
<select id="warningFilter" class="toolbar-select" onchange="onWarningFilterChange()">
|
<select id="warningFilter" class="toolbar-select" onchange="onWarningFilterChange()">
|
||||||
<option value="all" selected>全部设备</option>
|
<option value="all">全部设备</option>
|
||||||
<option value="warning1">一般告警</option>
|
<option value="warning1">一般告警</option>
|
||||||
<option value="warning2">严重告警</option>
|
<option value="warning2" selected>严重告警</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="toolbar-divider"></div>
|
<div class="toolbar-divider"></div>
|
||||||
|
|
||||||
<div class="toolbar-item">
|
<div class="toolbar-item">
|
||||||
<select id="mapFeatures" class="toolbar-select" onchange="onMapFeaturesChange()">
|
<select id="displayOptions" class="toolbar-select" onchange="onDisplayOptionsChange()">
|
||||||
<option value="" selected>地图功能 ▼</option>
|
<option value="both" selected>信息+集群</option>
|
||||||
<option value="toggle_labels">切换设备标签</option>
|
<option value="device">仅设备信息</option>
|
||||||
<option value="toggle_cluster">切换设备集群</option>
|
<option value="cluster">仅集群显示</option>
|
||||||
<option value="measure_distance">开始测距</option>
|
<option value="none">隐藏标签</option>
|
||||||
<option value="clear_measure">清除测距</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -520,10 +489,15 @@
|
|||||||
<span id="current-device-id-new" style="background: rgba(26, 160, 148, 0.1); padding: 4px 8px; border-radius: 4px; font-size: 12px; color: #1aa094; font-weight: bold;"></span>
|
<span id="current-device-id-new" style="background: rgba(26, 160, 148, 0.1); padding: 4px 8px; border-radius: 4px; font-size: 12px; color: #1aa094; font-weight: bold;"></span>
|
||||||
<button class="toolbar-btn" onclick="clearDeviceSearch()" style="padding: 2px 6px; font-size: 11px;">清除</button>
|
<button class="toolbar-btn" onclick="clearDeviceSearch()" style="padding: 2px 6px; font-size: 11px;">清除</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-divider"></div>
|
||||||
|
<div class="toolbar-item">
|
||||||
|
<button class="toolbar-btn" id="measure-distance-btn" onclick="toggleMeasureDistance()">测距</button>
|
||||||
|
<button class="toolbar-btn" id="clear-measure-btn" onclick="clearMeasure()" style="margin-left:4px;">清除测距</button>
|
||||||
|
<span id="measure-result" style="margin-left:8px;color:#1aa094;font-size:12px;"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 比例尺 -->
|
|
||||||
<div id="map-scale" class="map-scale">比例尺 1:1000</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -541,7 +515,7 @@
|
|||||||
var greenFeatures = [];
|
var greenFeatures = [];
|
||||||
var orangeFeatures = [];
|
var orangeFeatures = [];
|
||||||
var redFeatures = [];
|
var redFeatures = [];
|
||||||
var marker_state = 1; // 1:all; 2:orange; 3:red
|
var marker_state = 3; // 1:all; 2:orange; 3:red
|
||||||
var allFeatures = []; // 存储所有设备标记,用于搜索功能
|
var allFeatures = []; // 存储所有设备标记,用于搜索功能
|
||||||
var currentSearchedDevice = null; // 当前搜索的设备ID
|
var currentSearchedDevice = null; // 当前搜索的设备ID
|
||||||
var myLocationFeature = null; // 存储"我的位置"标记
|
var myLocationFeature = null; // 存储"我的位置"标记
|
||||||
@ -552,16 +526,9 @@
|
|||||||
var showCluster = true;
|
var showCluster = true;
|
||||||
var minZoomForLabels = 4;
|
var minZoomForLabels = 4;
|
||||||
var maxZoomForClustering = 8;
|
var maxZoomForClustering = 8;
|
||||||
|
// 测距专用source和layer
|
||||||
// 测距相关变量
|
|
||||||
var measureSource;
|
var measureSource;
|
||||||
var measureVector;
|
var measureLayer;
|
||||||
var measureTooltipElement;
|
|
||||||
var measureTooltip;
|
|
||||||
var helpTooltipElement;
|
|
||||||
var helpTooltip;
|
|
||||||
var draw;
|
|
||||||
var measuring = false;
|
|
||||||
|
|
||||||
// 天地图 API 密钥(fengyarnom@gmail.com)
|
// 天地图 API 密钥(fengyarnom@gmail.com)
|
||||||
var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac';
|
var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac';
|
||||||
@ -650,12 +617,38 @@
|
|||||||
layers: [
|
layers: [
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
@ -664,12 +657,38 @@
|
|||||||
layers: [
|
layers: [
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
@ -678,7 +697,20 @@
|
|||||||
layers: [
|
layers: [
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
@ -687,12 +719,38 @@
|
|||||||
layers: [
|
layers: [
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
new ol.layer.Tile({
|
new ol.layer.Tile({
|
||||||
source: new ol.source.XYZ({
|
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
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
@ -785,6 +843,28 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 创建测距专用图层
|
||||||
|
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.RegularShape({
|
||||||
|
points: 4,
|
||||||
|
radius: 8,
|
||||||
|
radius2: 0,
|
||||||
|
angle: Math.PI / 4,
|
||||||
|
stroke: new ol.style.Stroke({ color: '#ed8936', width: 2 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
map.addLayer(measureLayer);
|
||||||
|
|
||||||
|
// 添加比例尺控件
|
||||||
|
var scaleLineControl = new ol.control.ScaleLine();
|
||||||
|
map.addControl(scaleLineControl);
|
||||||
|
|
||||||
// 设置初始可见性状态
|
// 设置初始可见性状态
|
||||||
var initialZoom = map.getView().getZoom();
|
var initialZoom = map.getView().getZoom();
|
||||||
if (showCluster && initialZoom < maxZoomForClustering) {
|
if (showCluster && initialZoom < maxZoomForClustering) {
|
||||||
@ -807,7 +887,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
vectorLayer.changed();
|
vectorLayer.changed();
|
||||||
updateScale(); // 更新比例尺
|
|
||||||
});
|
});
|
||||||
|
|
||||||
map.on('click', function(evt) {
|
map.on('click', function(evt) {
|
||||||
@ -845,7 +924,6 @@
|
|||||||
addDeviceMarkers();
|
addDeviceMarkers();
|
||||||
myLocation();
|
myLocation();
|
||||||
startLocationUpdates();
|
startLocationUpdates();
|
||||||
updateScale(); // 初始化比例尺
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchMapType(mapType) {
|
function switchMapType(mapType) {
|
||||||
@ -942,229 +1020,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 新的地图功能事件处理
|
|
||||||
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() {
|
function onMapTypeChange() {
|
||||||
var mapType = document.getElementById('mapTypeSelectNew').value;
|
var mapType = document.getElementById('mapTypeSelectNew').value;
|
||||||
switchMapType(mapType);
|
switchMapType(mapType);
|
||||||
@ -1227,7 +1082,7 @@
|
|||||||
navigator.geolocation.getCurrentPosition(function(position) {
|
navigator.geolocation.getCurrentPosition(function(position) {
|
||||||
var lon = position.coords.longitude;
|
var lon = position.coords.longitude;
|
||||||
var lat = position.coords.latitude;
|
var lat = position.coords.latitude;
|
||||||
var currentMapType = document.getElementById('mapTypeSelectNew').value;
|
var currentMapType = document.getElementById('mapTypeSelect').value;
|
||||||
var coordinates;
|
var coordinates;
|
||||||
|
|
||||||
if (currentMapType === 'amap' || currentMapType === 'amap_satellite') {
|
if (currentMapType === 'amap' || currentMapType === 'amap_satellite') {
|
||||||
@ -1435,10 +1290,17 @@
|
|||||||
currentSearchedDevice = deviceId;
|
currentSearchedDevice = deviceId;
|
||||||
filterByDeviceId(deviceId);
|
filterByDeviceId(deviceId);
|
||||||
|
|
||||||
var layerIndex = layer.index;
|
var layerIndex = layer.open({
|
||||||
layer.close(layerIndex);
|
title: '',
|
||||||
|
type: 2,
|
||||||
layer.msg('已定位到设备: ' + deviceId);
|
shade: 0.2,
|
||||||
|
maxmin: true,
|
||||||
|
shadeClose: true,
|
||||||
|
anim: 2,
|
||||||
|
offset: 'rb',
|
||||||
|
area: ['100%', '50%'],
|
||||||
|
content: '../page/gnss_q_status?query=' + deviceId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFilterButtonsState(state) {
|
function updateFilterButtonsState(state) {
|
||||||
@ -1585,6 +1447,168 @@
|
|||||||
showWarning2();
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 测距相关变量 ---
|
||||||
|
var measureActive = false;
|
||||||
|
var measureDraw; // 当前测距交互
|
||||||
|
var measureTooltipElement;
|
||||||
|
var measureTooltip;
|
||||||
|
var measureTooltips = []; // 存储所有测距点的overlay
|
||||||
|
|
||||||
|
function toggleMeasureDistance() {
|
||||||
|
if (measureActive) {
|
||||||
|
deactivateMeasure();
|
||||||
|
} else {
|
||||||
|
activateMeasure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function activateMeasure() {
|
||||||
|
measureSource.clear();
|
||||||
|
clearAllMeasureTooltips();
|
||||||
|
measureActive = true;
|
||||||
|
document.getElementById('measure-distance-btn').style.background = '#ed8936';
|
||||||
|
// 创建测距交互
|
||||||
|
measureDraw = 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: '#ffcc33', width: 2 }),
|
||||||
|
image: new ol.style.RegularShape({
|
||||||
|
points: 4,
|
||||||
|
radius: 8,
|
||||||
|
radius2: 0,
|
||||||
|
angle: Math.PI / 4,
|
||||||
|
stroke: new ol.style.Stroke({ color: '#ed8936', width: 2 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
map.addInteraction(measureDraw);
|
||||||
|
|
||||||
|
var sketch;
|
||||||
|
var listener;
|
||||||
|
measureDraw.on('drawstart', function(evt) {
|
||||||
|
sketch = evt.feature;
|
||||||
|
var coords = sketch.getGeometry().getCoordinates();
|
||||||
|
// 第一个点
|
||||||
|
addMeasureTooltip(coords[0], '0 m');
|
||||||
|
listener = sketch.getGeometry().on('change', function(e) {
|
||||||
|
var geom = e.target;
|
||||||
|
var coords = geom.getCoordinates();
|
||||||
|
clearAllMeasureTooltips();
|
||||||
|
var total = 0;
|
||||||
|
for (var i = 0; i < coords.length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
addMeasureTooltip(coords[0], '0 m');
|
||||||
|
} else {
|
||||||
|
var seg = new ol.geom.LineString([coords[i-1], coords[i]]);
|
||||||
|
total += ol.sphere.getLength(seg);
|
||||||
|
var output = (total > 100 ? (Math.round(total / 100) / 10) + ' km' : (Math.round(total * 10) / 10) + ' m');
|
||||||
|
addMeasureTooltip(coords[i], output, i === coords.length-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
measureDraw.on('drawend', function(evt) {
|
||||||
|
// 终点的tooltip样式特殊
|
||||||
|
if (measureTooltips.length > 0) {
|
||||||
|
var last = measureTooltips[measureTooltips.length-1];
|
||||||
|
last.getElement().className = 'ol-tooltip ol-tooltip-static';
|
||||||
|
}
|
||||||
|
ol.Observable.unByKey(listener);
|
||||||
|
measureDraw = null;
|
||||||
|
measureActive = false;
|
||||||
|
document.getElementById('measure-distance-btn').style.background = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deactivateMeasure() {
|
||||||
|
measureActive = false;
|
||||||
|
document.getElementById('measure-distance-btn').style.background = '';
|
||||||
|
if (measureDraw) {
|
||||||
|
map.removeInteraction(measureDraw);
|
||||||
|
measureDraw = null;
|
||||||
|
}
|
||||||
|
if (measureTooltipElement) {
|
||||||
|
measureTooltipElement.parentNode.removeChild(measureTooltipElement);
|
||||||
|
measureTooltipElement = null;
|
||||||
|
}
|
||||||
|
document.getElementById('measure-result').innerHTML = '';
|
||||||
|
measureSource.clear();
|
||||||
|
clearAllMeasureTooltips();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加测距tooltip
|
||||||
|
function addMeasureTooltip(coord, text, isLast) {
|
||||||
|
var elem = document.createElement('div');
|
||||||
|
elem.className = isLast ? 'ol-tooltip ol-tooltip-static' : 'ol-tooltip ol-tooltip-measure';
|
||||||
|
elem.innerHTML = text;
|
||||||
|
var overlay = new ol.Overlay({
|
||||||
|
element: elem,
|
||||||
|
offset: [0, -15],
|
||||||
|
positioning: 'bottom-center'
|
||||||
|
});
|
||||||
|
overlay.setPosition(coord);
|
||||||
|
map.addOverlay(overlay);
|
||||||
|
measureTooltips.push(overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除所有测距tooltip
|
||||||
|
function clearAllMeasureTooltips() {
|
||||||
|
for (var i = 0; i < measureTooltips.length; i++) {
|
||||||
|
map.removeOverlay(measureTooltips[i]);
|
||||||
|
}
|
||||||
|
measureTooltips = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除测距按钮
|
||||||
|
function clearMeasure() {
|
||||||
|
measureSource.clear();
|
||||||
|
clearAllMeasureTooltips();
|
||||||
|
document.getElementById('measure-result').innerHTML = '';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user