百度地图使用任意图片旋转任意角度作为地面贴图

news2024/11/23 3:38:06

公司项目有个需求是要在地图上贴个航拍的照片做出类似卫星地图的效果,但是只有一张图片而且可以随时替换,也不好做瓦片地图,而且照片的角度可以任意旋转。
要实现这个功能需要解决以下问题:

  1. 百度地图怎么贴图片
  2. 图片角度如何旋转
    不卖关子,我先放出实现的效果,为了不涉及侵权,我换成了一张同事的爱犬的照片

实现需求

百度地图怎么贴图片

百度地图api中有GroundOverlay能实这个效果。


代码如下:

// 西南角和东北角
const SW = new BMap.Point(119.74455912589518, 36.92779662557118);
const NE = new BMap.Point(119.75332658767256, 36.936756872224294);

const groundOverlayOptions = {
    opacity: 1,
    displayOnMinLevel: 8,
    displayOnMaxLevel: 20
}

// 初始化GroundOverlay
const groundOverlay = new BMap.GroundOverlay(new BMap.Bounds(SW, NE), groundOverlayOptions);
const url = "(图片地址,可以是绝对地址也可以是相对地址)"

groundOverlay.setImageURL(url);
map.addOverlay(this.groundOverlay)

然而发现问题没有,百度地图能实现的是贴方方正正没有旋转的图片,那么如何让图片旋转呢。

如何让贴上去的图片旋转

既然百度地图无法实现这个旋转,那我们可以从图片自身下手:

  1. 使用Image对象加载图片,得到图片的宽高
 // 首先加载图片,获取图片宽高
var path = 'xxxxxx' 
var img = new Image()
// 如果是网络图片必须加这行,不然会报错
img.setAttribute("crossOrigin",'Anonymous')
img.src = path

// 逆时针为正
let angle = 64

img.onload = function() {
    var width = this.width
    var height = this.height
}
  1. 计算图片旋转任意角度后的包围盒大小
    计算我使用了旋转矩阵,原理在另一篇文章中 旋转矩阵
function rotate([x, y], angle) {
  // 用角度计算弧度
  let rad = angle * Math.PI / 180
  let sinA =  Math.sin(rad)
  let cosA = Math.cos(rad)
  return [x * cosA - y * sinA, x * sinA + y * cosA]
}

// 比较图片4个角坐标,获取最大最小值作为包围框
function getBoundingBox(list) {
  const xList = list.map(item => item[0])
  const yList = list.map(item => item[1])
  const minX = Math.min(...xList)
  const minY = Math.min(...yList)
  const maxX = Math.max(...xList)
  const maxY = Math.max(...yList)
  const width = maxX - minX
  const height = maxY - minY
  return {
    minX,
    minY,
    maxX,
    maxY,
    width,
    height
  }
}

img.onload = function() {
    var width = this.width
    var height = this.height
    // 计算矩形旋转θ角度之后的包围盒宽高
    // 旋转矩阵为 [[cosθ, sinθ][-sinθ, cosθ]],将四个点坐标和旋转矩阵相乘
    // [x,y][[cosθ, sinθ][-sinθ, cosθ]] = [x * cosθ + y * -sinθ, x * sinθ + y * cosθ]
    // 图片四个角坐标为 左下(0,0), 左上(0,height),右下(width,0),右上(width,height)
    let posLB = rotate([0,0], angle)
    let posLT = rotate([0,height],angle)
    let posRB = rotate([width,0],angle)
    let posRT = rotate([width,height],angle)
    // 获取旋转后的包围框大小
    let {width:boundingWidth,height:boundingHeight} = getBoundingBox([posLB,posLT,posRB,posRT])
}
  1. 创建图片旋转后包围盒大小的canvas
  2. 在canvas上绘制旋转了角度的图片
  3. 使用 canvas.toDataURL() 获取url并贴到百度地图上
