我正在开发一个项目,需要在网络浏览器中可视化实时流量。我有一个包含不断更新的汽车坐标的数据库。我想创建一个模拟,这些汽车根据数据库中的坐标在地图上实时移动。而且使用的前端技术是 Angular
有人可以指导我如何实现这一目标吗?为此目的我应该使用任何特定的技术或库吗? .任何示例代码或教程将不胜感激。预先感谢您的帮助!
我尝试使用 WebGl 但正在寻找更好的解决方案?
我认为您走在正确的道路上!虽然 WebGL 是一个强大的选项,但这里有一种改进的方法,可以使用数据库坐标和库在 Angular 应用程序中创建实时交通模拟:
后端注意事项
实时数据交付:您需要一种机制将汽车坐标更新从数据库实时推送到前端。以下是常见选项:如 WebSockets、服务器发送事件 (SSE) 和轮询。
数据格式:选择有效的数据格式来传输汽车坐标。 JSON(JavaScript 对象表示法)因其简单性和广泛的浏览器支持而成为流行的选择。
实时通信和数据处理
使用像
@ngneat/until-destroy
这样的库来管理订阅并防止组件被销毁时发生内存泄漏。
在 Angular 应用程序中实现一项服务,以使用 WebSocket、SSE 或轮询来处理与后端的实时通信。
在服务中,订阅实时数据流并使用接收到的汽车坐标更新本地数据存储(例如,BehaviorSubject)。
地图可视化和汽车运动
使用Leaflet创建地图实例并添加图块图层(例如OpenStreetMap)。
订阅显示地图的 Angular 组件中的本地数据存储 (BehaviorSubject)。
根据更新的汽车坐标,创建或更新代表地图上每辆车的传单标记。
使用 requestAnimationFrame 等技术对地图上标记的移动进行动画处理,以实现平滑高效的更新。您可以在下面看到一个示例:
TypeScript
import { Component, OnInit, OnDestroy } from '@angular/core';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import * as L from 'leaflet';
interface Car {
id: number;
latitude: number;
longitude: number;
}
@UntilDestroy()
@Component({
selector: 'app-traffic-simulation',
templateUrl: './traffic-simulation.component.html',
styleUrls: ['./traffic-simulation.component.css'],
})
export class TrafficSimulationComponent implements OnInit, OnDestroy {
private map: L.Map;
private carMarkers: { [key: number]: L.Marker } = {}; // Map car ID to marker
constructor(private trafficService: TrafficService) {}
ngOnInit() {
this.map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(this.map);
this.trafficService.carCoordinates$.pipe(untilDestroyed(this)).subscribe((cars: Car[]) => {
// Update markers based on received car coordinates
cars.forEach((car) => {
const marker = this.carMarkers[car.id];
if (marker) {
marker.setLatLng([car.latitude, car.longitude]);
} else {
this.carMarkers[car.id] = L.marker([car.latitude, car.longitude]).addTo(this.map);
}
});
// Remove markers for cars that are no longer present
const markerToRemove = Object.keys(this.carMarkers).filter((id) => !cars.some((car) => car.id === Number(id)));
markerToRemove.forEach((id) => {
this.map.removeLayer(this.carMarkers[id]);
delete this.carMarkers[id];
});
});
如果您想了解更多,请点击以下链接