From b067a520a2ddda07f0ada019dc81c8ad97a53ef6 Mon Sep 17 00:00:00 2001 From: eisserer Date: Wed, 3 Jul 2024 14:35:59 +0200 Subject: [PATCH] implement tile cache based on indexeddb --- main.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + yarn.lock | 5 +++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/main.js b/main.js index 888b8c4..ebcfb35 100644 --- a/main.js +++ b/main.js @@ -12,6 +12,7 @@ import XYZ from 'ol/source/XYZ'; import * as olProj from 'ol/proj' import QRCode from 'qrcode' import { Html5QrcodeScanner } from 'html5-qrcode'; +import { openDB, deleteDB, wrap, unwrap } from 'idb'; proj4.defs("EPSG:31287","+proj=lcc +lat_0=47.5 +lon_0=13.3333333333333 +lat_1=49 +lat_2=46 +x_0=400000 +y_0=400000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs +type=crs"); proj4.defs("EPSG:3035","+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs"); @@ -19,17 +20,46 @@ register(proj4); let vectorLayer = new VectorLayer(); +const idb = await openDB('hofapp', 3, { + upgrade(db, oldVersion, newVersion, transaction, event) { + db.deleteObjectStore('imgs'); + const imgStore = db.createObjectStore('imgs', { keyPath: 'url' }); + imgStore.createIndex("url", "url"); + } +}); const map = new Map({ target: 'map', layers: [ new TileLayer({ - //source: new OSM(), source : new XYZ({ url : "https://mapproxy.rest-gdi.geo-data.space/tiles/osm/webmercator/{z}/{x}/{y}.png", maxZoom : 19, - tileLoadFunction : function(imageTile, src) { - imageTile.getImage().src = src; + tileLoadFunction : async function(imageTile, src) { + const img = imageTile.getImage(); + + const imgStore = idb.transaction('imgs', 'readonly').objectStore('imgs'); + const imgUrlIdx = imgStore.index('url'); + const range = IDBKeyRange.only(src); + + const cursor = await imgUrlIdx.openCursor(range); + if(cursor) { + console.log("laoding cached tile: " + src) + img.src = cursor.value.data; + } else { + console.log("requesting tile: " + src) + + img.src = src; + + const response = await fetch(src); + const blobResp = await response.blob(); + const reader = new FileReader(); + reader.onload = e => { + const imgStore = idb.transaction('imgs', 'readwrite').objectStore('imgs'); + imgStore.put({url : src, data : reader.result}); + } + reader.readAsDataURL(blobResp); + } } }) }), @@ -42,6 +72,24 @@ const map = new Map({ }) }); +// In case a previous map state is found in localStorage, restore it +const center = localStorage.getItem('center'); +const zoom = localStorage.getItem('zoom'); +if(center) { + map.getView().setCenter(JSON.parse(center)); +} +if(zoom) { + map.getView().setZoom(JSON.parse(zoom)); +} + +map.getView().on('change', e => { + const center = map.getView().getCenter(); + const zoom = map.getView().getZoom(); + localStorage.setItem('center', JSON.stringify(center)); + localStorage.setItem('zoom', JSON.stringify(zoom)); + //const tx = idb.transaction(['toDoList'], 'readwrite'); +}) + const container = document.getElementById('popup'); const content = document.getElementById('popup-content'); diff --git a/package.json b/package.json index 4bd3900..a9d456a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "html5-qrcode": "^2.3.8", + "idb": "^8.0.0", "ol": "latest", "proj4": "^2.10.0", "qrcode": "^1.5.3" diff --git a/yarn.lock b/yarn.lock index 29cd9e6..302b94c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2058,6 +2058,11 @@ idb@^7.0.1: resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== +idb@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/idb/-/idb-8.0.0.tgz#33d7ed894ed36e23bcb542fb701ad579bfaad41f" + integrity sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw== + ieee754@^1.1.12: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"