Canvas中繪制Geojson數(shù)據(jù)示例詳解
需求分析
在做地圖開發(fā)的時候遇到一個需求,是在 canvas
中繪制 Geojson
數(shù)據(jù)
數(shù)據(jù)格式為 EPSG:4326
的 Polygon
:
- 三維數(shù)組
- 每一項都是由經(jīng)緯度組成的
- 第一個點和最后一個點相同,表示
Polygon
是閉合的
[ [ [109.54420471485196, 35.76192112844663], [109.54423617129702, 35.76132766033574], [109.54539219590997, 35.76155739029704], [109.54521918540507, 35.76241249100947], [109.54420471485196, 35.76192112844663], ], ];
需求分析:
- 顯示在
canvas
的中間 - 地圖
y
軸和屏幕的y
軸是相反的,繪制出來的Polygon
不能和實際反過來- 屏幕的原點在左上角,地圖的原點在左下角
數(shù)據(jù)處理
width
和 height
是 canvas
的寬高
將經(jīng)度和緯度單獨拆分出來
const getLongitudesAndLatitudes = (coordinates: number[][][]) => { return coordinates[0].reduce( (pre, cur) => { pre.longitudes.push(cur[0]); pre.latitudes.push(cur[1]); return pre; }, { longitudes: [] as number[], latitudes: [] as number[] } ); };
得到的結果是:
const longitudes = [
109.54420471485196, 109.54423617129702, 109.54539219590997,
109.54521918540507, 109.54420471485196,
];
const latitudes = [
35.76192112844663, 35.76132766033574, 35.76155739029704, 35.76241249100947,
35.76192112844663,
];
計算縮放比例
用 width / (Math.max(longitudes) - Math.min(longitudes))
的作用計算 Polygon
的 x
軸縮放比例 xScale = 67369.49567346855
height
同理,計算出 y
軸的縮放比例 yScale = 12905.23981205731
總的縮放比例 scale
采用 xScale
、yScale
誰小用誰,為 scale = 12905.23981205731
,因為用小的縮放比例,才能在有限的空間下顯示全
const calcScale = ({ longitudes, latitudes, }: { longitudes: number[]; latitudes: number[]; }) => { const xScale = width / Math.abs(Math.max(...longitudes) - Math.min(...longitudes)); const yScale = height / Math.abs(Math.max(...latitudes) - Math.min(...latitudes)); return xScale < yScale ? xScale : yScale; };
計算偏移度
(Math.max(longitudes) - Math.min(longitudes)) * scale
作用是將經(jīng)度按照 scale
進行縮放,緯度也是同理
在用 width
和 height
去減,分別得到要 x
軸和 y
軸需要偏移的空間
這些空間要分布在兩邊,也就是說要分布 Polygon
的周圍,所以左后需要除 2
,最終得到 xOffset = 32.33763608704606
,yOffset = -8.881784197001252e-16
const calcOffset = ( { longitudes, latitudes }: { longitudes: number[]; latitudes: number[] }, scale: number ) => { const xOffset = (width - Math.abs(Math.max(...longitudes) - Math.min(...longitudes)) * scale) / 2; const yOffset = (height - Math.abs(Math.max(...latitudes) - Math.min(...latitudes)) * scale) / 2; return { xOffset, yOffset }; };
將 Coordinates 進行縮放
對 coordinates
縮放一共分為 3
步
比較難理解的是第一步,為什么要將每個點去減它的最小值 item[0] - Math.min(...longitudes)
這樣做的目的是為了那個點無限接近于原點,接近原點后,再通過乘以縮放比例和加上偏移度,得到最終的的縮放值
在需求分析時說了,屏幕的原點在左上角,地圖的原點在左下角,所以 y
軸是剛好是相反,y
軸就用 Math.max(...latitudes) - item[1]
const scaleCoordinates = ( coordinates: number[][][], scale: number, offset: ReturnType<typeof calcOffset>, { longitudes, latitudes }: { longitudes: number[]; latitudes: number[] } ) => { return coordinates[0] .map((item) => { item[0] = item[0] - Math.min(...longitudes); item[1] = Math.max(...latitudes) - item[1]; return item; }) .map((item) => { item[0] = item[0] * scale; item[1] = item[1] * scale; return item; }) .map((item) => { item[0] = item[0] + offset.xOffset; item[1] = item[1] + offset.yOffset; return item; }); };
使用 Canvas 進行繪制
const canvas = document.getElementById("canvas"); if (!canvas.getContext) return; const ctx = canvas!.getContext("2d")!; ctx.fillStyle = "rgba(32, 210, 255, 0.3)"; ctx.strokeStyle = "rgba(32, 210, 255, 1)"; ctx.beginPath(); ctx.moveTo(coordinates[0][0], coordinates[0][1]); for (let i = 1; i < coordinates.length; i++) { ctx.lineTo(coordinates[i][0], coordinates[i][1]); } ctx.closePath(); ctx.stroke(); ctx.fill();
存在問題
無法區(qū)分 Polygon
大小,所以這個方案適用于繪制縮略圖
以上就是Canvas中繪制Geojson數(shù)據(jù)示例詳解的詳細內(nèi)容,更多關于Canvas繪制Geojson數(shù)據(jù)的資料請關注腳本之家其它相關文章!
相關文章
JS使用AudioContext實現(xiàn)音頻流實時播放
這篇文章主要為大家詳細介紹了JavaScript如何使用AudioContext實現(xiàn)音頻流實時播放功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-01-01javaScript矢量圖表庫-gRaphael幾行代碼實現(xiàn)精美的條形圖/餅圖/點圖/曲線圖
gRaphael是一個致力于幫助開發(fā)人員在網(wǎng)頁中繪制各種精美圖表的 Javascript庫,你只需要編寫幾行簡單的代碼就能創(chuàng)建出精美的條形圖、餅圖、點圖和曲線圖,感興趣的朋友可以了解下2013-01-01Next.js應用轉(zhuǎn)換為TypeScript方法demo
這篇文章主要為大家介紹了Next.js應用轉(zhuǎn)換為TypeScript方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12小程序?qū)崿F(xiàn)頁面跳轉(zhuǎn)與數(shù)據(jù)傳遞方案
在開發(fā)過程中經(jīng)常會遇到在微信小程序的頁面跳轉(zhuǎn)以及數(shù)據(jù)傳遞的知識點,所以下面這篇文章主要給大家介紹了關于小程序?qū)崿F(xiàn)頁面跳轉(zhuǎn)與數(shù)據(jù)傳遞的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-09-09