//.....
//.....
// 获取旋转后的包围框大小
let {width:boundingWidth,height:boundingHeight} = getBoundingBox([posLB,posLT,posRB,posRT])
// 创建canvas
var canvas = document.createElement("canvas");
canvas.width = boundingWidth;
canvas.height = boundingHeight;
var c = canvas.getContext('2d');
// 修改canvas的原点为中心点
c.translate(boundingWidth/2, boundingHeight/2)
// 旋转画布
c.rotate(-angle * Math.PI / 180)
c.drawImage(img,-width/2, -height/2,width,height);
let url = canvas.toDataURL()
// 设置GroundOverlay的图片地址
groundOverlay.setImageURL(url);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1860231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-dialog使用::v-deep()穿透设置样式不生效,解决办法亲测有效!

场景&#xff1a; <el-dialogv-model"dialogVisible"width"800px":before-close"beforeClose"append-to-body:close-on-click-modal"false"title"增加文档"><template #footer><div style"text-align:c…

开发大模型应用,到底使用RAG还是微调?我们应该从哪些方面考虑?

现在基于大模型开发应用时&#xff0c;相信很多人都有这种疑问&#xff0c;到底对大模型进行微调还是外接RAG呢&#xff1f;因为两者在一定层面上有很多相似的地方&#xff0c;下面让我给大家从各个层面进行分析&#xff0c;结合具体的业务场景&#xff0c;看哪种方式更适合你的…

【OnlyOffice】 桌面应用编辑器,版本8.1发布,PDF编辑器、幻灯片版式、改进从右至左显示、新的本地化选项等功能,快来体验吧

继 ONLYOFFICE 文档 8.1 发布后&#xff0c;适用于 Linux、Windows 和 macOS 的 ONLYOFFICE 桌面应用程序最新版本也已推出。它具有在线套件的最主要功能&#xff0c;例如功能齐全的 PDF 编辑器、演示文稿中的幻灯片版式、改进的 RTL 支持、新的本地化选项等。 目录 ONLYOFFICE…

【Unity Android】Unity链接安卓手机调试

一、物理连接手机 1.USB数据线链接 2.打开开发者模式 大部分手机在手机设置->系统管理->关于手机->软件版本型号中&#xff0c;点击7次以上&#xff0c;来开启系统管理中的开发者模式选项。 3.打开USB调试 打开开发者模式后&#xff0c;开启USB调试 二、Unity中…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS Timer

LiteOS Timer&#xff08;定时器&#xff09;是LiteOS操作系统中的一个重要组件&#xff0c;它提供了一种基于软件模拟的定时器功能&#xff0c;用于满足在硬件定时器数量不足时的定时需求。 软件定时器&#xff1a;基于系统Tick时钟中断&#xff0c;由软件来模拟的定时器。当经…

表单(forms)

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在app1文件夹下创建一个forms.py文件&#xff0c;添加如下类代码&#xff1a; from django import forms class PersonForm(forms.Form): first_na…

GPT-5:AI新纪元的领航者,多维度的审视与准备

一、引言&#xff1a;GPT-5与AI的多维演进 GPT-5作为AI领域的里程碑式突破&#xff0c;不仅仅代表了技术的飞跃&#xff0c;更预示着社会、文化以及经济等多个层面的深刻变革。从技术的角度看&#xff0c;GPT-5代表着AI在自然语言处理领域的最新高度&#xff1b;而从更宽广的视…

中国高分辨率土壤侵蚀因子K

土壤可蚀性因子&#xff08;K&#xff09;数据&#xff0c;基于多种土壤属性数据计算&#xff0c;所用数据包括土壤黏粒含量&#xff08;%&#xff09;、粉粒含量&#xff08;%&#xff09;、砂粒含量&#xff08;%&#xff09;、土壤有机碳含量&#xff08;g/kg&#xff09;、…

我国季戊四醇市场规模逐渐扩大 出口量有所增长

我国季戊四醇市场规模逐渐扩大 出口量有所增长 季戊四醇&#xff08;PETP/THME&#xff09;又称为四羟甲基甲烷、2,2-双羟甲基-1,3-丙二醇等&#xff0c;是一种多元醇类有机化合物&#xff0c;多表现为一种白色结晶性粉末。季戊四醇可溶于水及乙醇等溶剂&#xff0c;但不溶于苯…

台式扫描电镜工作距离越远观察区越大?

