Skip to content

Commit e014662

Browse files
authored
Merge branch 'master' into feat/test_resolution
2 parents 7000739 + 6e343c0 commit e014662

File tree

3 files changed

+120
-25
lines changed

3 files changed

+120
-25
lines changed

src/georaster-layer-for-leaflet.ts

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/types/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface GeoRasterLayerOptions_CommonOptions extends GridLayerOptions {
3030
updateWhenIdle?: boolean; // inherited from LeafletJS
3131
updateWhenZooming?: boolean; // inherited from LeafletJS
3232
keepBuffer?: number; // inherited from LeafletJS
33+
caching?: boolean;
3334
}
3435

3536
// Ensures at least one of the georaster[s] options is defined while being ok the other is not
@@ -58,6 +59,7 @@ export interface DrawTileOptions {
5859
coords: Coords;
5960
context: CanvasRenderingContext2D;
6061
done: DoneCallback;
62+
resolution: number;
6163
}
6264

6365
// note: Tile is taken from leaflets `InternalTiles` type and should not be modified. - SFR 2021-01-19

tests/caching.html

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta name="viewport" content="width=device-width, initial-scale=1" />
5+
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
6+
<style>
7+
#map {
8+
bottom: 0;
9+
left: 0;
10+
position: absolute;
11+
right: 0;
12+
top: 0;
13+
}
14+
</style>
15+
</head>
16+
<body>
17+
<div id="map"></div>
18+
<script src="https://unpkg.com/browse/whatwg-fetch@3.2.0/dist/fetch.umd.js"></script>
19+
<script src="https://unpkg.com/leaflet/dist/leaflet-src.js"></script>
20+
<script src="https://unpkg.com/georaster"></script>
21+
<script src="../dist/georaster-layer-for-leaflet.min.js"></script>
22+
<script>
23+
// initalize leaflet map
24+
var map = L.map("map").setView([0, 0], 5);
25+
26+
// add OpenStreetMap basemap
27+
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
28+
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
29+
}).addTo(map);
30+
31+
var url_to_geotiff_file = "https://geotiff.github.io/georaster-layer-for-leaflet-example/example_4326.tif";
32+
33+
fetch(url_to_geotiff_file)
34+
.then(function (response) {
35+
return response.arrayBuffer();
36+
})
37+
.then(function (arrayBuffer) {
38+
parseGeoraster(arrayBuffer).then(function (georaster) {
39+
console.log("georaster:", georaster);
40+
var layer = new GeoRasterLayer({
41+
georaster: georaster,
42+
resolution: {
43+
0: 2, // Zoom level 0 or higher: resolution 2
44+
16: 512 // Zoom level 16 or higher: resolution 512
45+
},
46+
caching: true
47+
});
48+
layer.addTo(map);
49+
map.fitBounds(layer.getBounds());
50+
});
51+
});
52+
</script>
53+
</body>
54+
</html>

0 commit comments

Comments
 (0)