@@ -57,9 +57,12 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
5757 updateWhenZooming : false ,
5858 keepBuffer : 25 ,
5959 resolution : 2 ** 5 ,
60- debugLevel : 0
60+ debugLevel : 0 ,
61+ caching : true
6162 } ,
6263
64+ cache : { } ,
65+
6366 initialize : function ( options : GeoRasterLayerOptions ) {
6467 try {
6568 if ( options . georasters ) {
@@ -224,6 +227,16 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
224227 }
225228 } ,
226229
230+ onAdd : function ( map ) {
231+ if ( ! this . options . maxZoom ) {
232+ // maxZoom is needed to display the tiles in the correct order over the zIndex between the zoom levels
233+ // https://github.com/Leaflet/Leaflet/blob/2592967aa6bd392db0db9e58dab840054e2aa291/src/layer/tile/GridLayer.js#L375C21-L375C21
234+ this . options . maxZoom = map . getMaxZoom ( ) ;
235+ }
236+
237+ L . GridLayer . prototype . onAdd . call ( this , map ) ;
238+ } ,
239+
227240 getRasters : function ( options : GetRasterOptions ) {
228241 const {
229242 innerTileTopLeftPoint,
@@ -321,12 +334,30 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
321334 // note that we aren't setting the tile height or width here
322335 // drawTile dynamically sets the width and padding based on
323336 // how much the georaster takes up the tile area
324- this . drawTile ( { tile, coords, context, done } ) ;
337+ const coordsKey = this . _tileCoordsToKey ( coords ) ;
338+
339+ const resolution = this . _getResolution ( coords . z ) ;
340+ const key = `${ coordsKey } :${ resolution } ` ;
341+ const doneCb = ( error ?: Error , tile ?: HTMLElement ) : void => {
342+ done ( error , tile ) ;
343+
344+ // caching the rendered tile, to skip the calculation for the next time
345+ if ( ! error && this . options . caching ) {
346+ this . cache [ key ] = tile ;
347+ }
348+ } ;
349+
350+ if ( this . options . caching && this . cache [ key ] ) {
351+ done ( undefined , this . cache [ key ] ) ;
352+ return this . cache [ key ] ;
353+ } else {
354+ this . drawTile ( { tile, coords, context, done : doneCb , resolution } ) ;
355+ }
325356
326357 return tile ;
327358 } ,
328359
329- drawTile : function ( { tile, coords, context, done } : DrawTileOptions ) {
360+ drawTile : function ( { tile, coords, context, done, resolution } : DrawTileOptions ) {
330361 try {
331362 const { debugLevel = 0 } = this ;
332363
@@ -432,7 +463,6 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
432463 const snappedSamplesDown = Math . abs ( gridbox [ 3 ] - gridbox [ 1 ] ) ;
433464 const rasterPixelsAcross = Math . ceil ( oldExtentOfInnerTileInRasterCRS . width / pixelWidth ) ;
434465 const rasterPixelsDown = Math . ceil ( oldExtentOfInnerTileInRasterCRS . height / pixelHeight ) ;
435- const { resolution } = this . options ;
436466 const layerCropExtent = inSimpleCRS ? extentOfLayer : this . extent ;
437467 const recropTileOrig = oldExtentOfInnerTileInRasterCRS . crop ( layerCropExtent ) ; // may be null
438468 let maxSamplesAcross = 1 ;
@@ -441,27 +471,8 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
441471 const recropTileProj = inSimpleCRS ? recropTileOrig : recropTileOrig . reproj ( code ) ;
442472 const recropTile = recropTileProj . crop ( extentOfTileInMapCRS ) ;
443473 if ( recropTile !== null ) {
444- let resolutionValue ;
445-
446- if ( typeof resolution === "object" ) {
447- const zoomLevels = Object . keys ( resolution ) ;
448-
449- for ( const key in zoomLevels ) {
450- if ( Object . prototype . hasOwnProperty . call ( zoomLevels , key ) ) {
451- const zoomLvl = zoomLevels [ key ] ;
452- if ( zoomLvl <= zoom ) {
453- resolutionValue = resolution [ zoomLvl ] ;
454- } else {
455- break ;
456- }
457- }
458- }
459- } else {
460- resolutionValue = resolution ;
461- }
462-
463- maxSamplesAcross = Math . ceil ( resolutionValue * ( recropTile . width / extentOfTileInMapCRS . width ) ) ;
464- maxSamplesDown = Math . ceil ( resolutionValue * ( recropTile . height / extentOfTileInMapCRS . height ) ) ;
474+ maxSamplesAcross = Math . ceil ( resolution * ( recropTile . width / extentOfTileInMapCRS . width ) ) ;
475+ maxSamplesDown = Math . ceil ( resolution * ( recropTile . height / extentOfTileInMapCRS . height ) ) ;
465476 }
466477 }
467478
@@ -1059,6 +1070,34 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
10591070
10601071 same ( array : GeoRaster [ ] , key : GeoRasterKeys ) {
10611072 return new Set ( array . map ( item => item [ key ] ) ) . size === 1 ;
1073+ } ,
1074+
1075+ clearCache ( ) {
1076+ this . cache = { } ;
1077+ } ,
1078+
1079+ _getResolution ( zoom : number ) {
1080+ const { resolution } = this . options ;
1081+
1082+ let resolutionValue ;
1083+ if ( typeof resolution === "object" ) {
1084+ const zoomLevels = Object . keys ( resolution ) ;
1085+
1086+ for ( const key in zoomLevels ) {
1087+ if ( Object . prototype . hasOwnProperty . call ( zoomLevels , key ) ) {
1088+ const zoomLvl = parseInt ( zoomLevels [ key ] ) ;
1089+ if ( zoomLvl <= zoom ) {
1090+ resolutionValue = resolution [ zoomLvl ] ;
1091+ } else {
1092+ break ;
1093+ }
1094+ }
1095+ }
1096+ } else {
1097+ resolutionValue = resolution ;
1098+ }
1099+
1100+ return resolutionValue ;
10621101 }
10631102} ) ;
10641103
0 commit comments