地图可视化,根据绘制的图形生成缩略图,经纬度转换二维canvas坐标系
一、h5在做可视化地图时,用高德地图绘制空域(圆形,线,多边形),碰到一个需求,根据绘制出来的图形给对应的空域列表项添加一个缩略图。
二、确定实现方法
要根据绘制的图形生成对应图形的缩略图,有两种方式,一是使用高德地图给每个列表项绘制对应的图形,二是自己实现。第一种方法性能差,要是自己实现,我这边选择的是canvas画布。难点:后台返回的是经纬度数据不是canvas坐标系数据,我们需要根据经纬度转化为我们所设计的画布大小的坐标系数据。
三、代码实现
import React, { useRef, useEffect, useState } from "react";
export default function GeneratePolygon({ type, coordinates }) {
const canvasRef = useRef(null);
const [context, setContext] = useState(null);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
// console.log('ctx',ctx)
// 设置Canvas大小
canvas.width = 100;
canvas.height = 100;
// 将经纬度转换为Canvas坐标
const toCanvasCoords = (lng, lat) => {
// debugger;
if (coordinates.length && coordinates.length > 1) { // length为1为圆否则就是多边形和线
const lons = coordinates.map((item) => item.lng);
const lats = coordinates.map((item) => item.lat);
const lonMax = Math.max(...lons);
const lonMin = Math.min(...lons);
const latMax = Math.max(...lats);
const latMin = Math.min(...lats);
const lonScale = lonMax === lonMin ? 1 : canvas.width / (lonMax - lonMin);
const latScale = latMax === latMin ? 1 : canvas.height / (latMax - latMin);
// 不让图形超出和贴边,x=0 x=100,y=0 y=100两种情况时自己挪一点
const x = ((lng - lonMin) * lonScale) == 0 ? 2 : ((lng - lonMin) * lonScale)>= canvas.width ? canvas.width-2 : (lng - lonMin) * lonScale;
const y = (canvas.height - (lat - latMin) * latScale) == 0 ? 2 : (canvas.height - (lat - latMin) * latScale) >= canvas.height ? canvas.height-2 : canvas.height - (lat - latMin) * latScale;
if(lonMax === lonMin){
return {x: canvas.width/2, y}
}else if(latMax === latMin){
return {x, y: canvas.height/2}
}else{
return { x, y };
}
} else {
return { x: canvas.width / 2, y: canvas.height / 2 };
}
};
// 根据type绘制不同的图形
if (type === "2" && coordinates && coordinates.length > 1) {
ctx.beginPath();
coordinates.forEach((coord) => {
const { x, y } = toCanvasCoords(coord.lng, coord.lat);
if (ctx._firstPoint === undefined) {
ctx._firstPoint = { x, y };
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
});
// 闭合多边形路径
ctx.lineTo(
toCanvasCoords(coordinates[0].lng, coordinates[0].lat).x,
toCanvasCoords(coordinates[0].lng, coordinates[0].lat).y
);
ctx.fillStyle = "rgba(5,95,231,0.20)"; // 填充色
ctx.strokeStyle = "#055FE7"; // 边框色
ctx.lineWidth = 2;
ctx.scale(1, 1);
ctx.stroke();
ctx.fill();
} else if (type === "1" && coordinates && coordinates.length === 1) {
const { lng, lat } = coordinates[0]; // 获取圆心的经纬度
const cx = toCanvasCoords(lng, lat).x;
const cy = toCanvasCoords(lng, lat).y;
ctx.beginPath();
ctx.arc(cx, cy, 45, 0, Math.PI * 2); // 绘制圆形
ctx.fillStyle = "rgba(5,95,231,0.20)"; // 填充色
ctx.strokeStyle = "#055FE7"; // 边框色
ctx.lineWidth = 2;
ctx.stroke();
ctx.fill();
} else if (type === "3" && coordinates && coordinates.length) {
ctx.beginPath();
coordinates.forEach(coord=>{
ctx.lineTo(toCanvasCoords(coord.lng, coord.lat).x, toCanvasCoords(coord.lng, coord.lat).y);
})
ctx.strokeStyle = "#055FE7";
ctx.lineWidth = 2;
ctx.stroke();
}
setContext(ctx);
}, [type, coordinates]); // 依赖type和coordinates的变化来重绘
return (
<canvas
ref={canvasRef}
style={{ height: "100px", width: "100px" }}
/>
);
}
四、使用
<GeneratePolygon
type={item?.type}
coordinates={
item?.polygonPoint ? JSON.parse(item?.polygonPoint) : []
}
/>
五、效果


