路线大屏页面创建

This commit is contained in:
wangcong 2024-09-25 09:45:16 +08:00
parent 26686e62e4
commit 1cbafa71d1
6 changed files with 263 additions and 21 deletions

BIN
src/assets/xc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@ -11,14 +11,9 @@ export default {
}, },
methods: { methods: {
initializeMap() { initializeMap() {
var imageURL = "http://t0.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=1eb44fae5b9dc454442b322e9a41d233";
//
var lay = new T.TileLayer(imageURL, {minZoom: 1, maxZoom: 18});
var config = {layers: [lay]};
// //
const map = new T.Map('mapContainer', config); const map = new T.Map('mapContainer');
// //
map.centerAndZoom(new T.LngLat(116.404, 39.915), 12); map.centerAndZoom(new T.LngLat(116.404, 39.915), 12);

View File

@ -46,6 +46,11 @@ export const constantRoutes = [
component: () => import('@/views/login'), component: () => import('@/views/login'),
hidden: true hidden: true
}, },
{
path: '/bigscreen',
component: () => import('@/views/bigscreen'),
hidden: true
},
{ {
path: '/register', path: '/register',
component: () => import('@/views/register'), component: () => import('@/views/register'),

215
src/views/bigscreen.vue Normal file
View File

@ -0,0 +1,215 @@
<template>
<div class="map-container">
<div id="map" class="map"></div>
</div>
</template>
<script>
export default {
data() {
return {
map: null,
currentLayer: null,
cars: [], //
carIcon: null,
pointIcon: null,
};
},
mounted() {
this.initMap();
for (let i = 0; i < document.getElementsByClassName("tdt-iconLayers-layer").length; i++) {
//document.getElementsByClassName("tdt-iconLayers-layer")[i].style.display = "none"
}
setTimeout(function () {
let a = document.getElementsByName('[data-layerid="128"]');
console.log(a)
}, 2000)
},
methods: {
initMap() {
//
const center = new T.LngLat(116.40769, 39.89945); //
let imageURL = 'http://t0.tianditu.gov.cn/vec_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=1eb44fae5b9dc454442b322e9a41d233';
let imageUrl2 = 'http://t0.tianditu.gov.cn/cia_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=1eb44fae5b9dc454442b322e9a41d233'
this.currentLayer = new T.TileLayer(imageURL, {minZoom: 1, maxZoom: 18}); //
this.map = new T.Map('map', {layers: [this.currentLayer]});
this.map.centerAndZoom(center, 18);
var ctrl = new T.Control.MapType();
//<EFBFBD><EFBFBD>
this.map.addControl(ctrl);
//
this.carIcon = new T.Icon({
iconUrl: require('@/assets/xc.png'), //
iconSize: new T.Point(40, 40)
});
//
this.pointIcon = new T.DivIcon({
html: '<div class="point-icon"></div>',
iconSize: new T.Point(10, 10)
});
//
const initialPositions = [
{ x: 116.40769, y: 39.89945 },
{ x: 116.40779, y: 39.89955 },
{ x: 116.40789, y: 39.89965 },
];
initialPositions.forEach((pos, index) => {
this.cars.push({
id: index,
marker: null,
lastPoint: null,
x: pos.x,
y: pos.y,
});
const point = new T.LngLat(pos.x, pos.y);
this.addCarAtPoint(index, point);
});
//
this.map.addEventListener("zoomend", this.updateAllCarsDisplay);
//
setInterval(() => {
this.cars.forEach(car => {
const newPoint = new T.LngLat(car.x += 0.00001, car.y += 0.00001);
this.addCarAtPoint(car.id, newPoint);
});
}, 200);
},
addCarAtPoint(carId, currentPoint) {
const car = this.cars[carId];
if (car.lastPoint) {
const angle = this.calculateAngle(car.lastPoint, currentPoint);
this.updateCarPosition(carId, currentPoint, angle);
} else {
const zoomLevel = this.map.getZoom();
let markerIcon = this.createMarkerIcon(zoomLevel, 0);
car.marker = new T.Marker(currentPoint, {icon: markerIcon});
this.map.addOverLay(car.marker);
}
car.marker.addEventListener('click', () => {
alert(`小车${carId}当前坐标:经度: ${currentPoint.lng}, 纬度: ${currentPoint.lat}`);
});
car.lastPoint = currentPoint;
},
//
calculateAngle(point1, point2) {
const deltaX = point2.lng - point1.lng;
const deltaY = point2.lat - point1.lat;
const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI); //
return angle;
},
updateCarPosition(carId, point, angle) {
const car = this.cars[carId];
if (car.marker) {
this.map.removeOverLay(car.marker);
}
const zoomLevel = this.map.getZoom();
let markerIcon = this.createMarkerIcon(zoomLevel, angle);
car.marker = new T.Marker(point, {icon: markerIcon});
this.map.addOverLay(car.marker);
car.marker.addEventListener('click', () => {
alert(`小车${carId}当前坐标:经度: ${point.lng}, 纬度: ${point.lat}`);
});
},
createMarkerIcon(zoomLevel, angle) {
if (zoomLevel >= 18) {
return new T.DivIcon({
html: `<div class="car-icon" style="transform: rotate(${angle}deg); width: 30px; height: 30px; background-color: transparent;">
<img src="${require('@/assets/xc.png')}" style="width: 100%; height: 100%; object-fit: contain;" />
</div>`,
iconSize: new T.Point(30, 30),
iconAnchor: new T.Point(15, 15)
});
} else {
return new T.DivIcon({
html: '<div class="point-icon" style="width: 10px; height: 10px; background-color: #007bff; border-radius: 50%;"></div>',
iconSize: new T.Point(10, 10),
iconAnchor: new T.Point(5, 5)
});
}
},
updateAllCarsDisplay() {
this.cars.forEach(car => {
if (car.lastPoint) {
const angle = this.calculateAngle(car.lastPoint, car.lastPoint);
this.updateCarPosition(car.id, car.lastPoint, angle);
}
});
}
},
};
</script>
<style scoped>
.map-container {
position: relative;
width: 100%;
height: 100vh;
}
.map {
width: 100%;
height: 100%;
}
.basemap-switcher {
position: absolute;
top: 10px;
left: 10px;
background-color: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
button {
margin: 5px;
padding: 8px 16px;
cursor: pointer;
}
:global(.custom-div-icon) {
background: none !important;
border: none !important;
}
.car-icon {
width: 30px;
height: 30px;
background-color: transparent;
}
.car-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.point-icon {
width: 10px;
height: 10px;
background-color: #007bff;
border-radius: 50%;
}
</style>

View File

@ -1,8 +1,9 @@
<template> <template>
<div class="app-container">
<div id="map" class="map"> <div id="map" class="map">
<map-component></map-component> <map-component></map-component>
</div> </div>
</div>
</template> </template>
<!-- // tktk --> <!-- // tktk -->
<script> <script>
@ -39,8 +40,11 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.map{ .map{
width: 1000px; width: 100%;
height: 800px; height: 800px;
} }
.app-container{
padding: 0px;
}
</style> </style>

View File

@ -138,8 +138,8 @@
<el-dialog :title="title" :visible.sync="dialogVisible" width="80%" append-to-body> <el-dialog :title="title" :visible.sync="dialogVisible" width="80%" append-to-body>
<div style="display: flex;"> <div style="display: flex;">
<!-- 左侧表单部分 --> <!-- 左侧表单部分 -->
<div style="flex: 1; padding-right: 20px;"> <div style="flex: 1; padding-right: 40px;">
<el-form ref="form" :model="form" :rules="rules" label-width="100px"> <el-form ref="form" :model="form" :rules="rules" label-width="70px">
<el-form-item> <el-form-item>
<el-row :gutter="20"> <el-row :gutter="20">
@ -155,13 +155,21 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="路线类型">
<el-input v-model="form.routeType"></el-input>
</el-form-item>
<el-form-item> <el-form-item>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12">
<el-form-item label="路线类型">
<el-input v-model="form.routeType"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-row :gutter="5">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="路线全称"> <el-form-item label="路线全称">
<el-input v-model="form.fullName"></el-input> <el-input v-model="form.fullName"></el-input>
@ -202,12 +210,27 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="坐标点"> <el-form-item>
<el-input type="textarea" :disabled="true" v-model="form.coordinates" rows="4"></el-input> <el-row :gutter="20">
<el-col :span="24">
<el-form-item label="坐标点">
<el-input type="textarea" :disabled="true" v-model="form.coordinates" rows="4"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form-item> </el-form-item>
<el-form-item label="备注"> <el-form-item>
<el-input v-model="form.remarks"></el-input> <el-row :gutter="20">
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="form.remarks"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>