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ù)的資料請關注腳本之家其它相關文章!
相關文章
javascript實現(xiàn)的鼠標鏈接提示效果生成器代碼
javascript實現(xiàn)的鼠標鏈接提示效果生成器代碼...2007-06-06
VS2008中使用JavaScript調(diào)用WebServices
這篇文章主要介紹了VS2008中使用JavaScript調(diào)用WebServices,需要的朋友可以參考下2014-12-12

