740 lines
25 KiB
HTML
740 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<title>机场车辆监控</title>
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<script src="https://unpkg.com/leaflet-rotatedmarker/leaflet.rotatedMarker.js"></script>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 20px;
|
|
font-family: Arial, sans-serif;
|
|
}
|
|
|
|
.container {
|
|
display: flex;
|
|
gap: 20px;
|
|
}
|
|
|
|
#map {
|
|
height: 800px;
|
|
width: 60%;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
#messages {
|
|
width: 40%;
|
|
height: 800px;
|
|
overflow-y: auto;
|
|
border: 1px solid #ccc;
|
|
padding: 10px;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.controls {
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.error {
|
|
color: red;
|
|
}
|
|
|
|
.success {
|
|
color: green;
|
|
}
|
|
|
|
.info {
|
|
color: blue;
|
|
}
|
|
|
|
.position {
|
|
color: #666;
|
|
}
|
|
|
|
.warning {
|
|
color: #f90;
|
|
}
|
|
|
|
.command {
|
|
color: #800080;
|
|
}
|
|
|
|
.vehicle-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
background-color: black;
|
|
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
|
|
border: 2px solid white;
|
|
}
|
|
|
|
.aircraft-icon {
|
|
width: 50px;
|
|
height: 50px;
|
|
background-color: rgba(128, 0, 128, 0.5);
|
|
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
|
|
border: 2px solid white;
|
|
position: relative;
|
|
}
|
|
|
|
.aircraft-icon::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 6px;
|
|
height: 6px;
|
|
background-color: black;
|
|
border-radius: 50%;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
.special-vehicle-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
background-color: orange;
|
|
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
|
|
border: 2px solid white;
|
|
}
|
|
|
|
.intersection-icon {
|
|
width: 30px;
|
|
height: 30px;
|
|
background-color: #666;
|
|
clip-path: polygon(40% 0%, 60% 0%, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0% 60%, 0% 40%, 40% 40%);
|
|
border: 2px solid white;
|
|
}
|
|
|
|
.traffic-light {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
border: 2px solid white;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.traffic-light-red {
|
|
background-color: red;
|
|
}
|
|
|
|
.traffic-light-green {
|
|
background-color: green;
|
|
}
|
|
|
|
.traffic-light-yellow {
|
|
background-color: yellow;
|
|
}
|
|
|
|
.countdown-label {
|
|
background: #000;
|
|
border: 1px solid #666;
|
|
border-radius: 2px;
|
|
font-family: "Digital-7", "DSEG7 Classic", Monaco, monospace;
|
|
font-weight: normal;
|
|
font-size: 12px;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
padding: 1px 2px;
|
|
line-height: 14px;
|
|
min-width: 28px;
|
|
box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 14px;
|
|
}
|
|
|
|
.countdown-red {
|
|
color: #ff3333;
|
|
}
|
|
|
|
.countdown-green {
|
|
color: #33ff33;
|
|
}
|
|
|
|
.countdown-yellow {
|
|
color: #ffff33;
|
|
}
|
|
|
|
.distance-label {
|
|
background: none;
|
|
border: none;
|
|
color: #666;
|
|
font-size: 12px;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.command-text {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: white;
|
|
font-size: 10px;
|
|
font-weight: bold;
|
|
pointer-events: none;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.safety-border {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 2px solid;
|
|
background: none;
|
|
}
|
|
|
|
.emergency-border {
|
|
border-color: rgba(255, 0, 0, 0.8);
|
|
}
|
|
|
|
.core-border {
|
|
border-color: rgba(255, 165, 0, 0.6);
|
|
}
|
|
|
|
.warning-border {
|
|
border-color: rgba(255, 255, 0, 0.4);
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h2>机场车辆监控系统</h2>
|
|
<div class="container">
|
|
<div id="map"></div>
|
|
<div id="messages"></div>
|
|
</div>
|
|
<div class="controls">
|
|
<button onclick="connect()">连接</button>
|
|
<button onclick="disconnect()">断开</button>
|
|
<button onclick="clearMessages()">清空日志</button>
|
|
</div>
|
|
|
|
<script>
|
|
let ws = null;
|
|
const messagesDiv = document.getElementById('messages');
|
|
|
|
// 初始化地图
|
|
const map = L.map('map').setView([36.35305878, 120.08558121], 17);
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© OpenStreetMap contributors'
|
|
}).addTo(map);
|
|
|
|
// 定义路口坐标
|
|
const T1_INTERSECTION = {
|
|
latitude: 36.35496367,
|
|
longitude: 120.0868853
|
|
};
|
|
|
|
const T2_INTERSECTION = {
|
|
latitude: 36.35448347,
|
|
longitude: 120.08502054
|
|
};
|
|
|
|
const T3_INTERSECTION = {
|
|
latitude: 36.35406879,
|
|
longitude: 120.08341044
|
|
};
|
|
|
|
const T4_INTERSECTION = {
|
|
latitude: 36.35305878,
|
|
longitude: 120.08558121
|
|
};
|
|
|
|
const T6_INTERSECTION = {
|
|
latitude: 36.35074527,
|
|
longitude: 120.08649105
|
|
};
|
|
|
|
const T7_INTERSECTION = {
|
|
latitude: 36.35052372,
|
|
longitude: 120.08562915
|
|
};
|
|
|
|
const T8_INTERSECTION = {
|
|
latitude: 36.35004529,
|
|
longitude: 120.08676664
|
|
};
|
|
|
|
const T10_INTERSECTION = {
|
|
latitude: 36.34917893,
|
|
longitude: 120.08710569
|
|
};
|
|
|
|
const T11_INTERSECTION = {
|
|
latitude: 36.3509885,
|
|
longitude: 120.0873865
|
|
};
|
|
|
|
// 存储所有标记
|
|
const markers = new Map();
|
|
const intersectionMarkers = new Map();
|
|
const intersections = new Map();
|
|
|
|
// 创建自定义图标
|
|
function createIcon(className, command = '') {
|
|
let size;
|
|
if (className.includes('aircraft')) {
|
|
size = [50, 50]; // 50米正方形
|
|
} else if (className.includes('vehicle')) {
|
|
size = [20, 20]; // 10米正方形
|
|
} else if (className.includes('traffic-light')) {
|
|
size = [12, 12]; // 10像素的红绿灯
|
|
} else {
|
|
size = [20, 20]; // 其他图标保持原样
|
|
}
|
|
|
|
// 如果有指令,创建带指令的图标
|
|
if (command && className === 'vehicle-icon') {
|
|
const html = `
|
|
<div style="width:${size[0]}px;height:${size[1]}px;position:relative;">
|
|
<div class="${className}"></div>
|
|
<div class="command-text">${command}</div>
|
|
</div>`;
|
|
return L.divIcon({
|
|
html: html,
|
|
className: '',
|
|
iconSize: size,
|
|
iconAnchor: [size[0] / 2, size[1] / 2]
|
|
});
|
|
}
|
|
|
|
// 没有指令时,创建普通图标
|
|
return L.divIcon({
|
|
className: className,
|
|
iconSize: size,
|
|
iconAnchor: [size[0] / 2, size[1] / 2]
|
|
});
|
|
}
|
|
|
|
function log(message, type = 'info') {
|
|
const div = document.createElement('div');
|
|
div.className = type;
|
|
// 将换行符转换为 HTML 换行
|
|
div.innerHTML = `${new Date().toLocaleTimeString()} - ${message.replace(/\n/g, '<br>')}`;
|
|
messagesDiv.appendChild(div);
|
|
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
|
}
|
|
|
|
function clearMessages() {
|
|
messagesDiv.innerHTML = '';
|
|
}
|
|
|
|
function updatePosition(data) {
|
|
const id = data.object_id;
|
|
const position = [data.position.latitude, data.position.longitude];
|
|
let iconClass;
|
|
|
|
// 根据ID前缀确定图标类型
|
|
if (data.object_type === 'aircraft') {
|
|
iconClass = 'aircraft-icon';
|
|
|
|
// 创建或更新安全边框
|
|
const borders = [
|
|
{ size: 250, class: 'warning-border' }, // 外围预警区
|
|
{ size: 150, class: 'core-border' }, // 核心安全区
|
|
{ size: 100, class: 'emergency-border' } // 紧急制动区
|
|
];
|
|
|
|
borders.forEach(border => {
|
|
const borderId = id + '_' + border.class;
|
|
let borderMarker = markers.get(borderId);
|
|
|
|
if (!borderMarker) {
|
|
// 创建边框标记
|
|
borderMarker = L.marker(position, {
|
|
icon: L.divIcon({
|
|
className: 'safety-border ' + border.class,
|
|
iconSize: [border.size, border.size],
|
|
iconAnchor: [border.size / 2, border.size / 2]
|
|
}),
|
|
rotationAngle: data.heading || 0,
|
|
rotationOrigin: 'center center'
|
|
}).addTo(map);
|
|
markers.set(borderId, borderMarker);
|
|
} else {
|
|
// 更新边框位置和方向
|
|
borderMarker.setLatLng(position);
|
|
if (data.heading !== undefined) {
|
|
borderMarker.setRotationAngle(data.heading);
|
|
}
|
|
}
|
|
});
|
|
} else if (id.startsWith('TQ')) {
|
|
iconClass = 'special-vehicle-icon';
|
|
} else {
|
|
iconClass = 'vehicle-icon';
|
|
}
|
|
|
|
let marker = markers.get(id);
|
|
if (!marker) {
|
|
// 创建新标记
|
|
marker = L.marker(position, {
|
|
icon: createIcon(iconClass),
|
|
rotationAngle: data.heading || 0,
|
|
rotationOrigin: 'center center'
|
|
}).addTo(map);
|
|
marker.bindTooltip(id);
|
|
markers.set(id, marker);
|
|
} else {
|
|
// 更新现有标记位置和航向
|
|
marker.setLatLng(position);
|
|
if (data.heading !== undefined) {
|
|
marker.setRotationAngle(data.heading);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加红绿灯状态和倒计时变量
|
|
// let lastTrafficLightState = null;
|
|
// let countdownInterval = null;
|
|
// let countdown = 10;
|
|
|
|
// New function to update intersection traffic lights
|
|
function updateIntersectionTrafficLights(data) {
|
|
const intersectionId = data.intersection_id;
|
|
const position = [data.position.latitude, data.position.longitude];
|
|
const nsStatus = data.ns_status; // 0: red, 1: green, 2: yellow
|
|
const ewStatus = data.ew_status; // 0: red, 1: green, 2: yellow
|
|
|
|
const nsColor = nsStatus === 0 ? 'red' : nsStatus === 1 ? 'green' : 'yellow';
|
|
const ewColor = ewStatus === 0 ? 'red' : ewStatus === 1 ? 'green' : 'yellow';
|
|
|
|
// Calculate offset positions for NS and EW lights
|
|
const nsPositionOffset = [position[0] + 0.00003, position[1]]; // Slightly north
|
|
const ewPositionOffset = [position[0], position[1] + 0.00003]; // Slightly east
|
|
|
|
let currentMarkers = intersectionMarkers.get(intersectionId);
|
|
if (!currentMarkers) {
|
|
// Create new marker group
|
|
currentMarkers = {};
|
|
currentMarkers.nsMarker = L.marker(nsPositionOffset, {
|
|
icon: createIcon(`traffic-light traffic-light-${nsColor}`),
|
|
pane: 'markerPane' // Ensure lights are above roads
|
|
}).addTo(map).bindTooltip(`Intersection ${intersectionId} (NS)`);
|
|
|
|
currentMarkers.ewMarker = L.marker(ewPositionOffset, {
|
|
icon: createIcon(`traffic-light traffic-light-${ewColor}`),
|
|
pane: 'markerPane'
|
|
}).addTo(map).bindTooltip(`Intersection ${intersectionId} (EW)`);
|
|
|
|
intersectionMarkers.set(intersectionId, currentMarkers);
|
|
} else {
|
|
// Update existing markers
|
|
currentMarkers.nsMarker.setLatLng(nsPositionOffset);
|
|
currentMarkers.nsMarker.setIcon(createIcon(`traffic-light traffic-light-${nsColor}`));
|
|
|
|
currentMarkers.ewMarker.setLatLng(ewPositionOffset);
|
|
currentMarkers.ewMarker.setIcon(createIcon(`traffic-light traffic-light-${ewColor}`));
|
|
}
|
|
}
|
|
|
|
function updateVehicleCommand(vehicleId, commandType) {
|
|
console.log('更新车辆指令:', vehicleId, commandType);
|
|
|
|
// 只处理无人车
|
|
if (!vehicleId.startsWith('QN')) {
|
|
return;
|
|
}
|
|
|
|
// 如果是 SIGNAL 指令,不更新显示
|
|
if (commandType === 'SIGNAL') {
|
|
console.log('忽略 SIGNAL 指令');
|
|
return;
|
|
}
|
|
|
|
// 获取指令字母
|
|
let commandText = '';
|
|
switch (commandType) {
|
|
case 'ALERT':
|
|
commandText = 'A';
|
|
break;
|
|
case 'WARNING':
|
|
commandText = 'W';
|
|
break;
|
|
case 'RESUME':
|
|
commandText = 'R';
|
|
break;
|
|
default:
|
|
commandText = '';
|
|
}
|
|
|
|
console.log('指令文本:', commandText);
|
|
|
|
// 更新图标
|
|
const marker = markers.get(vehicleId);
|
|
if (marker && commandText) {
|
|
console.log('设置新标:', vehicleId, commandText);
|
|
marker.setIcon(createIcon('vehicle-icon', commandText));
|
|
} else if (marker) {
|
|
marker.setIcon(createIcon('vehicle-icon'));
|
|
}
|
|
}
|
|
|
|
function connect() {
|
|
if (ws) {
|
|
log('已经连接,请先断开', 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
ws = new WebSocket('ws://localhost:8010');
|
|
|
|
ws.onopen = () => {
|
|
log('连接成功', 'success');
|
|
};
|
|
|
|
ws.onclose = () => {
|
|
log('连接关闭', 'info');
|
|
ws = null;
|
|
};
|
|
|
|
ws.onerror = (error) => {
|
|
log('发生错误: ' + error, 'error');
|
|
};
|
|
|
|
ws.onmessage = (event) => {
|
|
try {
|
|
const data = JSON.parse(event.data);
|
|
// 忽略心跳响应
|
|
if (data.type === 'heartbeat') {
|
|
return;
|
|
}
|
|
|
|
let type = 'info'; // 默认类型
|
|
let message = '';
|
|
|
|
switch (data.type) {
|
|
case 'position_update':
|
|
type = 'position';
|
|
updatePosition(data);
|
|
message = `位置更新: ${data.object_id} (${data.object_type})\n` +
|
|
`位置: (${data.position.longitude.toFixed(6)}, ${data.position.latitude.toFixed(6)})\n` +
|
|
`航向: ${data.heading !== undefined ? data.heading.toFixed(2) + '°' : 'N/A'}\n` +
|
|
`速度: ${data.speed !== undefined ? data.speed.toFixed(2) + ' m/s' : 'N/A'}`;
|
|
break;
|
|
case 'intersection_traffic_light_status':
|
|
type = 'info';
|
|
updateIntersectionTrafficLights(data);
|
|
message = `路口交通灯状态更新:\n` +
|
|
`路口 ID: ${data.intersection_id}\n` +
|
|
`南北状态: ${data.ns_status === 0 ? '红' : data.ns_status === 1 ? '绿' : '黄'}\n` +
|
|
`东西状态: ${data.ew_status === 0 ? '红' : data.ew_status === 1 ? '绿' : '黄'}`;
|
|
break;
|
|
case 'collision_warning':
|
|
type = 'warning';
|
|
message = '收到碰撞预警:\n' + JSON.stringify(data, null, 2);
|
|
break;
|
|
case 'vehicle_command':
|
|
type = 'command';
|
|
console.log('收到指令消息:', data); // 调试日志
|
|
updateVehicleCommand(data.vehicleId, data.commandType);
|
|
// 为控制指令添加中文描述
|
|
const commandTypes = {
|
|
'SIGNAL': '信号灯',
|
|
'ALERT': '告警',
|
|
'WARNING': '预警',
|
|
'RESUME': '恢复',
|
|
'PARKING': '安全停靠'
|
|
};
|
|
const reasons = {
|
|
'TRAFFIC_LIGHT': '红绿灯控制',
|
|
'AIRCRAFT_CROSSING': '航空器交叉',
|
|
'SPECIAL_VEHICLE': '特勤车辆',
|
|
'AIRCRAFT_PUSH': '航空器推出',
|
|
'RESUME_TRAFFIC': '恢复通行',
|
|
'PARKING_SIDE': '安全停靠'
|
|
};
|
|
message = `收到车辆控制指令:\n车辆: ${data.vehicleId}\n` +
|
|
`指令类型: ${commandTypes[data.commandType] || data.commandType}\n` +
|
|
`原因: ${reasons[data.reason] || data.reason}\n` +
|
|
(data.targetLatitude !== undefined ? `目标位置: (${data.targetLatitude}, ${data.targetLongitude})\n` : '') +
|
|
(data.signalState ? `信号灯状态: ${data.signalState}\n` : '') +
|
|
(data.intersectionId ? `路口ID: ${data.intersectionId}\n` : '') +
|
|
`时间戳: ${new Date(data.timestamp / 1000000).toLocaleString()}`;
|
|
break;
|
|
default:
|
|
message = '收到未知类型消息:\n' + JSON.stringify(data, null, 2);
|
|
}
|
|
|
|
log(message, type);
|
|
} catch (e) {
|
|
log('消息解析错误: ' + e.message, 'error');
|
|
}
|
|
};
|
|
} catch (error) {
|
|
log('连接失败: ' + error, 'error');
|
|
}
|
|
}
|
|
|
|
function disconnect() {
|
|
if (!ws) {
|
|
log('未连接', 'error');
|
|
return;
|
|
}
|
|
|
|
// 清除倒计时
|
|
// if (countdownInterval) {
|
|
// clearInterval(countdownInterval);
|
|
// countdownInterval = null;
|
|
// }
|
|
// lastTrafficLightState = null;
|
|
// countdown = 10;
|
|
|
|
// 清除倒计时标记
|
|
// trafficLights.forEach(light => {
|
|
// if (light.countdownMarker) {
|
|
// map.removeLayer(light.countdownMarker);
|
|
// light.countdownMarker = null;
|
|
// }
|
|
// });
|
|
|
|
ws.close();
|
|
ws = null;
|
|
|
|
// 清除所有车辆和安全边框标记
|
|
markers.forEach((marker, key) => {
|
|
map.removeLayer(marker);
|
|
});
|
|
markers.clear();
|
|
|
|
// 清除旧的红绿灯标记
|
|
// trafficLights.forEach(light => map.removeLayer(light));
|
|
// trafficLights.clear();
|
|
|
|
// 清除路口红绿灯标记
|
|
intersectionMarkers.forEach((markers, id) => {
|
|
if (markers.nsMarker) map.removeLayer(markers.nsMarker);
|
|
if (markers.ewMarker) map.removeLayer(markers.ewMarker);
|
|
});
|
|
intersectionMarkers.clear();
|
|
}
|
|
|
|
// 添加道路刻度标记函数
|
|
function addRoadMarks(startPoint, endPoint) {
|
|
// 计算点之间的距离(米)
|
|
const lat1 = startPoint[0];
|
|
const lon1 = startPoint[1];
|
|
const lat2 = endPoint[0];
|
|
const lon2 = endPoint[1];
|
|
|
|
// 计算道路角度(考虑经纬度投影)
|
|
const latMid = (lat1 + lat2) / 2; // 使用中点纬度来算经度缩放
|
|
const lonScale = Math.cos(latMid * Math.PI / 180); // 经度缩放因子
|
|
const dx = (lon2 - lon1) * lonScale;
|
|
const dy = lat2 - lat1;
|
|
const angle = Math.atan2(dy, dx);
|
|
|
|
// 计算垂直于道路的方向(只在右侧显示刻度)
|
|
const perpAngle = angle + Math.PI / 2;
|
|
const markLength = 0.00005; // 保持您设置的较短刻度线长度
|
|
const offset = 0.00004; // 向右偏移一点,避免与道路重叠
|
|
|
|
// 计算总距离
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
// 每50米一个刻度
|
|
const step = 0.0005; // 约50米
|
|
const steps = Math.floor(dist / step);
|
|
|
|
for (let i = 0; i <= steps; i++) {
|
|
// 计算刻度位置
|
|
const ratio = i / steps;
|
|
// 在经纬度坐标系中正插值
|
|
const pos = [
|
|
lat1 + dy * ratio,
|
|
lon1 + (dx / lonScale) * ratio
|
|
];
|
|
|
|
// 计算垂直偏移(考虑经纬度投影)
|
|
const offsetPos = [
|
|
pos[0] + Math.sin(perpAngle) * offset,
|
|
pos[1] + Math.cos(perpAngle) * offset / lonScale
|
|
];
|
|
|
|
// 计算刻度线终点(考虑经纬度投影)
|
|
const markEnd = [
|
|
offsetPos[0] + Math.sin(perpAngle) * markLength,
|
|
offsetPos[1] + Math.cos(perpAngle) * markLength / lonScale
|
|
];
|
|
|
|
// 添加刻度线
|
|
L.polyline([offsetPos, markEnd], {
|
|
color: '#666',
|
|
weight: 1.5
|
|
}).addTo(map);
|
|
|
|
// 添加距离标签
|
|
const distance = Math.round(i * 50);
|
|
if (distance > 0) {
|
|
const label = L.divIcon({
|
|
className: 'distance-label',
|
|
html: distance + 'm',
|
|
iconSize: [40, 20],
|
|
iconAnchor: [-5, 10]
|
|
});
|
|
|
|
L.marker(markEnd, {
|
|
icon: label,
|
|
interactive: false
|
|
}).addTo(map);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加道路
|
|
// T2 到 T10主路
|
|
const mainRoadEW = L.polyline([
|
|
[T2_INTERSECTION.latitude, T2_INTERSECTION.longitude],
|
|
[T10_INTERSECTION.latitude, T10_INTERSECTION.longitude]
|
|
], {
|
|
color: '#999',
|
|
weight: 8
|
|
}).addTo(map);
|
|
|
|
// T1 到 T3道路
|
|
const westRoadNS = L.polyline([
|
|
[T1_INTERSECTION.latitude, T1_INTERSECTION.longitude],
|
|
[T3_INTERSECTION.latitude, T3_INTERSECTION.longitude]
|
|
], {
|
|
color: '#999',
|
|
weight: 8
|
|
}).addTo(map);
|
|
|
|
// T7 到 T11道路
|
|
const eastRoadNS = L.polyline([
|
|
[T7_INTERSECTION.latitude, T7_INTERSECTION.longitude],
|
|
[T11_INTERSECTION.latitude, T11_INTERSECTION.longitude]
|
|
], {
|
|
color: '#999',
|
|
weight: 8
|
|
}).addTo(map);
|
|
|
|
// 添加刻度标记
|
|
// T1 到 T3路刻度
|
|
addRoadMarks(
|
|
[T1_INTERSECTION.latitude, T1_INTERSECTION.longitude],
|
|
[T3_INTERSECTION.latitude, T3_INTERSECTION.longitude]
|
|
);
|
|
|
|
// T7 到 T11路刻度
|
|
addRoadMarks(
|
|
[T7_INTERSECTION.latitude, T7_INTERSECTION.longitude],
|
|
[T11_INTERSECTION.latitude, T11_INTERSECTION.longitude]
|
|
);
|
|
|
|
// T2 到 T10路刻度
|
|
addRoadMarks(
|
|
[T2_INTERSECTION.latitude, T2_INTERSECTION.longitude],
|
|
[T10_INTERSECTION.latitude, T10_INTERSECTION.longitude]
|
|
);
|
|
</script>
|
|
</body>
|
|
|
|
</html> |