feat:将 OpenLayers 替换百度地图地图,加入高德和天地图

This commit is contained in:
fengyarnom 2025-06-09 17:56:25 +08:00
parent 7f66b1ae7b
commit 0b777802bf

View File

@ -6,9 +6,11 @@
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
<link rel="stylesheet" href="../lib/font-awesome-4.7.0/css/font-awesome.min.css" media="all">
<link rel="stylesheet" href="../css/public.css" media="all">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.5.0/ol.css">
<style>
.top-panel {
border: 1px solid #eceff9;
@ -58,10 +60,30 @@
background-color: rgba(27, 142, 236, 0.8);
color: #fff;
}
#map-container {
height: 85vh;
width: 100%;
padding:0px;
}
.map-controls {
position: absolute;
top: 10px;
right: 10px;
z-index: 1000;
background: white;
padding: 8px;
border-radius: 3px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
min-width: 120px;
}
.map-controls select {
width: 100%;
border: 1px solid #e6e6e6;
height: 30px;
}
</style>
<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=4ef46ba62e8fba67b53a0becca4d05da">
</script>
<script src="https://cdn.jsdelivr.net/npm/ol@v10.5.0/dist/ol.js"></script>
</head>
<body>
@ -111,240 +133,389 @@
<li class="night btn" onclick="showWarning1()">一般告警</li>
<li class="night btn" onclick="showWarning2()">严重告警</li>
</ul>
<div id="map-container" class="layui-card-body" style="height: 85vh;weight :100vw"></div>
<div class="map-controls">
<form class="layui-form">
<div class="layui-form-item">
<select id="mapTypeSelect" lay-filter="mapType">
<option value="tianditu_satellite" selected>天地图-卫星影像</option>
<option value="tianditu_normal">天地图-矢量</option>
<option value="amap_satellite">高德-卫星影像</option>
<option value="amap">高德-矢量</option>
</select>
</div>
</form>
</div>
<div id="map-container" class="layui-card-body"></div>
</div>
</div>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script th:inline="javascript">
var greenMarkers=[];
var orangeMarkers=[];
var redMarkers=[];
var greenLabels=[];
var orangeLabels=[];
var redLabels=[];
var batch_id = 0;
var deviceList=
[
var map;
var vectorSource;
var vectorLayer;
var currentBaseLayer;
var greenFeatures = [];
var orangeFeatures = [];
var redFeatures = [];
var marker_state = 1; // 1:all; 2:orange; 3:red
// 天地图 API 密钥fengyarnom@gmail.com
var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac';
var deviceList = [
[# th:each="device : ${deviceList}"]
{deviceid:[[${device.deviceid}]],
latitude:[[${device.latitude}]],
longitude:[[${device.longitude}]],
warning:[[${device.warning}]]},
{
deviceid: [[${device.deviceid}]],
latitude: [[${device.latitude}]],
longitude: [[${device.longitude}]],
warning: [[${device.warning}]]
},
[/]
];
var marker_state = 0;//0: translating; 1:all; 2:orange; 3:red
var map = new BMapGL.Map("map-container");
var convertor = new BMapGL.Convertor();
var loc_green = new BMapGL.Icon("../images/loc1_green.png", new BMapGL.Size(18, 24));
var loc_red = new BMapGL.Icon("../images/loc1_red.png", new BMapGL.Size(18, 24));
var loc_orange = new BMapGL.Icon("../images/loc1_orange.png", new BMapGL.Size(18, 24));
var loc_blue = new BMapGL.Icon("../images/loc_blue.png", new BMapGL.Size(18, 24));
var pi = 3.14159265358979324;
var a = 6378245.0;
var ee = 0.00669342162296594323;
/*判断是否在国内,不在国内则不做偏移*/
function outOfChina(lon, lat) {
if ((lon < 72.004 || lon > 137.8347) && (lat < 0.8293 || lat > 55.8271)) {
return true;
} else {
return false;
}
}
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;
}
initialize();
myLocation();
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
})
}),
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
})
})
]
}),
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
})
}),
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
})
})
]
})
};
function initialize() {
var point = new BMapGL.Point(116.404, 39.915);
map.centerAndZoom(point, 7);
map.enableScrollWheelZoom(true);
//map.setMapType(BMAP_SATELLITE_MAP);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var centerLat = 0;
var centerLon = 0;
//console.log(deviceList);
for(var i=0; i<deviceList.length; i++) {
centerLat += deviceList[i].latitude;
centerLon += deviceList[i].longitude;
}
if(deviceList.length>0) {
centerLat = centerLat/deviceList.length;
centerLon = centerLon/deviceList.length;
map.setCenter(new BMapGL.Point(centerLon,centerLat));
}
marker_state = 0;
var initialMapType = document.getElementById('mapTypeSelect').value;
currentBaseLayer = mapLayers[initialMapType];
translateCallback = function (data){
if(data.status === 0) {
var i=0;
for(; i<data.points.length; i++){
var label = new BMapGL.Label(deviceList[batch_id+i].deviceid,
{
position: data.points[i], // 指定文本标注所在的地理位置
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
}); // 创建文本标注对象
map = new ol.Map({
target: 'map-container',
layers: [
currentBaseLayer,
vectorLayer
],
view: new ol.View({
center: ol.proj.fromLonLat([116.404, 39.915]),
zoom: 7
})
});
if (deviceList.length > 0) {
var centerLat = 0;
var centerLon = 0;
var marker;
if(deviceList[batch_id+i].warning == 2) {
marker = new BMapGL.Marker(data.points[i], {
icon: loc_red
});
redMarkers.push(marker);
redLabels.push(label);
}
else if(deviceList[batch_id+i].warning == 1) {
marker = new BMapGL.Marker(data.points[i], {
icon: loc_orange
});
orangeMarkers.push(marker);
orangeLabels.push(label);
}
else {
marker = new BMapGL.Marker(data.points[i], {
icon: loc_green
});
greenMarkers.push(marker);
greenLabels.push(label);
}
// 点标记添加点击事件
map.addOverlay(marker);
map.addOverlay(label);
}
}
batch_id+=10;
// 函数内定时器的回调函数会继续调用 timer()
if(batch_id<deviceList.length) {
setTimeout(() => {
timer();
}, 500);
}
else marker_state = 1;
}
//每秒转换10个坐标否则会受百度并发限制
function timer() {
var pointArr = [];
var count = batch_id+10;
var totalNum = deviceList.length;
if(count>totalNum) count=totalNum;
for (var i = batch_id; i < count; i++) {
point = new BMapGL.Point(deviceList[i].longitude, deviceList[i].latitude);
pointArr.push(point);
for (var i = 0; i < deviceList.length; i++) {
centerLat += deviceList[i].latitude;
centerLon += deviceList[i].longitude;
}
convertor.translate(pointArr, 1, 5, translateCallback);
centerLat = centerLat / deviceList.length;
centerLon = centerLon / deviceList.length;
map.getView().setCenter(ol.proj.fromLonLat([centerLon, centerLat]));
}
// 启动函数
timer();
addDeviceMarkers();
myLocation();
}
function switchMapType(mapType) {
console.log('切换地图类型到:', mapType);
map.removeLayer(currentBaseLayer);
currentBaseLayer = mapLayers[mapType];
map.getLayers().insertAt(0, currentBaseLayer);
addDeviceMarkers();
}
function myLocation(){
var geolocation = new BMapGL.Geolocation();
geolocation.getCurrentPosition(function(r){
if(this.getStatus() == BMAP_STATUS_SUCCESS){
var mk = new BMapGL.Marker(r.point, {
icon: loc_blue
});
map.addOverlay(mk);
map.panTo(r.point);
function addDeviceMarkers() {
// 清除现有标记
vectorSource.clear();
greenFeatures = [];
orangeFeatures = [];
redFeatures = [];
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') {
// 高德地图 WGS84 转换为 GCJ-02
var gcjCoord = transform(device.latitude, device.longitude);
mapCoordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]);
} else {
// 天地图 CGCS20002000国家大地坐标系与WGS84实质一样
mapCoordinates = ol.proj.fromLonLat([device.longitude, device.latitude]);
}
var feature = new ol.Feature({
geometry: new ol.geom.Point(mapCoordinates),
deviceInfo: device
});
var iconSrc;
var color = '#000';
if (device.warning == 2) {
iconSrc = '../images/loc1_red.png';
redFeatures.push(feature);
} else if (device.warning == 1) {
iconSrc = '../images/loc1_orange.png';
orangeFeatures.push(feature);
} else {
iconSrc = '../images/loc1_green.png';
greenFeatures.push(feature);
}
var style = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: iconSrc,
scale: 1
}),
text: new ol.style.Text({
text: device.deviceid,
offsetY: -30,
fill: new ol.style.Fill({ color: color }),
stroke: new ol.style.Stroke({ color: '#fff', width: 2 }),
font: '12px Arial'
})
});
feature.setStyle(style);
vectorSource.addFeature(feature);
}
if (marker_state === 2) {
hideGreen();
hideRed();
} else if (marker_state === 3) {
hideGreen();
hideOrange();
}
}
function myLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var lon = position.coords.longitude;
var lat = position.coords.latitude;
var coordinates = ol.proj.fromLonLat([lon, lat]);
var feature = new ol.Feature({
geometry: new ol.geom.Point(coordinates)
});
var style = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: '../images/loc_blue.png',
scale: 1
})
});
feature.setStyle(style);
vectorSource.addFeature(feature);
map.getView().setCenter(coordinates);
});
}
}
function showAll() {
if (marker_state == 2) {
showGreen();
showRed();
marker_state = 1;
} else if (marker_state == 3) {
showGreen();
showOrange();
marker_state = 1;
}
}
function showWarning1() {
if (marker_state == 1) {
hideGreen();
hideRed();
marker_state = 2;
} else if (marker_state == 3) {
hideRed();
showOrange();
marker_state = 2;
}
}
function showWarning2() {
if (marker_state == 1) {
hideGreen();
hideOrange();
marker_state = 3;
} else if (marker_state == 2) {
hideOrange();
showRed();
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]);
}
}
layui.use(['form'], function(){
var form = layui.form;
form.on('select(mapType)', function(data){
switchMapType(data.value);
});
initialize();
});
function queryDevices(status_type) {
var index = 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,
});
}
function showAll(){
if(marker_state == 2){
showGreen();
showRed();
marker_state = 1;
}
else if(marker_state == 3){
showGreen();
showOrange();
marker_state = 1;
}
}
function showWarning1(){
if(marker_state == 1){
hideGreen();
hideRed();
marker_state = 2;
}
else if(marker_state == 3){
hideRed();
showOrange();
marker_state = 2;
}
}
function showWarning2(){
if(marker_state == 1){
hideGreen();
hideOrange();
marker_state = 3;
}
else if(marker_state == 2){
hideOrange();
showRed();
marker_state = 3;
}
}
function showGreen(){
for(var i=0; i<greenMarkers.length; i++){
map.addOverlay(greenMarkers[i]);
map.addOverlay(greenLabels[i]);
}
}
function showOrange(){
for(var i=0; i<orangeMarkers.length; i++){
map.addOverlay(orangeMarkers[i]);
map.addOverlay(orangeLabels[i]);
}
}
function showRed(){
for(var i=0; i<redMarkers.length; i++){
map.addOverlay(redMarkers[i]);
map.addOverlay(redLabels[i]);
}
}
function hideGreen(){
for(var i=0; i<greenMarkers.length; i++){
map.removeOverlay(greenMarkers[i]);
map.removeOverlay(greenLabels[i]);
}
}
function hideOrange(){
for(var i=0; i<orangeMarkers.length; i++){
map.removeOverlay(orangeMarkers[i]);
map.removeOverlay(orangeLabels[i]);
}
}
function hideRed(){
for(var i=0; i<redMarkers.length; i++){
map.removeOverlay(redMarkers[i]);
map.removeOverlay(redLabels[i]);
}
}
</script>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
function queryDevices(status_type){
var index = 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,
});
}
</script>
</body>