之前做地图叠加影像时,出现地图旋转后图片位置不对或图片变形,第一次图片加载不出来的问题,特此记录
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>地图叠加图片之BaseDynamicLayer</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/dark-blue/main.css" />
<script src="https://js.arcgis.com/4.19/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
button {
position: fixed;
top: 10px;
right: 10px;
}
</style>
</head>
<body>
<div id="viewDiv"></div>
<button onclick="addImageToMap()">显示/隐藏图片</button>
<script>
let baseMap, mapView, customDynamicLayer, GeoExtent, GeoPoint, DynamicLayer, WebMercatorUtils;
const extent = {
"xmin": 73.42961975,
"ymin": 20.2,
"xmax": 135.10961975,
"ymax": 53.56
}
require([
"esri/Map",
"esri/views/MapView",
"esri/geometry/Extent",
"esri/geometry/Point",
"esri/geometry/support/webMercatorUtils",
"esri/layers/BaseDynamicLayer"
], function (Map, MapView, Extent, Point, webMercatorUtils, BaseDynamicLayer) {
GeoExtent = Extent;
GeoPoint = Point;
DynamicLayer = BaseDynamicLayer;
WebMercatorUtils = webMercatorUtils;
var map = new Map({
basemap: 'osm',
});
baseMap = map
var view = new MapView({
container: "viewDiv",
map: map,
center: [107.246152, 34.414465],
zoom: 7
});
mapView = view
view.when(() => crateDynamicLayer())
});
function addImageToMap() {
//初次叠加创建图层,后续控制该图层的显示隐藏
const curLayer = baseMap.findLayerById(`baes_dynamic_layer`);
// mapView.goTo({
// center: [extent.xmin + (extent.xmax - extent.xmin) / 2, extent.ymin + (extent.ymax - extent.ymin) / 2],
// zoom: 10
// })
mapView.extent = extent;
if (curLayer) {
curLayer.visible = !curLayer.visible;
return
}
let ImageOverlayLayer = new customDynamicLayer({
id: 'baes_dynamic_layer',
picUrl: `./image/quickview.png`,
extent: extent,
view: mapView
});
ImageOverlayLayer.refreshInterval = 0;//不自动刷新
baseMap.add(ImageOverlayLayer);
}
function crateDynamicLayer() {
customDynamicLayer = DynamicLayer.createSubclass({
properties: {
picUrl: null,
extent: null,
image: null,
canvas: null,
view: mapView
},
getImageUrl: async function (extent, width, height) {
//转换图片范围的坐标系,如果坐标系相同,则无需转换
console.log(this.extent);
let wgsExtent = WebMercatorUtils.geographicToWebMercator(new GeoExtent({
xmin: this.extent.xmin,
ymin: this.extent.ymin,
xmax: this.extent.xmax,
ymax: this.extent.ymax
}));
let upperLeftMerc = new GeoPoint({
x: wgsExtent.xmin,
y: wgsExtent.ymax,
spatialReference: this.view.spatialReference
});
let lowerRightMerc = new GeoPoint({
x: wgsExtent.xmax,
y: wgsExtent.ymin,
spatialReference: this.view.spatialReference
});
let newULX = (upperLeftMerc.x - extent.xmin) / (extent.xmax - extent.xmin) * width;
let newULY = height - (upperLeftMerc.y - extent.ymin) / (extent.ymax - extent.ymin) * height;
let newLRX = (lowerRightMerc.x - extent.xmin) / (extent.xmax - extent.xmin) * width;
let newLRY = height - (lowerRightMerc.y - extent.ymin) / (extent.ymax - extent.ymin) * height;
let imageWidth = Math.abs(newLRX - newULX);
let imageHeight = Math.abs(newULY - newLRY);
if (!this.image) {
this.image = new Image();
this.image.setAttribute("crossOrigin", 'Anonymous');
}
if (!this.canvas) {
this.canvas = document.createElement('canvas');
}
this.canvas.width = width;
this.canvas.height = height;
//第一次图片未加载完成就导出canvas,所以第一次不显示,这里改为异步导出canvas
const loadimg = img => {
return new Promise((rel, rej) => {
img.onload = () => {
this.canvas.getContext('2d').drawImage(img, newULX, newULY, imageWidth, imageHeight);
rel(this.canvas.toDataURL('image/png'))
}
img.src = this.picUrl;
})
}
return await loadimg(this.image)
}
})
}
</script>
</body>
</html>
实现地图旋转图片不变形,不位移
第一次加载请耐心等待图片加载完成
运行
npm i
npm run dev
浏览:http://localhost:3456
或者本机装了liver-server、serve等工具,直接项目下运行即可
主要解决了图片位置和大小的算法,地图旋转后图片位置不对和图片变形的问题。
更新
第一次图片未加载完成就导出canvas,所以第一次不显示,改为异步导出canvas