欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 百度地图使用任意图片旋转任意角度作为地面贴图

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

2024/10/24 15:22:19 来源:https://blog.csdn.net/qq_23447231/article/details/139865737  浏览:    关键词:百度地图使用任意图片旋转任意角度作为地面贴图

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

  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 = 64img.onload = function() {var width = this.widthvar height = this.height
}
  1. 计算图片旋转任意角度后的包围盒大小
    计算我使用了旋转矩阵,原理在另一篇文章中 旋转矩阵
function rotate([x, y], angle) {// 用角度计算弧度let rad = angle * Math.PI / 180let 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 - minXconst height = maxY - minYreturn {minX,minY,maxX,maxY,width,height}
}img.onload = function() {var width = this.widthvar 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);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com