根据地图经纬度绘制 canvas 电子围栏【1】-文章-关尔先生

根据地图经纬度绘制 canvas 电子围栏【1】 前端

地图上的一小寸,是人类实际跨越的一大大大大……步

关尔先生2021-11-30 12:01:29
# 根据地图经纬度绘制 canvas 电子围栏 ## 第二版代码 [根据地图经纬度绘制 canvas 电子围栏【2】](https://www.nanshanqiao.com/zz_article/106.html) ## 画个坐标轴 ![根据地图经纬度绘制 canvas 电子围栏-画个坐标.png](/img.php?20211130ab22faf1899d3f9f76c417f5da3d7519.png) ## 坐标转换 把输入的经纬度坐标转换为显示在 canvas 上的坐标 ![根据地图经纬度绘制canvas电子围栏-坐标转换.jpg](/img.php?20211130c4b4b20e1e6425728304219bcb7336ac.jpeg) ## 坐标放大 地图上的一小寸,是人类实际跨越的一大大大大……步 比如 `A [39.075069,117.22905]` 和 `B [39.074902,117.22673]` ,两个坐标点的值相差的量级只有 `0.001`。 而 canvas 是最小显示是`1像素`。 所以要把坐标放大,比如 100 万倍: 39.075069117 × 1000000 - 39.074902117 × 1000000 = 167,就可以在 canvas 上显示出两个点的距离了。
1
2
3
4
// 转换 并 放大 原始坐标
area = area.map(p => {
return [p.x * scale + x0, (y0 - p.y) * scale];
});
![根据地图经纬度绘制canvas电子围栏-坐标放大.jpg](/img.php?2021113067c23230984964053b5217b70761068f.jpeg) 这样,解决了坐标值的差距问题,又出现了另一个问题:_ 看不见点了!_ 因为 canvas 的可见视野就是预设的 1000*800,如上图所示:蓝色框外都不可见!! ## 原点移动 ![根据地图经纬度绘制canvas电子围栏-原点平移.jpg](/img.php?20211130ee5fec6e83da600b29acff19076d066a.jpeg) 通过 ` ctx.translate(-xoffset, -yoffset);` 平移坐标原点,把经纬点所在的区域显示在视野里! ## 结果展示 最终结果是这样的(测试红点是不是在电子围栏内?) ![根据地图经纬度绘制canvas电子围栏2.png](/img.php?20211130b285526967be4ddcde1eba959fd5ec73.png) ## 在线 DEMO [经纬度转直角坐标-根据地图经纬度绘制 canvas 电子围栏](http://demo.nanshanqiao.com/canvas-lng-lat.html) ## 核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
let myCanvas = document.querySelector('canvas');
let ctx = myCanvas.getContext('2d');
//原始数据
let points = [{"x":39.047335,"y":117.203573}]; //检测点
let area = [{"x":39.075069,"y":117.22905},{"x":39.074902,"y":117.22673}...] // 电子围栏坐标
// 所有点
const ALL_POINT = [...points, ...area];
let xMax = Math.max(...ALL_POINT.map(e => e.x));
let xMin = Math.min(...ALL_POINT.map(e => e.x));
let yMax = Math.max(...ALL_POINT.map(e => e.y));
let yMin = Math.min(...ALL_POINT.map(e => e.y));
// 根据canvas宽高计算缩放级别 占坐标视野的2/3
let xScale = ((canvasWidth / 3) * 2) / (xMax - xMin); // 每1坐标占多少宽度
let yScale = ((canvasHeight / 3) * 2) / (yMax - yMin); // 每1坐标占多少宽度
let scale = Math.min(xScale, yScale);
// 计算canvas原点坐标偏移量 居中显示
let xoffset = xMin * scale - canvasWidth / 3 / 2;
let yoffset = (y0 - yMax) * scale - canvasHeight / 3 / 2;
ctx.translate(-xoffset, -yoffset);
// 计算当前坐标轴的原点,并在canvas上画出数值
const X00 = x0 + xoffset;
const Y00 = y0 + yoffset;
// drawPoint(X00, Y00);
console.log('X00,Y00 放大:', X00, Y00);
console.log('X00,Y00 实际', X00 / scale, y0 - Y00 / scale);
ctx.font = '14px Arial';
ctx.strokeText(`坐标原点:${X00 / scale},${y0 - Y00 / scale}`, X00 - 16, Y00 + 16);
// 转换并放大原始坐标
area = area.map(p => {
return [p.x * scale + x0, (y0 - p.y) * scale];
});
// 画多边形
drawArea(area);
// 画点
points.forEach(p => {
const xx = p.x * scale + x0;
const yy = (y0 - p.y) * scale;
drawPoint(xx, yy);
});
function drawArea(area) {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'blue';
area.forEach(([xx, yy], i) => {
if (i == 0) {
ctx.moveTo(xx, yy);
} else {
ctx.lineTo(xx, yy);
}
});
ctx.closePath();
ctx.stroke();
}
function drawPoint(xxx, yyy) {
ctx.beginPath();
ctx.lineWidth = 4;
ctx.strokeStyle = 'red';
ctx.moveTo(xxx, yyy);
ctx.lineTo(xxx + 2, yyy + 2); // 用一个短的线段表示点
ctx.closePath();
ctx.stroke();
}

地图经纬度canvas电子围栏坐标放大

上一篇:js判断点是否在多边形内部

下一篇:根据地图经纬度绘制 canvas 电子围栏【2】

本文链接: http://www.nanshanqiao.com/zz_article/105.html

暂无评论

评论