这样就生成了相对应的缩略图了,需要注意的是要处理坐标的边界值问题,不然会有贴边效果不太好看,over。
地图可视化,根据绘制的图形生成缩略图,经纬度转换二维canvas坐标系的更多相关文章
- C#生成带logo的二维码
带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码. 生成的二维码效果如下: 下面直接贴出二维码生成类 QRCode ...
- C#+ZXing.dll生成手机路径导航二维码
1.原谅我先写点废话哈 这两天用C#写一个C端的软件,甲方提出一个很无理的需求(在C端的程序中实现路径导航,关键是这个程序最终是运行在物理隔绝的电脑上的……),头疼了好几天,领导突然想到可以把坐标+百 ...
- js生成带参的二维码
最近项目中有需求生成带参的二维码,考虑过用JAVA后台生成返回前端展示,后面了解到用jquery的qrcode.js插件可以很好现实 引入js: require.config({ baseUrl : ...
- .NET使用ZXing.NET生成中间带图片的二维码
很久之前就有写这样的代码了,只是一直没记录下来,偶然想写成博客. 把之前的代码封装成函数,以方便理解以及调用. 基于开源的 ZXing.NET 组件,代码如下: 先添加对ZXing.NET的引用,然后 ...
- .NET生成带Logo的二维码
使用ThoughtWorks.QRCode生成,利用这个库来生成带Logo的二维码(就是中间嵌了一个图片的二维码),直接见代码: HttpContext context = HttpContext.C ...
- C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(二)
1.使用ZXint.Net生成带logo的二维码 /// <summary> /// 生成带Logo的二维码 /// </summary> /// <param name ...
- 微信公众号生成带参数的二维码asp源码下载
晚上闲着没事,一个朋友联系,让帮忙写一个微信公众号利用asp生成带参数的二维码,别人扫了后如果已经关注过该公众号的,则直接进入公众号里,如果没关注则提示关注,关注后自动把该微信用户资料获取到并且保存入 ...
- js实现生成中间带图片的二维码
之前需要实现生成中间带图片的二维码,所以找了半天终于找到一个可以用的.于是在这里记录一下. 下面是需要注意的几点: 1.使用的js为jquery-qrcode 但是已经经过别人的修改,和网上原来的那些 ...
- PHP生成有背景的二维码图,摘自网络
有一天产品MM高高兴兴的走过来,兴奋的和我分享她想出来的一个新的idea. 产品MM:你看这个(她指了指她的手机),一脸兴奋 那是一张带着二维码的图片,内容如下: 她接着说:如果我们的分销也能做成类似 ...
- C# 生成 DataMatrix 格式的二维码
该文主要是利用OnBarcode.dll 生成 DataMatrix 格式的二维码的一些简单方法和操作技巧.关于QrBarcode的二维码比较常见和简单,网上有很多资源. 1.附件为dll 2.利用上 ...
随机推荐
- Could not retrieve transation read-only status server 的解决办法
问题描述: 在项目开发的过程中,使用Hibernate的ORM进行建表时,出现 " Could not retrieve transation read-only status server ...
- 聊一聊 C#线程池 的线程动态注入 (下)
一:背景 1. 讲故事 前面二篇我们聊到了 Thread.Sleep 和 Task.Result 场景下的线程注入逻辑,在线程饥饿的情况下注入速度都不是很理想,那怎么办呢?有没有更快的注入速度,这篇作 ...
- Powercat 无文件落地执行技巧,你确定不进来看看?
声明:本文主要用作技术分享,所有内容仅供参考.任何使用或依赖于本文信息所造成的法律后果均与本人无关.请读者自行判断风险,并遵循相关法律法规. 目录 完整示例 注意事项 演示 无文件落地执行(filel ...
- modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持
一.前言说明 搞物联网开发很多年,用的最多的当属modbus协议,一个稳定好用的物联网组件是物联网平台持续运行多年的基石,所以这个物联网组件从一开始就定位于自研,为了满足各种场景的需求,当然最重要的一 ...
- Qt开源作品33-图片开关控件
一.前言 进入智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ.360卫士.金山毒霸等,都有很多开关控制一些操作,在WINFORM项目上,如 ...
- [转]idea中创建maven的Javaweb工程并进行配置(图文教程)
原文链接: idea中创建maven的Javaweb工程并进行配置(图文教程)
- Object.freeze冻结属性和v-if结合requestAnimationFrame分帧渲染解决白屏
计算100W条数据的长度造成2s延迟 <template> <div> <h1>数据总长度{{ arrList.length }}</h1> </ ...
- Java中hashCode() 和 equals()
该文章为转载(原文链接在结尾),虽然篇幅偏长,但是却能使你真正理解hashCode和queals各自的作用以及之间的联系,尤其是第四部分,读完肯定会让你有所收获. 第1部分 equals() 的作用 ...
- manim边做边学--动画联动
今天介绍Manim中的动画联动的技巧,在数学动画中,动画联动是常用的功能, 比如讲解平面几何中三角形与圆的位置关系变化,通过动画联动可以让圆沿着三角形的边滚动,或者让三角形的顶点在圆上移动,从而直观地 ...
- 微服务实战系列(七)-网关springcloud gateway-copy
1. 场景描述 springcloud刚推出的时候用的是netflix全家桶,路由用的zuul,但是据说zull1.0在大数据量访问的时候存在较大性能问题,2.0就没集成到springcloud中了, ...