別 Zoom Level 全解析:從原理到離線底圖實(shí)戰(zhàn))
做 WebGIS 開發(fā)這幾年幾乎每個(gè)人都會(huì)碰到map.setZoom(14)這種代碼但真正被問(wèn)爆的問(wèn)題往往不是“怎么放大”而是“為什么我底圖顯示不全”“為什么放大到 15 級(jí)就黑屏”“為什么同一級(jí)別下不同數(shù)據(jù)源疊上去會(huì)錯(cuò)位”。這些問(wèn)題的根源幾乎都指向同一個(gè)概念地圖級(jí)別Zoom Level。這個(gè)小數(shù)字背后其實(shí)是一整套全球剖分、投影變換、瓦片索引和資源管理的規(guī)則。這篇文章就把 Zoom Level 從原理到實(shí)戰(zhàn)拆開講清楚特別是本地 PNG 瓦片、MBTiles 底圖這些離線地圖場(chǎng)景里怎么跟級(jí)別打交道。無(wú)論你是用 Leaflet、OpenLayers還是自己封裝地圖引擎這套邏輯都通用。1. Zoom Level 是什么從 0 級(jí)那張世界地圖說(shuō)起1.1 金字塔模型每放大一級(jí)瓦片數(shù)乘四地圖級(jí)別不是自由放大縮小的一個(gè)浮點(diǎn)數(shù)而是一套離散層級(jí)。大多數(shù) WebGIS 底圖采用“瓦片金字塔”模型0 級(jí)時(shí)整個(gè)地球平面被壓縮到一張 256×256 或 512×512 像素的圖片里到 1 級(jí)把上一級(jí)圖片均勻切成 2×2共 4 張瓦片2 級(jí)再切成 4×4共 16 張。每一級(jí)瓦片本身尺寸不變但覆蓋的地理范圍變成上一級(jí)的四分之一所以看起來(lái)越放越大、細(xì)節(jié)越來(lái)越多。核心公式要記牢在縮放級(jí)別為 z 時(shí)單邊長(zhǎng)方向的瓦片數(shù)量是 2^z整個(gè)層級(jí)瓦片總數(shù)是 4^z。聽起來(lái)很慢算一下就知道了z14 時(shí)單邊約 16384 張瓦片全層級(jí)總瓦片數(shù)達(dá)到 2.68 億。這個(gè)幾何級(jí)數(shù)的膨脹速度決定了 Zoom Level 不是“設(shè)多大都行”而是每一級(jí)都要付出存儲(chǔ)、帶寬和加載成本。我見過(guò)很多項(xiàng)目把 maxZoom 設(shè)到 22導(dǎo)致服務(wù)端預(yù)生成瓦片時(shí)磁盤爆滿這就是沒搞懂?dāng)?shù)量級(jí)增長(zhǎng)帶來(lái)的后果。1.2 Web Mercator 投影是瓦片能對(duì)齊的前提為什么全世界的 WebGIS 平臺(tái)在 Zoom Level 計(jì)算上能基本統(tǒng)一因?yàn)榻^大多數(shù)切片方案都建立在 Web Mercator 投影EPSG:3857之上。這個(gè)投影把地球近似成球體經(jīng)度從 -180 度到 180 度均勻映射到水平方向緯度從約 -85.05 度到 85.05 度截?cái)噙@樣全球范圍最終呈現(xiàn)為一個(gè)正方形。正方形才能均勻切成標(biāo)準(zhǔn)瓦片金字塔層級(jí)才能成立。用生活類比來(lái)說(shuō)Web Mercator 就是把地球這個(gè)“橘子”的皮剝下來(lái)強(qiáng)行壓成一張方紙。赤道附近變形很小越往兩極拉伸越夸張所以地圖上的格陵蘭看起來(lái)比非洲還大這不是 Bug而是這種投影的固有特性。WebGIS 選它不是因?yàn)樗鼛缀巫罹_而是因?yàn)樗屚咂吘壞芨袼貙?duì)齊緩存、傳輸、拼接都非常簡(jiǎn)單。需要提醒的是如果你的底圖數(shù)據(jù)是 WGS84 / EPSG:4326 直接切出來(lái)的跟標(biāo)準(zhǔn) 3857 切片的網(wǎng)格并不是一回事。很多新舊系統(tǒng)疊加錯(cuò)位查到最后就是投影基準(zhǔn)不一致。1.3 一個(gè)級(jí)別對(duì)應(yīng)多少米地面分辨率公式在 Web Mercator 下Zoom Level 跟地面分辨率每像素代表多少米直接相關(guān)計(jì)算公式可以寫成一個(gè)簡(jiǎn)單除法resolution(z) 156543.03392804097 / 2^z這里的 156543.03392804097 是怎么來(lái)的Web Mercator 把地球半徑近似為 6378137 米周長(zhǎng)約 40075016.686 米把它映射到 256 像素寬度于是 40075016.686 / 256 ≈ 156543.0339。如果你的瓦片是 512 像素基準(zhǔn)分辨率就要除以 512結(jié)果大約是 78271.5169。這種差異會(huì)直接影響后續(xù)比例尺換算不能混用。實(shí)際做項(xiàng)目時(shí)不需要背小數(shù)但要理解除法的含義。比如 0 級(jí)是約 156 公里每像素10 級(jí)大約是 152.87 米每像素16 級(jí)大約是 2.39 米每像素18 級(jí)則接近 0.6 米每像素??吹揭粋€(gè)需求寫“我要全市影像圖”你就能立刻估算出大致需要幾個(gè)級(jí)別以及最高需要切到多少級(jí)。2. 比例尺、分辨率與 Zoom Level 的換算2.1 從米/像素到“1:X”的屏幕比例尺客戶經(jīng)常拿著 CAD 圖紙來(lái)問(wèn)“我這里做到 1:1000地圖平臺(tái)里應(yīng)該用多少級(jí)”這就涉及 Zoom Level 和傳統(tǒng)比例尺的換算。屏幕上的比例尺不是簡(jiǎn)單地“圖上 1 厘米等于實(shí)地多少米”還要考慮屏幕 DPI每英寸像素?cái)?shù)。完整公式是scale resolution × dpi / 0.0254因?yàn)?1 英寸等于 0.0254 米。WebGIS 里通常按 96 DPI 計(jì)算這不是真實(shí)顯示器物理參數(shù)而是行業(yè)里的一種統(tǒng)一約定。舉個(gè)例子z15 時(shí)resolution 156543.0339 / 32768 ≈ 4.777 米/像素代入公式scale ≈ 4.777 × 96 / 0.0254 ≈ 18055也就是說(shuō)在 96 DPI 下z15 大致對(duì)應(yīng) 1:1.8 萬(wàn)比例尺。要接近 CAD 里說(shuō)的 1:1000通常得切到 z17 到 z18 左右。先算清楚這筆賬再去配置級(jí)別就不會(huì)憑感覺亂設(shè)了。2.2 常用 Zoom 級(jí)別速查表我整理了一張常用速查表統(tǒng)一按 256 像素瓦片、Web Mercator、96 DPI 計(jì)算。注意如果你的切圖工具輸出的是 512 像素瓦片分辨率和比例尺數(shù)值都要乘以 2實(shí)際項(xiàng)目里經(jīng)常有人忽略這一點(diǎn)結(jié)果把 1 級(jí)當(dāng)成 2 級(jí)用。Zoom Level單邊瓦片數(shù)地面分辨率m/px屏幕比例尺1:X常見用途01156.543 km約 59.2 萬(wàn)全球輪廓5324.892 km約 184.9 萬(wàn)省/州級(jí)別101024152.874 m約 57.8 萬(wàn)城市范圍14163849.555 m約 3611街道級(jí)別15327684.777 m約 1806街區(qū)地圖16655362.388 m約 903建筑輪廓171310721.194 m約 451小區(qū)內(nèi)部182621440.597 m約 226近似 1:1000 圖紙這張表的價(jià)值不在于背數(shù)字而在于反推決策。比如客戶要求類似 1:2000 的大比例尺底圖你對(duì)照表就應(yīng)該知道需要至少切到 z17再考慮到屏幕縮放和瀏覽器渲染穩(wěn)妥起見切到 z18。否則只切到 z15放大后必然糊。2.3 為什么地圖庫(kù)之間經(jīng)常出現(xiàn)“差一級(jí)”的現(xiàn)象很多人在 Leaflet 里加載天地圖或 ArcGIS 在線底圖發(fā)現(xiàn)同樣的截圖范圍、同樣的 level地圖大小明顯對(duì)不上。這不一定是代碼寫錯(cuò)更多是不同平臺(tái)采用了不同的切片方案和縮放錨點(diǎn)。Google 底圖、OSM 底圖的 0 級(jí)基本是同一套規(guī)則但國(guó)內(nèi)一些服務(wù)會(huì)把起始級(jí)別從 1 開始前端庫(kù)默認(rèn)從 0 開始加載后整體少一級(jí)。這種情況直接硬改前端代碼往往治標(biāo)不治本更靠譜的做法是去確認(rèn)切圖配置里的起始級(jí)別并直接在瀏覽器里請(qǐng)求0/0/0.png這個(gè) URL看是否存在有效的全球縮略圖一測(cè)就知道起始級(jí)別對(duì)不對(duì)。這里還要注意Leaflet 默認(rèn)支持非整數(shù) zoom比如 14.5。如果你的瓦片服務(wù)只有整數(shù)級(jí)別非整數(shù)縮放會(huì)讓瀏覽器在兩級(jí)之間插值看起來(lái)有點(diǎn)模糊還會(huì)增加瓦片請(qǐng)求量。所以在線航拍或底圖業(yè)務(wù)里我一般會(huì)把zoomSnap設(shè)置為 1禁止半級(jí)縮放避免用戶無(wú)意間放大到 14.5同時(shí)觸發(fā) 14 和 15 兩套瓦片的請(qǐng)求。3. 本地 PNG 瓦片與 MBTiles 底圖里的 Zoom Level3.1 本地 PNG 瓦片目錄文件系統(tǒng)就是金字塔WebGIS 項(xiàng)目里最常見的離線底圖形態(tài)就是本地 PNG 瓦片目錄路徑通常長(zhǎng)這樣tiles/ 0/ 0/ 0.png 1/ 0/ 0.png 1/ 0.png ...這里的z/x/y.png對(duì)應(yīng)著 Zoom Level、橫向列號(hào)、縱向行號(hào)。文件系統(tǒng)本身就是一座瓦片金字塔前端加載時(shí)把 URL 拼接成tiles/{z}/{x}/{y}.png就行。不過(guò)這里有一個(gè)特別容易踩的坑XYZ 規(guī)范和 TMS 規(guī)范的 y 軸方向是反的。XYZ 的 y 從左上角開始往下增長(zhǎng)TMS 的 y 從左下角開始往上增長(zhǎng)兩者的換算關(guān)系是tms_y 2^z - 1 - xyz_y注意這個(gè)公式里必須有 z 參與計(jì)算因?yàn)槊恳患?jí)的 y 范圍不同。我剛開始給 Leaflet 接某個(gè)切圖工具時(shí)默認(rèn)它就是 XYZ結(jié)果加載出來(lái)的地圖上下顛倒排查半天才發(fā)現(xiàn)工具輸出的是 TMS 切片。后來(lái)我養(yǎng)成了習(xí)慣切圖完成后先看0/0/0.png再看相鄰幾個(gè)瓦片的拼接效果能少走很多彎路。3.2 MBTiles用 SQLite 把每個(gè)級(jí)別裝進(jìn)一個(gè)文件MBTiles 是 Mapbox 提出的一種瓦片包規(guī)范本質(zhì)是一個(gè) SQLite 數(shù)據(jù)庫(kù)文件。核心表tiles中包括zoom_level、tile_column、tile_row、tile_data四個(gè)字段metadata表里記錄format、minzoom、maxzoom、bounds、scheme等信息。你看連表結(jié)構(gòu)設(shè)計(jì)都以zoom_level作為關(guān)鍵索引可見 Zoom Level 是整個(gè)瓦片存取的核心維度。用 MBTiles 最大的好處是單文件管理。舉個(gè)例子一個(gè)城市的 PNG 瓦片目錄可能有幾萬(wàn)個(gè)零碎文件拷貝到 U 盤、上傳到服務(wù)器都很慢而且大量小文件會(huì)占用 inode。打包成 MBTiles 后只有一個(gè).mbtiles文件遷移、備份、分發(fā)都極其方便。桌面端離線地圖、移動(dòng)端離線包以及很多產(chǎn)品內(nèi)置的 GIS 數(shù)據(jù)都偏愛這種格式。這里提一下MBTiles 里瓦片行號(hào)一般存 TMS 規(guī)范的行號(hào)也就是從南到北增長(zhǎng)前端讀取時(shí)要注意轉(zhuǎn)換。3.3 本地 PNG 目錄和 MBTiles 怎么選選擇方案不是看哪個(gè)“高級(jí)”而是看使用場(chǎng)景。對(duì)比項(xiàng)本地 PNG 瓦片目錄MBTiles文件形式多層級(jí)目錄、零散文件單文件 SQLite部署到 Nginx/CDN方便URL 直接對(duì)應(yīng)文件需要加一層讀取服務(wù)離線分發(fā)/拷貝小文件多效率低單文件秒級(jí)拷貝瀏覽器直接加載直接拼 URL需要服務(wù)端或動(dòng)態(tài)讀取更新維護(hù)可單獨(dú)替換某級(jí)某張瓦片需要重新生成或修改庫(kù)元信息管理無(wú)內(nèi)建機(jī)制metadata 表天然保存級(jí)別、范圍等我個(gè)人的常見組合是開發(fā)環(huán)境用本地 PNG方便調(diào)試正式交付或離線場(chǎng)景用 MBTiles減少運(yùn)維負(fù)擔(dān)。轉(zhuǎn)換工具方面可以用mbutil把目錄導(dǎo)入 MBTiles也可以用 GDAL 的相關(guān)工具但不管用什么轉(zhuǎn)換完成后一定要檢查metadata表里的minzoom和maxzoom這是后面配置前端級(jí)別的唯一依據(jù)。3.4 給離線底圖設(shè)置正確的 minZoom / maxZoom / maxNativeZoom這里是我看過(guò)最多項(xiàng)目翻車的地方。比方說(shuō)服務(wù)器只切了 0 到 14 級(jí)瓦片但前端代碼把maxZoom設(shè)成 20用戶放大到 15 級(jí)以后看到的不是黑塊就是空白。更隱蔽的是有的底圖切到了 18 級(jí)但你只設(shè)置了maxZoom: 18Leaftlet 默認(rèn)會(huì)在超過(guò) 18 級(jí)時(shí)停止加載看起來(lái)沒問(wèn)題可一旦地圖允許縮放到 20它就會(huì)嘗試請(qǐng)求 19、20 級(jí)而這些瓦片根本不存在。對(duì)策很明確如果底圖只有 14 級(jí)就把maxZoom設(shè)置成 14如果希望用戶能繼續(xù)擴(kuò)大視野但不想黑屏就設(shè)置maxNativeZoom: 14、maxZoom: 18這樣高于 14 級(jí)時(shí)瀏覽器會(huì)拉伸原生層級(jí)的瓦片清晰度會(huì)下降但至少不會(huì)白屏。實(shí)際項(xiàng)目里我用得最多的做法是maxNativeZoom等于切圖最大級(jí)別maxZoom則根據(jù)交互需要適當(dāng)放大同時(shí)給瓦片圖層加一個(gè) “加載失敗時(shí)不重復(fù)請(qǐng)求” 的容錯(cuò)策略盡量不把錯(cuò)誤暴露給用戶。4. Zoom Level 相關(guān)的坑與性能調(diào)優(yōu)4.1 瓦片錯(cuò)位、花屏先查原點(diǎn)、坐標(biāo)和規(guī)范瓦片出問(wèn)題時(shí)我建議先按順序排查三件事切圖原點(diǎn)是否正確、坐標(biāo)系是否統(tǒng)一、瓦片命名是否規(guī)范。標(biāo)準(zhǔn) Web 墨卡托切圖原點(diǎn)一般在地圖左上角也就是經(jīng)度 -180 度、緯度約 85.05 度的位置。如果某些工具從 (0,0) 或者其他原點(diǎn)開始切瓦片坐標(biāo)就會(huì)整體偏移。更常見的是坐標(biāo)系不統(tǒng)一。數(shù)據(jù)源是 WGS84 經(jīng)緯度底盤服務(wù)是 GCJ-02 坐標(biāo)切圖模板卻按 3857 瓦片網(wǎng)格生成最后疊加后整個(gè)地圖像被“平移”過(guò)一樣。這里要強(qiáng)調(diào)一點(diǎn)坐標(biāo)轉(zhuǎn)換只能保證幾何位置正確不能保證瓦片邊界和緩存網(wǎng)格對(duì)齊。切圖之前必須明確整個(gè)鏈路統(tǒng)一使用 EPSG:3857或者統(tǒng)一使用 4326 的等距圓柱投影網(wǎng)格不要在中間隨意混用。4.2 跨級(jí)放大的瓦片請(qǐng)求爆炸同一地理范圍下z 每增加一級(jí)橫向和縱向的瓦片數(shù)各翻一倍總數(shù)翻四倍。從 z14 放大到 z18差 4 級(jí)同一范圍瓦片數(shù)量相差 4^4 256 倍。如果用戶操作很快瀏覽器可能瞬間發(fā)出幾十上百個(gè)圖片請(qǐng)求底圖加載自然變慢。優(yōu)化手段我一般分三層第一層前端控制交互比如合理設(shè)置zoomSnap和minZoom/maxZoom避免無(wú)意義的半級(jí)和過(guò)深縮放第二層加緩存包括瀏覽器 HTTP 緩存、Nginx 緩存和服務(wù)端瓦片緩存讓重復(fù)訪問(wèn)直接命中第三層降低首屏壓力進(jìn)入頁(yè)面時(shí)不要從 0 級(jí)一級(jí)一級(jí)加載直接把視野定位到業(yè)務(wù)關(guān)注的級(jí)別。本地 PNG 目錄部署時(shí)還要注意 404 請(qǐng)求瓦片缺失時(shí)返回的 404 頁(yè)面如果很大會(huì)白白消耗帶寬最好統(tǒng)一返回一個(gè)空的 1×1 PNG 或設(shè)置更短的緩存時(shí)間。4.3 多源底圖疊加級(jí)別對(duì)齊是第一原則項(xiàng)目里經(jīng)常要疊加多套底圖比如一個(gè) BIM 模型覆蓋到天地圖影像上或者把本地 MBTiles 疊加到在線 OSM 上。多源疊加時(shí)最讓頭疼的是同一 Zoom Level 下兩組瓦片范圍不一致。這種問(wèn)題多半不是級(jí)別本身而是兩個(gè)源的切片網(wǎng)格不統(tǒng)一。最穩(wěn)妥的方法是先把所有源都轉(zhuǎn)到同一投影默認(rèn)就用 EPSG:3857并使用同一套瓦片網(wǎng)格參數(shù)。OpenLayers 里可以自定義TileGridLeaflet 里則盡量使用統(tǒng)一 CRS。實(shí)際操作時(shí)我會(huì)先拉一個(gè)很小的試驗(yàn)區(qū)把兩個(gè)圖層都開到相同級(jí)別用半透明方式疊著看邊界重合了再繼續(xù)做整體。盲目相信“都是標(biāo)準(zhǔn) Web Mercator”有時(shí)候會(huì)吃大虧因?yàn)槟承┰诰€服務(wù)的“標(biāo)準(zhǔn)”并不完全等同于開源的 XYZ 網(wǎng)格。4.4 常見問(wèn)題排查實(shí)錄Zoom Level 問(wèn)題速查表故障現(xiàn)象診斷思路推薦解決方式放大地圖后出現(xiàn)黑塊高等級(jí)瓦片不存在或請(qǐng)求 404檢查切圖最大級(jí)別在代碼里設(shè)maxNativeZoom地圖上下顛倒瓦片源是 TMS前端按 XYZ 加載反轉(zhuǎn) ytms_y 2^z - 1 - xyz_y或設(shè)置 tms:true左右偏移/整體錯(cuò)位切圖原點(diǎn)、投影基準(zhǔn)不一致統(tǒng)一 EPSG:3857 和標(biāo)準(zhǔn)左上角原點(diǎn)放大后圖像模糊低級(jí)別瓦片被拉伸展示接受拉伸或加深切圖級(jí)別平衡存儲(chǔ)級(jí)別越高加載越慢瓦片請(qǐng)求數(shù)量級(jí)增長(zhǎng)緩存不足設(shè)置 zoomSnap、加 HTTP 緩存、預(yù)加載當(dāng)前范圍MBTiles 讀取失敗metadata 缺 minzoom/maxzoom用 SQLite 工具檢查元數(shù)據(jù)缺則手動(dòng)補(bǔ)充0 級(jí)瓦片無(wú)法顯示起始級(jí)別不是 0或者切片范圍不完整瀏覽器直接訪問(wèn) 0/0/0.png確認(rèn)最小級(jí)別這些坑不是靠“改一個(gè)數(shù)字”能解決的而是要在架構(gòu)層面把 Zoom Level 當(dāng)作一條貫穿始終的規(guī)則線從切圖、存儲(chǔ)到前端設(shè)置都保持一致。5. 實(shí)操用本地 PNG 瓦片 MBTiles 搭一套離線底圖5.1 切圖之前先確定級(jí)別范圍實(shí)操前最該做的事不是打開切圖工具而是定范圍。給一個(gè)城市做規(guī)劃展示我通常這樣切全市范圍 z10 到 z16重點(diǎn)片區(qū)再單獨(dú)切 z17 到 z18。z10 大概能看到區(qū)縣邊界z16 能看到街道z18 已經(jīng)接近 1:1000 圖紙表達(dá)精度。如果客戶要求更高再對(duì)重點(diǎn)區(qū)域加密切而不是盲目把全市都切到 z19。因?yàn)槊慷嘁患?jí)數(shù)據(jù)量和切圖時(shí)間都翻四倍準(zhǔn)備工作不做好后面磁盤吃緊是常事。切圖工具方面GDAL2Tiles、MapTiler、QGIS 都能輸出標(biāo)準(zhǔn)的本地 PNG 瓦片。選擇工具時(shí)務(wù)必確認(rèn)它能設(shè)置輸出格式為 XYZ 或 TMS并記錄好minzoom/maxzoom。有些工具默認(rèn)把視圖范圍綁定在某個(gè) bbox 上導(dǎo)致輸出目錄的起始瓦片坐標(biāo)不是 (0,0)這種情況就要手動(dòng)補(bǔ)充網(wǎng)格參數(shù)。5.2 本地 PNG 方式Leaflet 加載的關(guān)鍵配置用 Leaflet 加載本地 PNG 瓦片代碼看起來(lái)很簡(jiǎn)單但幾個(gè)參數(shù)必須認(rèn)真對(duì)待const map L.map(map, { center: [28.5, 111.2], zoom: 14, minZoom: 10, maxZoom: 18, zoomSnap: 1 }); L.tileLayer(tiles/{z}/{x}/{y}.png, { minZoom: 10, maxZoom: 18, maxNativeZoom: 18, tms: false }).addTo(map);這里tms: false表示使用 XYZ 規(guī)則也就是 y 從左上角開始如果你的瓦片來(lái)自 TMS 規(guī)范改成true后 Leaflet 會(huì)自動(dòng)處理 y 軸反轉(zhuǎn)省去手寫換算。maxNativeZoom: 18和maxZoom: 18完全一致時(shí)系統(tǒng)不會(huì)做拉伸如果底圖只有 14 級(jí)我會(huì)把maxNativeZoom設(shè)成 14maxZoom設(shè)成 18這樣放大到 15 級(jí)以上時(shí)用的是低級(jí)別拉伸圖視覺上變糊但不會(huì)黑屏。5.3 轉(zhuǎn)成 MBTiles 并加載本地 PNG 目錄轉(zhuǎn) MBTiles常用工具是mbutil。命令很簡(jiǎn)單mb-util tiles output.mbtiles生成之后先用 SQLite 工具檢查元數(shù)據(jù)SELECT * FROM metadata;正常情況下你會(huì)看到類似minzoom10、maxzoom18、formatpng、schemetms的記錄。如果scheme是 tms后續(xù)讀取瓦片時(shí)要記得反轉(zhuǎn) y。前端加載時(shí)最簡(jiǎn)單的做法是用 TileServer GL 或自寫一個(gè)瓦片服務(wù)把 MBTiles 暴露成標(biāo)準(zhǔn)的{z}/{x}/{y}.pngURLtileserver-gl --file output.mbtiles --port 8080然后前端把瓦片地址指到http://localhost:8080/data/v3/{z}/{x}/{y}.png即可。如果項(xiàng)目要求完全離線純?yōu)g覽器端直接讀取大型 MBTiles 并不推薦因?yàn)?SQLite 文件可能上百 MB把整個(gè)庫(kù)加載進(jìn)瀏覽器內(nèi)存非常吃力。更穩(wěn)妥的方案是 PWA 緩存或封裝一個(gè)輕量本地服務(wù)。5.4 驗(yàn)證 Zoom Level 配沒配對(duì)的黃金方法配置完成后不要急著疊業(yè)務(wù)圖層先做 30 秒的瓦片驗(yàn)證。打開瀏覽器開發(fā)者工具切到 Network 面板過(guò)濾圖片請(qǐng)求然后連續(xù)放大、縮小、平移。正常情況下URL 中的 z 應(yīng)該連續(xù)變化同一區(qū)域在不同 z 之間能無(wú)縫銜接區(qū)域內(nèi)不會(huì)出現(xiàn)半塊缺失或錯(cuò)位。如果發(fā)現(xiàn)某一級(jí)直接空白優(yōu)先檢查該級(jí)別瓦片目錄是否存在。我還會(huì)直接訪問(wèn)http://localhost:8080/tiles/0/0/0.png看能否返回 256 像素的全球縮略圖。如果 404說(shuō)明切圖工具起始級(jí)別不是 0或者范圍配置有問(wèn)題。這類問(wèn)題越早發(fā)現(xiàn)越好等業(yè)務(wù)圖層都疊上再排查難度翻倍。6. 寫在最后幾個(gè)關(guān)于 Zoom Level 的個(gè)人經(jīng)驗(yàn)做項(xiàng)目久了會(huì)發(fā)現(xiàn) Zoom Level 遠(yuǎn)不只是地圖庫(kù)里的一個(gè)參數(shù)。它隱藏在切圖報(bào)價(jià)、硬盤容量、帶寬預(yù)估、加載速度、數(shù)據(jù)疊加精度里。我現(xiàn)在的習(xí)慣是任何 WebGIS 項(xiàng)目動(dòng)手前先問(wèn)“要展示到多細(xì)”再倒推出minZoom和maxZoom再?zèng)Q定用 PNG 目錄還是 MBTiles上線前一定會(huì)用 Network 面板把瓦片請(qǐng)求拉一遍確認(rèn) URL 中的 z/x/y 連續(xù)且正確尤其是換了切圖工具之后。還有一個(gè)小技巧如果你負(fù)責(zé)的底圖數(shù)據(jù)源經(jīng)常更新比如影像地圖每季度換一次建議把瓦片金字塔設(shè)計(jì)成“穩(wěn)定級(jí)別 動(dòng)態(tài)級(jí)別”兩層。穩(wěn)定級(jí)別用 MBTiles 打包長(zhǎng)期復(fù)用動(dòng)態(tài)級(jí)別從在線服務(wù)拉取并疊加這樣既保證性能又不會(huì)每次更新都重新切一遍所有級(jí)別。Zoom Level 這個(gè)概念的延展性其實(shí)很強(qiáng)從柵格瓦片到矢量瓦片從離線包到云服務(wù)真正吃透之后你在 WebGIS 很多疑難問(wèn)題上的排查速度會(huì)明顯快一截。