台式扫描电镜&#xff08;Scanning Electron Microscope, SEM&#xff09;是一种高分辨率的显微镜&#xff0c;它利用电子束扫描样品表面&#xff0c;通过样品与电子束相互作用产生的信号来形成图像。这种显微镜广泛应用于材料科学、生物学和医学等领域&#xff0c;以观察样品的…

AI元宇宙

随着科技的迅猛发展&#xff0c;人工智能&#xff08;AI&#xff09;迎来了一个宇宙大爆发的时代。特别是以GPT为代表的生成式大模型的诞生和不断进步&#xff0c;彻底改变了人们的工作和生活方式。程序员与AI协同工作写代码已成为常态&#xff0c;大模型不仅提高了工作效率&am…

4418 HMI 更换logo 图片

逻辑说明&#xff1a; HMI 的 kernel 没有提供源码&#xff0c;只是提供了镜像&#xff0c;如果客户需要更换自己的logo 的话&#xff0c; 可以使用提供的工具&#xff0c;将内核logo 打包起来。 我觉得这里的打包的过程应该是参考了&#xff0c; 4418 build_android.sh 脚…

linux学习week1

linux学习 一.介绍 1.概述 linux的读法不下10种 linux是一个开源的操作系统&#xff0c;操作系统包括mac、windows、安卓等 linux的开发版&#xff1a;Ubuntu&#xff08;乌班图&#xff09;、RedHat&#xff08;红帽&#xff09;、CentOS linux的应用&#xff1a;linux在服…

百问网全志D1h开发板MIPI屏幕触摸功能适配

硬件了解 首先&#xff0c;还是从官方提供的资料&#xff0c;可以了解MIPI LCD对应的接口信息&#xff1a; [ 触摸功能涉及到DSI_SCL、DSI_SDA、TP_INT、TP_RESET。 从芯片的引脚图里面&#xff0c;可以了解到&#xff1a; [ 其中&#xff1a; DSI_SCL、DSI_SDA使用的是…

1954springboot VUE 天然气系统隐患管理系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE天然气系统隐患管理系统是一套完善的完整信息管理类型系统&#xff0c;结合springboot框架和VUE完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC 模式开发&#xff09;&#xff0c;系统具有完整的…

JNI详解

JNI简介 Java是跨平台的语言,但在有的时候仍需要调用本地代码(这些代码通常由C/C++编写的)。 Sun公司提供的JNI是Java平台的一个功能强大的接口,JNI接口提供了Java与操作系统本地代码互相调用的功能。 Java调C++ 1)使用javah命令生成native的头文件 javah com.studio.j…

优化|PyOptInterface:高效且灵活的Python优化建模语言

优化建模语言作为优化求解器与终端用户之间的桥梁&#xff0c;是构建、求解和分析优化模型的重要工具。建模语言的效率直接影响优化模型的构建和求解时间。PyOptInterface是一种基于Python编程语言的优化建模语言&#xff0c;相比现有建模语言兼具高效率和灵活性&#xff0c;在…

Kotlin设计模式:深入理解桥接模式

Kotlin设计模式&#xff1a;深入理解桥接模式 在软件开发中&#xff0c;随着系统需求的不断增长和变化&#xff0c;类的职责可能会变得越来越复杂&#xff0c;导致代码难以维护和扩展。桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过…

【MySQL】如果表被锁可以尝试看一下事务

今天在MySQL中删除表的时候&#xff0c;发现无法删除&#xff0c;一执行drop&#xff0c;navicat就卡死。 通过 SHOW PROCESSLIST显示被锁了 kill掉被锁的进程后依旧被锁 最后发现是由于存在为执行完的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; kill掉这些事务以…

九泰智库 | 医械周刊- Vol.36

⚖️ 法规动态 广东药监局 | 8家医疗器械公司体系不合规被停产 6月17日&#xff0c;广东省药品监督管理局组织开展医疗器械生产企业监督检查&#xff0c;发现8家企业质量管理体系存在严重缺陷&#xff0c;不符合《医疗器械生产质量管理规范》相关规定&#xff0c;广东省药品监督…