feat: 新增测距功能

- 新增测距功能
- 优化 device_overview.html 页面的JS代码
This commit is contained in:
fengyarnom 2025-06-30 14:44:41 +08:00
parent 0d21c8c6f3
commit 281c11b1e7
2 changed files with 898 additions and 823 deletions

View File

@ -0,0 +1,755 @@
(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
});
};
})();