地图可视化,根据绘制的图形生成缩略图,经纬度转换二维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.利用上 ...
随机推荐
- shell 获取 目录名 当前目录名
Four ways to extract the current directory name By Sergio Gonzalez Duran on November 06, 2007 (9:00 ...
- elasticsearch数据导出和导入
数据导入和导出依赖于命令 elasticdump 数据导出 #!/bin/bash ES=http://ip:port ED=数据保存位置 datename=$(date +%Y-%m-%d) #da ...
- Verilog4_时序逻辑电路
时序逻辑电路概述 时序逻辑电路分类: 按照触发器的动作特点: 同步时序逻辑电路: 所有触发器的状态变化都是在同一个时钟信号作用下同时发生的 异步时序逻辑电路: 没有统一的时钟脉冲信号,各触发器状态的变 ...
- Apgar score
Apgar score Apgar is a quick test performed on a baby at 1 and 5 minutes after birth. The 1-minute s ...
- SpringBoot集成MinIO8.3.x 依赖冲突解决,至简之招覆盖spring-boot-dependencies的依赖版本声明
版本声明 SpringBoot 2.6.5 MinIO 8.3.7 报错信息 An attempt was made to call a method that does not exist. The ...
- 为了解决服务启动慢的问题,我为什么要给Apollo和Spring提交PR?
最近在整理之前记录的工作笔记时,看到之前给团队内一组服务优化启动耗时记录的笔记,简单整理了一下分享出来.问题原因并不复杂,主要是如何精准测量和分析,优化后如何定量测量优化效果,说人话就是用实际数据证明 ...
- uwp 获取屏幕分辨率
public static Size ScreenSize { get { //screen resolution var height = DisplayInformation.GetForCurr ...
- MySQL---事务、死锁、mvcc原理
前言 在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别. MySQL 是支持多事务并发执行的.否则来一个事务处理一个请求,处理一个人请 ...
- Linux系统用户登录命令行或执行命令显示日志文件异常-bash: /var/log/ 解决办法
经常会遇到Linux系统用户登录命令行或执行命令显示日志文件异常,比如:-bash: /var/log/xxx_audit/xxx_audit.log: Permission denied 其实是说开 ...
- iptables使用详解(示例如何屏蔽docker 暴露的端口)
[场景]搭建了一台CentOS虚拟机,并在上面搭了DOCKER,然后再DOCKER中安装Mysql.但只要将网络端口映射到宿主机上,那么外部网络就可以直接访问该数据.为此,我们需要使用防火墙(暂且不考 ...