Offline-capable geomap, meant for storing location bookmarks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: issue where tiles don't render correctly

+30 -18
+28 -16
www/components/m-map.ts
··· 421 421 maxzoom: 24, 422 422 layout: { 423 423 'text-field': '{point_count_abbreviated}', 424 - 'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'], 424 + 'text-font': ['Noto Sans Regular'], 425 425 'text-size': 12, 426 426 }, 427 427 paint: { ··· 505 505 506 506 async #checkAvailableTile(): Promise<void> { 507 507 if (!this.#map) return 508 - const center = this.#map.getCenter() 509 508 const zoom = this.#map.getZoom() 510 509 511 - if (zoom < 5) { 510 + if (zoom < 7) { 512 511 this.#availableTile = null 513 512 this.requestUpdate() 514 513 return ··· 516 515 517 516 const manifest = await fetchTileManifest() 518 517 this.#tileManifest = manifest 518 + 519 + const viewport = this.#map.getBounds() 519 520 520 521 for (const tile of manifest) { 521 522 if (this.#map.getSource(tile.id)) continue 522 523 if (!tile.bounds) continue 523 524 const [w, s, e, n] = tile.bounds 524 - if ( 525 - center.lng >= w && center.lng <= e && center.lat >= s && center.lat <= n 526 - ) { 527 - const cached = await isPMTilesCached(tile.filename) 528 - if (!cached) { 529 - this.#availableTile = tile 530 - this.requestUpdate() 531 - return 532 - } 525 + // Only show when the tile's centroid is visible in the current viewport. 526 + // This prevents tiles with large bounds (e.g. Alaska) from showing a 527 + // download prompt when the user is actually looking at a distant region. 528 + const centroidLng = (w + e) / 2 529 + const centroidLat = (s + n) / 2 530 + if (!viewport.contains([centroidLng, centroidLat])) continue 531 + const cached = await isPMTilesCached(tile.filename) 532 + if (!cached) { 533 + this.#availableTile = tile 534 + this.requestUpdate() 535 + return 533 536 } 534 537 } 535 538 ··· 544 547 `/static/tiles/${this.#availableTile.filename}`, 545 548 this.#availableTile.filename, 546 549 ) 547 - await this.#loadCachedDetailTiles() 550 + await this.#loadCachedDetailTiles(this.#tileManifest) 551 + this.#ensureBookmarkLayersOnTop() 548 552 this.#availableTile = null 549 553 this.requestUpdate() 550 554 } catch (err) { ··· 622 626 } 623 627 } 624 628 625 - async #loadCachedDetailTiles(): Promise<void> { 629 + async #loadCachedDetailTiles( 630 + manifest?: TileManifestEntry[], 631 + ): Promise<void> { 626 632 if (!this.#map) return 627 - for (const tile of await fetchTileManifest()) { 633 + const tiles = manifest?.length ? manifest : await fetchTileManifest() 634 + // Insert regional layers below bookmark layers so bookmarks always 635 + // render on top regardless of when this is called. 636 + const beforeId = this.#map.getLayer('bookmarks-clusters') 637 + ? 'bookmarks-clusters' 638 + : undefined 639 + for (const tile of tiles) { 628 640 if (this.#map.getSource(tile.id)) continue 629 641 const pmtiles = await getCachedPMTiles(tile.filename) 630 642 if (!pmtiles) continue ··· 637 649 url: `pmtiles://${tile.filename}`, 638 650 }) 639 651 layers(tile.id).forEach((layer) => 640 - this.#map!.addLayer(layer as maplibregl.AddLayerObject) 652 + this.#map!.addLayer(layer as maplibregl.AddLayerObject, beforeId) 641 653 ) 642 654 } 643 655 }
+1 -1
www/models/app.ts
··· 25 25 } 26 26 27 27 const backend = new IDBStorage({ dbName: 'maps-store' }) 28 - const blobBackend = new IDBBlobStorage({ dbName: 'maps-blobs' }) 28 + const blobBackend = new IDBBlobStorage({ dbName: 'maps-store' }) 29 29 const blobStore = new BlobStore(blobBackend) 30 30 const store = new Store(backend, { 31 31 documents: ['preferences', 'searchHistory'],
+1 -1
www/utils/fs.ts
··· 1 1 import { PMTiles } from 'pmtiles' 2 2 import { IndexedDBSource } from 'pmtiles-offline' 3 3 4 - const DB_NAME = 'maps-offline' 4 + const DB_NAME = 'maps-data' 5 5 const STORE_NAME = 'tiles' 6 6 7 7 let _db: IDBDatabase | null = null