Skip to content

Commit

Permalink
Merge branch 'master' into feat/test_resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
Falke-Design authored Jul 15, 2023
2 parents 7000739 + 6e343c0 commit e014662
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 25 deletions.
89 changes: 64 additions & 25 deletions src/georaster-layer-for-leaflet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
updateWhenZooming: false,
keepBuffer: 25,
resolution: 2 ** 5,
debugLevel: 0
debugLevel: 0,
caching: true
},

cache: {},

initialize: function (options: GeoRasterLayerOptions) {
try {
if (options.georasters) {
Expand Down Expand Up @@ -224,6 +227,16 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
}
},

onAdd: function (map) {
if (!this.options.maxZoom) {
// maxZoom is needed to display the tiles in the correct order over the zIndex between the zoom levels
// https://github.com/Leaflet/Leaflet/blob/2592967aa6bd392db0db9e58dab840054e2aa291/src/layer/tile/GridLayer.js#L375C21-L375C21
this.options.maxZoom = map.getMaxZoom();
}

L.GridLayer.prototype.onAdd.call(this, map);
},

getRasters: function (options: GetRasterOptions) {
const {
innerTileTopLeftPoint,
Expand Down Expand Up @@ -321,12 +334,30 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
// note that we aren't setting the tile height or width here
// drawTile dynamically sets the width and padding based on
// how much the georaster takes up the tile area
this.drawTile({ tile, coords, context, done });
const coordsKey = this._tileCoordsToKey(coords);

const resolution = this._getResolution(coords.z);
const key = `${coordsKey}:${resolution}`;
const doneCb = (error?: Error, tile?: HTMLElement): void => {
done(error, tile);

// caching the rendered tile, to skip the calculation for the next time
if (!error && this.options.caching) {
this.cache[key] = tile;
}
};

if (this.options.caching && this.cache[key]) {
done(undefined, this.cache[key]);
return this.cache[key];
} else {
this.drawTile({ tile, coords, context, done: doneCb, resolution });
}

return tile;
},

drawTile: function ({ tile, coords, context, done }: DrawTileOptions) {
drawTile: function ({ tile, coords, context, done, resolution }: DrawTileOptions) {
try {
const { debugLevel = 0 } = this;

Expand Down Expand Up @@ -432,7 +463,6 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
const snappedSamplesDown = Math.abs(gridbox[3] - gridbox[1]);
const rasterPixelsAcross = Math.ceil(oldExtentOfInnerTileInRasterCRS.width / pixelWidth);
const rasterPixelsDown = Math.ceil(oldExtentOfInnerTileInRasterCRS.height / pixelHeight);
const { resolution } = this.options;
const layerCropExtent = inSimpleCRS ? extentOfLayer : this.extent;
const recropTileOrig = oldExtentOfInnerTileInRasterCRS.crop(layerCropExtent); // may be null
let maxSamplesAcross = 1;
Expand All @@ -441,27 +471,8 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C
const recropTileProj = inSimpleCRS ? recropTileOrig : recropTileOrig.reproj(code);
const recropTile = recropTileProj.crop(extentOfTileInMapCRS);
if (recropTile !== null) {
let resolutionValue;

if (typeof resolution === "object") {
const zoomLevels = Object.keys(resolution);

for (const key in zoomLevels) {
if (Object.prototype.hasOwnProperty.call(zoomLevels, key)) {
const zoomLvl = zoomLevels[key];
if (zoomLvl <= zoom) {
resolutionValue = resolution[zoomLvl];
} else {
break;
}
}
}
} else {
resolutionValue = resolution;
}

maxSamplesAcross = Math.ceil(resolutionValue * (recropTile.width / extentOfTileInMapCRS.width));
maxSamplesDown = Math.ceil(resolutionValue * (recropTile.height / extentOfTileInMapCRS.height));
maxSamplesAcross = Math.ceil(resolution * (recropTile.width / extentOfTileInMapCRS.width));
maxSamplesDown = Math.ceil(resolution * (recropTile.height / extentOfTileInMapCRS.height));
}
}

Expand Down Expand Up @@ -1059,6 +1070,34 @@ const GeoRasterLayer: (new (options: GeoRasterLayerOptions) => any) & typeof L.C

same(array: GeoRaster[], key: GeoRasterKeys) {
return new Set(array.map(item => item[key])).size === 1;
},

clearCache() {
this.cache = {};
},

_getResolution(zoom: number) {
const { resolution } = this.options;

let resolutionValue;
if (typeof resolution === "object") {
const zoomLevels = Object.keys(resolution);

for (const key in zoomLevels) {
if (Object.prototype.hasOwnProperty.call(zoomLevels, key)) {
const zoomLvl = parseInt(zoomLevels[key]);
if (zoomLvl <= zoom) {
resolutionValue = resolution[zoomLvl];
} else {
break;
}
}
}
} else {
resolutionValue = resolution;
}

return resolutionValue;
}
});

Expand Down
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface GeoRasterLayerOptions_CommonOptions extends GridLayerOptions {
updateWhenIdle?: boolean; // inherited from LeafletJS
updateWhenZooming?: boolean; // inherited from LeafletJS
keepBuffer?: number; // inherited from LeafletJS
caching?: boolean;
}

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

// note: Tile is taken from leaflets `InternalTiles` type and should not be modified. - SFR 2021-01-19
Expand Down
54 changes: 54 additions & 0 deletions tests/caching.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
#map {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/browse/[email protected]/dist/fetch.umd.js"></script>
<script src="https://unpkg.com/leaflet/dist/leaflet-src.js"></script>
<script src="https://unpkg.com/georaster"></script>
<script src="../dist/georaster-layer-for-leaflet.min.js"></script>
<script>
// initalize leaflet map
var map = L.map("map").setView([0, 0], 5);

// add OpenStreetMap basemap
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var url_to_geotiff_file = "https://geotiff.github.io/georaster-layer-for-leaflet-example/example_4326.tif";

fetch(url_to_geotiff_file)
.then(function (response) {
return response.arrayBuffer();
})
.then(function (arrayBuffer) {
parseGeoraster(arrayBuffer).then(function (georaster) {
console.log("georaster:", georaster);
var layer = new GeoRasterLayer({
georaster: georaster,
resolution: {
0: 2, // Zoom level 0 or higher: resolution 2
16: 512 // Zoom level 16 or higher: resolution 512
},
caching: true
});
layer.addTo(map);
map.fitBounds(layer.getBounds());
});
});
</script>
</body>
</html>

0 comments on commit e014662

Please sign in to comment.