Skip to content

Commit 0443901

Browse files
committed
Expand viewport to nearby changes
1 parent b719a0b commit 0443901

1 file changed

Lines changed: 59 additions & 10 deletions

File tree

js/maps.js

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ class Maps {
105105
// Apply filtered bbox if set
106106
if (filteredBbox) {
107107
const bounds = [[bbox.getWest(), bbox.getSouth()], [bbox.getEast(), bbox.getNorth()]];
108-
108+
109109
this.main.on('load', () => {
110110
this.main.fitBounds(bounds, { padding: 50, duration: 0 });
111111
this.addBboxRectangle(this.main, bbox, 'main-bbox-rect', 5);
112112
});
113-
113+
114114
this.overviewMap.on('load', () => {
115115
this.overviewMap.fitBounds(bounds, { padding: 20, duration: 0 });
116116
this.addBboxRectangle(this.overviewMap, bbox, 'overview-bbox-rect', 1);
@@ -121,6 +121,9 @@ class Maps {
121121
this.featureCounter = 0;
122122
this.activeFeatures = [];
123123

124+
// Track current changeset
125+
this.currentChangesetId = null;
126+
124127
this.main.on('load', () => {
125128
this.setupDrawingLayers();
126129

@@ -314,19 +317,63 @@ class Maps {
314317
}
315318
}
316319

320+
// Calculate bounding box containing all active features
321+
getActiveFeaturesBounds() {
322+
const bounds = new maplibregl.LngLatBounds();
323+
324+
for (const feature of this.activeFeatures) {
325+
const geom = feature.geometry;
326+
327+
if (geom.type === 'Point') {
328+
bounds.extend(geom.coordinates);
329+
} else if (geom.type === 'LineString') {
330+
for (const coord of geom.coordinates) {
331+
bounds.extend(coord);
332+
}
333+
} else if (geom.type === 'Polygon') {
334+
for (const coord of geom.coordinates[0] || []) {
335+
bounds.extend(coord);
336+
}
337+
}
338+
}
339+
340+
return bounds;
341+
}
342+
317343
drawMapElement(change, cb) {
318344
this.pruneMapElements();
319345

320346
const noPanBounds = this.getNoPanBounds();
321347
const changeBounds = change.meta.bounds;
322348
const changeCenter = changeBounds.getCenter();
349+
const changesetId = change.meta.changeset;
350+
const distance = this.getDistanceFromCenter(changeCenter);
351+
352+
// Check if this change is a continuation of the same changeset and close enough by
353+
const isSameChangeset = this.currentChangesetId === changesetId;
354+
const isNearby = distance <= 5000; // 5km threshold
323355

324356
// Determine if we need to fly to the change
325357
const boundsContained = noPanBounds.contains([changeCenter.lng, changeCenter.lat]);
326358

327-
if (!boundsContained) {
328-
// Fly to fit the change bounds
329-
const distance = this.getDistanceFromCenter(changeCenter);
359+
if (isSameChangeset && isNearby && !boundsContained) {
360+
// Same changeset and nearby: fit viewport to all active geometry + new change
361+
const combinedBounds = this.getActiveFeaturesBounds();
362+
363+
// Extend to include the new change
364+
combinedBounds.extend([changeBounds.getWest(), changeBounds.getSouth()]);
365+
combinedBounds.extend([changeBounds.getEast(), changeBounds.getNorth()]);
366+
367+
this.main.fitBounds(
368+
[[combinedBounds.getWest(), combinedBounds.getSouth()],
369+
[combinedBounds.getEast(), combinedBounds.getNorth()]],
370+
{
371+
maxZoom: 18,
372+
padding: { top: 50, bottom: 200, left: 100, right: 100 },
373+
duration: 500
374+
}
375+
);
376+
} else if (!boundsContained) {
330377
// If the change is more than 1000km away it's a big jump so give it more time to pan
331378
const duration = distance > 1000000 ? 3000 : distance > 100000 ? 2000 : 1200;
332379

@@ -335,14 +382,19 @@ class Maps {
335382
[changeBounds.getEast(), changeBounds.getNorth()]],
336383
{
337384
maxZoom: 18,
338-
padding: 200,
385+
padding: { top: 50, bottom: 200, left: 100, right: 100 },
339386
duration: duration
340387
}
341388
);
342389
} else if (this.context.debug) {
343390
this.updateDebugRect();
344391
}
345392

393+
// Update changeset tracking
394+
if (!this.currentChangesetId || !isSameChangeset) {
395+
this.currentChangesetId = changesetId;
396+
}
397+
346398
// Spin the overview globe to the new location
347399
// Clamp latitude and use pitch for polar regions to keep equator visible
348400
const targetLat = changeCenter.lat;
@@ -397,9 +449,6 @@ class Maps {
397449
const mapElement = change.type === 'delete' ? change.old : change.neu;
398450
const featureId = `feature-${this.featureCounter++}`;
399451

400-
// Calculate distance to determine if this is a "big jump"
401-
const distance = this.getDistanceFromCenter(changeCenter);
402-
const isBigJump = !boundsContained && distance > 1000; // > 1km
403452

404453
const startDrawing = () => {
405454
switch (mapElement.type) {
@@ -419,7 +468,7 @@ class Maps {
419468
}
420469
};
421470

422-
if (isBigJump) {
471+
if (!isNearby) {
423472
// Wait for map to finish panning before drawing
424473
this.main.once('moveend', startDrawing);
425474
} else {

0 commit comments

Comments
 (0)