Skip to content

Commit 89cce65

Browse files
committed
Fix smooth map route zooming
1 parent 7c4e4a5 commit 89cce65

1 file changed

Lines changed: 33 additions & 61 deletions

File tree

docs/js/map.js

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ const MapView = (() => {
3131
return 2 * R * Math.asin(Math.sqrt(s));
3232
}
3333

34-
function segmentTrajectory(points) {
34+
function segmentTrajectory(points, maxGapKm = PORT_MAX_GAP_KM) {
3535
if (!points || points.length < 2) return [];
3636
const segs = [];
3737
let cur = [points[0]];
3838
for (let i = 1; i < points.length; i++) {
39-
if (haversineKm(points[i - 1], points[i]) > PORT_MAX_GAP_KM) {
39+
if (haversineKm(points[i - 1], points[i]) > maxGapKm) {
4040
if (cur.length >= 2) segs.push(cur);
4141
cur = [points[i]];
4242
} else {
@@ -105,39 +105,32 @@ const MapView = (() => {
105105
setData(data, filters) {
106106
this._data = data;
107107
this._filters = filters;
108-
if (this._canvas) this._draw();
108+
if (this._map) this._redraw();
109109
},
110110

111111
onAdd(map) {
112112
this._map = map;
113-
this._canvas = document.createElement("canvas");
114-
this._canvas.style.cssText = "position:absolute;top:0;left:0;pointer-events:none;z-index:300;";
115-
map.getPane("overlayPane").appendChild(this._canvas);
116-
this._resize();
117-
map.on("moveend zoomend resize", this._onMove, this);
118-
this._draw();
113+
this._renderer = L.canvas({ padding: 0.6, tolerance: 2 });
114+
this._layer = L.layerGroup().addTo(map);
115+
this._redraw();
119116
},
120117

121118
onRemove(map) {
122-
map.off("moveend zoomend resize", this._onMove, this);
123-
this._canvas.remove();
124-
this._canvas = null;
125-
},
126-
127-
_onMove() { this._resize(); this._draw(); },
128-
129-
_resize() {
130-
const sz = this._map.getSize();
131-
this._canvas.width = sz.x;
132-
this._canvas.height = sz.y;
133-
L.DomUtil.setPosition(this._canvas, this._map.containerPointToLayerPoint([0, 0]));
119+
if (this._layer) {
120+
this._layer.clearLayers();
121+
map.removeLayer(this._layer);
122+
}
123+
if (this._renderer) {
124+
this._renderer.remove();
125+
}
126+
this._layer = null;
127+
this._renderer = null;
128+
this._map = null;
134129
},
135130

136-
_draw() {
137-
if (!this._canvas) return;
138-
const ctx = this._canvas.getContext("2d");
139-
const sz = this._map.getSize();
140-
ctx.clearRect(0, 0, sz.x, sz.y);
131+
_redraw() {
132+
if (!this._layer || !this._renderer) return;
133+
this._layer.clearLayers();
141134

142135
const { activeTypes, hour } = this._filters;
143136

@@ -147,42 +140,21 @@ const MapView = (() => {
147140
if (!traj.points || traj.points.length < 2) continue;
148141

149142
const meanSog = traj.points.reduce((s, p) => s + (p.sog || 0), 0) / traj.points.length;
150-
ctx.strokeStyle = meanSog >= GLOBAL_SOG_THRESHOLD ? GLOBAL_UNDERWAY_COLOR : GLOBAL_SLOW_COLOR;
151-
ctx.globalAlpha = 0.42;
152-
ctx.lineWidth = 1.1;
153-
ctx.beginPath();
154-
155-
let started = false;
156-
let prevPx = null;
157-
158-
for (const pt of traj.points) {
159-
const px = this._map.latLngToContainerPoint([pt.lat, pt.lon]);
160-
161-
if (prevPx) {
162-
const screenDist = Math.hypot(px.x - prevPx.x, px.y - prevPx.y);
163-
const kmPerPx = this._kmPerPixel();
164-
if (screenDist * kmPerPx > GLOBAL_MAX_STEP_KM) {
165-
if (started) ctx.stroke();
166-
ctx.beginPath();
167-
started = false;
168-
prevPx = null;
169-
}
170-
}
171-
172-
if (!started) { ctx.moveTo(px.x, px.y); started = true; }
173-
else ctx.lineTo(px.x, px.y);
174-
prevPx = px;
175-
}
176-
if (started) ctx.stroke();
143+
const color = meanSog >= GLOBAL_SOG_THRESHOLD ? GLOBAL_UNDERWAY_COLOR : GLOBAL_SLOW_COLOR;
144+
const segs = segmentTrajectory(traj.points, GLOBAL_MAX_STEP_KM);
145+
146+
segs.forEach(seg => {
147+
L.polyline(seg.map(p => [p.lat, p.lon]), {
148+
renderer: this._renderer,
149+
interactive: false,
150+
bubblingMouseEvents: false,
151+
color,
152+
weight: 1.1,
153+
opacity: 0.42,
154+
smoothFactor: 1.2,
155+
}).addTo(this._layer);
156+
});
177157
}
178-
ctx.globalAlpha = 1;
179-
},
180-
181-
_kmPerPixel() {
182-
const center = this._map.getCenter();
183-
const zoom = this._map.getZoom();
184-
const mPerPx = (156543.03392 * Math.cos(center.lat * Math.PI / 180)) / (2 ** zoom);
185-
return mPerPx / 1000;
186158
},
187159
});
188160

0 commit comments

Comments
 (0)