Trong quá trình phát triển các dự án WebGIS với yêu cầu phải hỗ trợ nhiều lớp dữ liệu nền từ GeoServer WMS (trên 25 lớp với yêu cầu bật tắt riêng, trong đó có 3 lớp bản đồ nền hành chính).
Tôi bắt gặp một bất cập của Leaflet như sau: Leaflet sử dụng kỹ thuật backbuffer nhằm giúp giao diện mượt hơn khi thay đổi zoom của bản đồ, tuy nhiên vấn đề này lại gây ra một hiệu ứng kèm theo là khi có nhiều lớp được bật, bản đồ tải khá chậm và hầu như không thể thực hiện được thao tác, do leaflet phải chờ kết thúc sự kiện zoom mới cho phép các thao tác liên quan thực hiện.
Bằng cách thử nhiệm thay đổi cách backbuffer hoạt động, website của tôi đã đạt những hiệu quả tích cực, chiến lược tải backbuffer như sau:
Các layer được chia thành 2 loại:
+ Loại 1 là layer nền hành chính cần được sử dụng backbuffer để tránh hiện tượng nhấp nháy bản đồ khi zoom.
+ Loại 2 là các layer chuyên đề khác, đối với các layer này tôi chấp nhận việc các layer nhấp nháy, vì đã có các layer thuộc nhóm 1 đóng vai trò chống nhấp nháy.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
L.TileLayer.include({
_prepareBgBuffer: function() {
var front = this._tileContainer,
bg = this._bgBuffer;
// if foreground layer doesn't have many tiles but bg layer does,
// keep the existing bg layer and just zoom it some more
var bgLoaded = this._getLoadedTilesPercentage(bg),
frontLoaded = this._getLoadedTilesPercentage(front);
var addtional = (bgLoaded > 0.5 && frontLoaded < 0.5) || this.options._htjs_hidden_on_zoom;
if (bg && addtional) {
this._bgBuffer.style.visibility = 'visible';
this._stopLoadingImages(front);
front.style.visibility = 'hidden';
return;
}
// prepare the buffer to become the front tile pane
bg.style.visibility = 'hidden';
bg.style[L.DomUtil.TRANSFORM] = '';
this._stopLoadingImages(bg);
// switch out the current layer to be the new bg layer (and vice-versa)
this._tileContainer = bg;
bg = this._bgBuffer = front;
//prevent bg buffer from clearing right after zoom
clearTimeout(this._clearBgBufferTimer);
},
});
/////////////////////////////////////////////////////////////////////////////////
Đoạn code phía trên nhằm thay thể hàm _prepareBgBuffer tại lớp L.TileLayer, đoạn code màu đó nhằm bổ sung thuộc tính TileLayer.options._htjs_hidden_on_zoom, bằng cách lựa chọn layer nào sẽ giữ vài trò làm mượt và các layer khác sẽ tập trung vào hiệu năng tải, từ đó giúp bản đồ được tải nhanh hơn và không ảnh hưởng đến cảm nhận của người dùng.
Chúc các bạn thành công.
_prepareBgBuffer: function() {
var front = this._tileContainer,
bg = this._bgBuffer;
// if foreground layer doesn't have many tiles but bg layer does,
// keep the existing bg layer and just zoom it some more
var bgLoaded = this._getLoadedTilesPercentage(bg),
frontLoaded = this._getLoadedTilesPercentage(front);
var addtional = (bgLoaded > 0.5 && frontLoaded < 0.5) || this.options._htjs_hidden_on_zoom;
if (bg && addtional) {
this._bgBuffer.style.visibility = 'visible';
this._stopLoadingImages(front);
front.style.visibility = 'hidden';
return;
}
// prepare the buffer to become the front tile pane
bg.style.visibility = 'hidden';
bg.style[L.DomUtil.TRANSFORM] = '';
this._stopLoadingImages(bg);
// switch out the current layer to be the new bg layer (and vice-versa)
this._tileContainer = bg;
bg = this._bgBuffer = front;
//prevent bg buffer from clearing right after zoom
clearTimeout(this._clearBgBufferTimer);
},
});
/////////////////////////////////////////////////////////////////////////////////
Đoạn code phía trên nhằm thay thể hàm _prepareBgBuffer tại lớp L.TileLayer, đoạn code màu đó nhằm bổ sung thuộc tính TileLayer.options._htjs_hidden_on_zoom, bằng cách lựa chọn layer nào sẽ giữ vài trò làm mượt và các layer khác sẽ tập trung vào hiệu năng tải, từ đó giúp bản đồ được tải nhanh hơn và không ảnh hưởng đến cảm nhận của người dùng.
Chúc các bạn thành công.
Không có nhận xét nào:
Đăng nhận xét