Để thực hiện mô phỏng lộ trình xe chạy trên bản đồ thì chúng ta có dùng thư viện bản đồ của google (Google Maps Platform), tuy nhiên hiện giờ google đã thu phí nên việc lấy Api Key cũng hơi phức tạp và nhất là bản đồ lại bị chế độ Development Purposes Only. Chính vì vậy tôi dùng thư viện Leafletjs để thay thế. Đây là một thư viện javascript mã nguồn mở, chả cần Api Key gì cả mà dùng vẫn ngon.
Tôi cũng đã rất mất công làm một lộ trình cho xe để mô phỏng chạy được mượt trên bản đồ. Mã nguồn có link ở dưới nhé.
- Thời gian
- Tọa độ
Như trên mô phỏng các bạn thấy, lộ trình của xe được thể hiện qua một bảng bên trái và xe di chuyển trên bản đồ. Vì vậy tôi đã khai báo một class View
như sau:
var View = function () { this.vehicleTracking = null; this.clear = function () { }; this.initTracking = function (tracking, previousTracking) { }; // Khởi tạo tracking. this.onAddVehicleTracking = function () { }; this.viewTracking = function (tracking, focus) { }; // Hiển thị tracking this.clearTracking = function (tracking) { }; };
Để xem được lộ trình như bảng bên trái tôi tạo class TableView
kế thừa tới View
như sau.
var TableView = function () { $.extend(this, new View()); /* Code Code */ this.clear = function () { tableBody.empty(); }; this.onAddVehicleTracking = function () { /* Code Code */ btnPlay.click(function () { $this.vehicleTracking.start(); }); btnPause.click(function () { $this.vehicleTracking.pause(); }); btnReset.click(function () { $this.vehicleTracking.stop(); }); } this.initTracking = function (tracking) { /* Code Code */ }; // cho dòng lộ trình màu xanh khi xe chạy tới tọa độ trong tracking this.viewTracking = function (tracking, focus) { if (focus) { tableBody.find("ul").removeClass("bg-success text-white"); var parent = tableBody.parent(); parent.scrollTop(parent.scrollTop() + tracking.row.position().top - parent.height() / 2 + tracking.row.height() / 2); tracking.row.addClass("bg-success text-white"); } }; };
Để xem được lộ trình của xe trên bản đồ tôi tạo class MapView
kế thừa View
như sau:
var MapView = function () { $.extend(this, new View()); /* Code Code */ this.clear = function () { /* Code Code */ }; this.initTracking = function (tracking, previousTracking) { /* Code Code Khởi tạo marker xe, polyline lộ trình */ }; // show marker xe và polyline lộ trình lên bản đồ this.viewTracking = function (tracking, focus) { if (tracking.polyline != null) { tracking.polyline.addTo(this.map); tracking.markerDirection.addTo(this.map); } if (focus) { markerVehicle.setIcon(tracking.vehicleIcon); markerVehicle.setLatLng(tracking.latLng).addTo(this.map); this.map.panTo(tracking.latLng, { animate: true }); } } this.clearTracking = function (tracking) { if (tracking.polyline != null) { tracking.polyline.removeFrom(this.map); tracking.markerDirection.removeFrom(this.map); } } };
Và cuối cùng tôi có class VehicleTracking
có chứa 2 View
trên và cho chạy lần lượt các tracking của xe.
var VehicleTracking = function () { var views = []; // các view cần hiển thị tracking this.addView = function (view) { view.vehicleTracking = this; view.onAddVehicleTracking(); views.push(view); } var withView = function (wv) { for (var i = 0; i < views.length; i++) wv.bind(this)(views[i]); }.bind(this); // Code Code var trackings = []; var currentTrackingIndex = 0; this.loadTrackings = function (data) { // Code Code } this.start = function () { if (timer != null && timer.isRunning) return; if (timer == null) { timer = new Core.Timer({ interval: function () { return interval; } }); timer.onStop = function () { withView(function (view) { view.timerStop(); }); }; } timer.setOption(function (options) { options.onTick = function () { var nextIndex = currentTrackingIndex + 1; if (nextIndex >= trackings.length) { currentTrackingIndex = nextIndex; return; }; viewTracking(nextIndex, true); } options.stopWhen = function () { return currentTrackingIndex >= trackings.length - 1; }; }); timer.start(); } this.stop = function () { stopTimer(); clear(); viewTracking(0, true); } this.pause = function () { stopTimer(); }; // Code Code this.gotoIndex = function (index) { if (timer == null || !timer.isRunning) clearForGoto(index); else { timer.stop(); clearForGoto(index); timer.start(); } } };
Tại hàm viewTracking
sẽ gửi tracking đi tới các View
để thực hiện hiển thị lộ trình. Khai báo và sử dụng VehicleTracking
như sau:
var vehicleTracking = new VehicleTracking(); // View tracking theo table var tableView = new TableView(); tableView.container = divMapId; vehicleTracking.addView(tableView); // View tracking trên bản đồ var mapView = new MapView(); vehicleTracking.addView(mapView); // Load lộ trình của xe vehicleTracking.loadTrackings(trackings);
Để xem chi tiết mã nguồn các bạn có thể click vào đây. Để xem dữ liệu trackings demo các bạn có thể click vào đây
Nếu các bạn thấy mô phỏng này hay và bổ ích. Hãy like và share để mình có động lực làm các mô phỏng tiếp theo nhé
Sơn 20