一、h5在做可视化地图时,用高德地图绘制空域(圆形,线,多边形),碰到一个需求,根据绘制出来的图形给对应的空域列表项添加一个缩略图。

二、确定实现方法

  1. 要根据绘制的图形生成对应图形的缩略图,有两种方式,一是使用高德地图给每个列表项绘制对应的图形,二是自己实现。
  2. 第一种方法性能差,要是自己实现,我这边选择的是canvas画布。
  3. 难点:后台返回的是经纬度数据不是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坐标系的更多相关文章

  1. C#生成带logo的二维码

    带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码. 生成的二维码效果如下: 下面直接贴出二维码生成类   QRCode ...

  2. C#+ZXing.dll生成手机路径导航二维码

    1.原谅我先写点废话哈 这两天用C#写一个C端的软件,甲方提出一个很无理的需求(在C端的程序中实现路径导航,关键是这个程序最终是运行在物理隔绝的电脑上的……),头疼了好几天,领导突然想到可以把坐标+百 ...

  3. js生成带参的二维码

    最近项目中有需求生成带参的二维码,考虑过用JAVA后台生成返回前端展示,后面了解到用jquery的qrcode.js插件可以很好现实 引入js: require.config({ baseUrl : ...

  4. .NET使用ZXing.NET生成中间带图片的二维码

    很久之前就有写这样的代码了,只是一直没记录下来,偶然想写成博客. 把之前的代码封装成函数,以方便理解以及调用. 基于开源的 ZXing.NET 组件,代码如下: 先添加对ZXing.NET的引用,然后 ...

  5. .NET生成带Logo的二维码

    使用ThoughtWorks.QRCode生成,利用这个库来生成带Logo的二维码(就是中间嵌了一个图片的二维码),直接见代码: HttpContext context = HttpContext.C ...

  6. C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(二)

    1.使用ZXint.Net生成带logo的二维码 /// <summary> /// 生成带Logo的二维码 /// </summary> /// <param name ...

  7. 微信公众号生成带参数的二维码asp源码下载

    晚上闲着没事,一个朋友联系,让帮忙写一个微信公众号利用asp生成带参数的二维码,别人扫了后如果已经关注过该公众号的,则直接进入公众号里,如果没关注则提示关注,关注后自动把该微信用户资料获取到并且保存入 ...

  8. js实现生成中间带图片的二维码

    之前需要实现生成中间带图片的二维码,所以找了半天终于找到一个可以用的.于是在这里记录一下. 下面是需要注意的几点: 1.使用的js为jquery-qrcode 但是已经经过别人的修改,和网上原来的那些 ...

  9. PHP生成有背景的二维码图,摘自网络

    有一天产品MM高高兴兴的走过来,兴奋的和我分享她想出来的一个新的idea. 产品MM:你看这个(她指了指她的手机),一脸兴奋 那是一张带着二维码的图片,内容如下: 她接着说:如果我们的分销也能做成类似 ...

  10. C# 生成 DataMatrix 格式的二维码

    该文主要是利用OnBarcode.dll 生成 DataMatrix 格式的二维码的一些简单方法和操作技巧.关于QrBarcode的二维码比较常见和简单,网上有很多资源. 1.附件为dll 2.利用上 ...

随机推荐

  1. shell 获取 目录名 当前目录名

    Four ways to extract the current directory name By  Sergio Gonzalez Duran on November 06, 2007 (9:00 ...

  2. elasticsearch数据导出和导入

    数据导入和导出依赖于命令 elasticdump 数据导出 #!/bin/bash ES=http://ip:port ED=数据保存位置 datename=$(date +%Y-%m-%d) #da ...

  3. Verilog4_时序逻辑电路

    时序逻辑电路概述 时序逻辑电路分类: 按照触发器的动作特点: 同步时序逻辑电路: 所有触发器的状态变化都是在同一个时钟信号作用下同时发生的 异步时序逻辑电路: 没有统一的时钟脉冲信号,各触发器状态的变 ...

  4. Apgar score

    Apgar score Apgar is a quick test performed on a baby at 1 and 5 minutes after birth. The 1-minute s ...

  5. 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 ...

  6. 为了解决服务启动慢的问题,我为什么要给Apollo和Spring提交PR?

    最近在整理之前记录的工作笔记时,看到之前给团队内一组服务优化启动耗时记录的笔记,简单整理了一下分享出来.问题原因并不复杂,主要是如何精准测量和分析,优化后如何定量测量优化效果,说人话就是用实际数据证明 ...

  7. uwp 获取屏幕分辨率

    public static Size ScreenSize { get { //screen resolution var height = DisplayInformation.GetForCurr ...

  8. MySQL---事务、死锁、mvcc原理

    前言 在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别. MySQL 是支持多事务并发执行的.否则来一个事务处理一个请求,处理一个人请 ...

  9. Linux系统用户登录命令行或执行命令显示日志文件异常-bash: /var/log/ 解决办法

    经常会遇到Linux系统用户登录命令行或执行命令显示日志文件异常,比如:-bash: /var/log/xxx_audit/xxx_audit.log: Permission denied 其实是说开 ...

  10. iptables使用详解(示例如何屏蔽docker 暴露的端口)

    [场景]搭建了一台CentOS虚拟机,并在上面搭了DOCKER,然后再DOCKER中安装Mysql.但只要将网络端口映射到宿主机上,那么外部网络就可以直接访问该数据.为此,我们需要使用防火墙(暂且不考 ...