<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
mapboxgl通過新增tiff圖層,解決小網格的fill圖層在地圖縮小時圖層不顯示問題
近期在專案中遇到這麼一個需求,需要在地圖上展示一組格網資料,格網大小為2m*2m
,地圖api
用的mapboxgl
。起初拿到這個需要感覺很easy,在地圖上新增一個fill
圖層就好啦。把格網面資料新增到地圖上之後,在大比例尺下顯示正常,但是當地圖層級小於15級時,渲染出的結果會消失。
簡單理一下原因,應該是在地圖縮小後,每個網格所佔的畫素太小,所以就消失了。
mapboxgl
在處理symbol
圖層的時候,會遇到點位自動避讓問題,導致部分點位不顯示。解決方法是把layout
中的icon-allow-overlap
設定為true
,這樣就相當於關閉了自動避讓功能,所有點圖示保持可見狀態。但是針對fill
圖層卻沒有這麼一個屬性。
但是這種情況又需要檢視資料,要如何實現呢?
首先分析下資料,我的原始資料是通過模型匯出的tiff
格式的柵格資料,然後在後臺根據tiff
格式資料中每個畫素所在行列號以及其灰度值生成帶屬性的格網資料,其中畫素的灰度值就是在渲染時需要分類展示的值。既然原始tiff
資料的灰度值就是所用的屬性值,那是不是直接新增到地圖就好了。接下來的解決方案就是看是否能直接用mapboxgl
直接載入tiff
資料,並渲染出自己想要的效果。
檢視mapboxgl
檔案,可以看到mapboxgl
支援image
圖層,只需傳入url和coordinates
// 新增至地圖 map.addSource('some id', { type: 'image', url: 'https://www.mapbox.com/images/foo.png', coordinates: [ [-76.54, 39.18], [-76.52, 39.18], [-76.52, 39.17], [-76.54, 39.17] ]});
可是,當我把地址換成tiff
資料時卻報錯了。下面為報錯內容:
Could not load image because of The source image could not be decoded.. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported
可以簡單理解為不支援tiff
格式。
既然mapboxgl
的image
圖層不支援tiff
格式,那是不是可以把tiff
資料匯出成png
呢,於是使用arcmap
開啟了tiff
資料,匯出資料格式也支援png
,但是在儲存時又報錯了。
經過分析,發現是tiff
資料波段數量的原因,我的這份資料波段數為1,從網上下載了一份測試資料,波段數為3,可以成功匯出。
在查詢相關解決方案的時候,看到這麼個工具,geotiff.js,可以通過js
解析tiff
資料並渲染,leaflet
有個擴充套件就是用的這個工具,https://github.com/stuartmatthews/leaflet-geotiff。檢視geotiff.js
相關檔案,發現其實用起來還是挺方便的,通過簡單的程式碼實現的我的需求。
先使用geotiff.js
解析tiff
資料,再配合使用canvas
繪製圖片匯出base64
格式資料,然後就可以使用新增到mapboxgl
圖層了。
核心程式碼如下:
async function getData() { GeoTIFF.fromUrl(url).then(tiff => { console.log(tiff) getImage(tiff) }); } async function getImage(tiff) { const image = await tiff.getImage(); let bbox = await image.getBoundingBox(); let data = await image.readRasters({ samples: rgbBands // 波段數量,一個波段:[0],三個波段:[2,1,0] }); let base64Image = getBase64Image(data) addToMapboxgl(base64Image) } function getBase64Image(data) { let thumbnailPixelHeight = data.height let thumbnailPixelWidth = data.width let canvas = document.createElement('canvas') canvas.width = thumbnailPixelWidth canvas.height = thumbnailPixelHeight let ctx = canvas.getContext("2d") let totalPixelCount = 0 for (let y = 0; y < thumbnailPixelHeight; y++) { for (let x = 0; x < thumbnailPixelWidth; x++) { let colour = 'rgb(0, 0, 0, 0)' // let the default be no data (transparent) // 根據灰度值所在範圍渲染顏色 if (data[0][totalPixelCount] > 0) { if (data[0][totalPixelCount] > 50 && data[0][totalPixelCount] <= 55) { colour = `rgb(15, 255, 0, 1)` } else if (data[0][totalPixelCount] > 55 && data[0][totalPixelCount] <= 60) { colour = `rgb(155, 255, 0, 1)` } else if (data[0][totalPixelCount] > 60 && data[0][totalPixelCount] <= 65) { colour = `rgb(255, 255, 0, 1)` } else { colour = `rgb(255, 255, 0, 1)` } } ctx.fillStyle = colour ctx.fillRect(x, y, 1, 1) totalPixelCount++ } } let canvasImage = canvas.toDataURL("image/png") return canvasImage } // 將圖片新增到地圖 function addToMapboxgl(image) { map.addSource('tiff-source', { "type": "image", "url": image, "coordinates": [ [114.425597191307, 38.1091563484708], [114.538187627939, 38.1091563484708], [114.538187627939, 37.9627378349512], [114.425597191307, 37.9627378349512] ] }); map.addLayer({ id: 'tiff-layer', 'type': 'raster', 'source': 'tiff-source', 'paint': { 'raster-fade-duration': 0 } }); }
本以為到這裡問題已經解決,但是在檢視地圖時,發現圖片圖層資料疊加到底圖有不小的偏移。
經過一番對比分析,發現原來是tiff
資料的座標系與地圖座標系不一致的導致的。我拿到的tiff
資料座標系為西安80的投影座標系,在展示時設定的為wgs84
地理座標系,所以會有偏差。既然是座標系問題,那就通過工具對tiff
檔案做下投影轉換。這裡用的是arcmap
,開啟ArcToolbox–>Data Management Tools–>Projections and Transformations–>Raster–>Project Raster
轉換之後會發現,資料的行列值也會發生變化,也就是tiff
圖片的大小和形狀都有所變化。
轉換前:
轉換後:
使用轉換後的資料再次解析,然後疊加到地圖,位置完全匹配。
通過嘗試發現,單獨的圖片展示時,由於圖片解析度固定,當地圖等級放大到一定程度圖片會被放大很多導致圖片模糊不清,展示效果不理想;單獨的格網面展示時,當地圖等級縮小到一定程度,面圖層則會消失,也就是文章開頭提到的問題。
綜上,根據自己的格網資料大小,判斷在哪個等級格網面資料會消失,小於這個等級使用圖片展示,大於這個等級用格網面展示,就可以完美的展示出想要的效果。
處理前效果:
處理後效果:
以上為有tiff
柵格資料情況的解決方案,針對於只有格網面資料,而沒有tiff
柵格資料的情況要怎麼解決呢?
如果在這組格網資料中,每個網格的屬性中有他所在原始tiff
資料的畫素位置,以及原始tiff
資料畫素大小,就可以寫一個類似上文中的getBase64Image方法,遍歷每個網格,在網格對應的畫素位置上繪製顏色,然後再通過canvas
匯出圖片新增到地圖。
mapboxgl
的image
圖層無法直接新增tiff柵格資料mapboxgl
新增fill
圖層時,地圖層級縮小到一定程度,面資料所佔畫素值過小無法顯示tiff
資料可以使用geotiff.js+canvas
解析,得到base64
的圖片,新增到mapboxgl
的image
圖層tiff
資料時,需注意它的座標系、波段個數等資訊image
圖層和fill
圖層結合展示,效果較好到此這篇關於mapboxgl載入tiff的文章就介紹到這了,更多相關mapboxgl載入tiff內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45