@@ -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