前に書く
ArcGISマップに画像を追加することについての記事を書いたところ、注目が集まりました。プロジェクトでは、記事に記載されている技術ルートを使用して、マップオーバーレイ画像の必要性を実現しました。しかし、最近、前の記事でレイヤーを展開して画像を追加した後、画像の特定の部分にさらに情報がある場合、マップをズームした瞬間にマップをドラッグすると、顧客は新しい要求を持っています。写真のその部分はスタックします。実際、この状況は1秒程度しかかからないので深刻ではありませんが、顧客はこの点を把握するために競争しなければなりません。それでは仕方がないので、最適化の波を作りましょう。
前回の記事のアドレスは次のとおりです:「07ArcGIS JS API4.14マップ読み込みイメージの実装」。
最終的な効果は次のとおりです。
具体操作
1.以前の技術ルートはBaseDynamicLayerクラスを拡張することによって実装されたため、最下層は引き続きキャンバス描画テクノロジーを使用してマップに画像を描画します。このように、後の期間のダブルバッファテクノロジーの使用は最適化されていませんが、画像のより有益な場所に描画するのが遅くなり、スタッターが確実に失われるため、この記事では別の方法を採用しますマップオーバーレイ画像を実現します。
2.この記事ではimgタグを直接使用します。原理は非常に単純です。マップレンダリングのcanvasタグにimgタグを直接追加し、マップの表示領域の変化を監視することで、画像のサイズと位置を動的に変更します。
3.まず、2次元マップをインスタンス化します。コードは次のとおりです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Intro to MapView - Create a 2D map - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="http://localhost/4.15/esri/themes/light/main.css" />
<script src="http://localhost/4.15/init.js"></script>
<script>
require(['esri/Map', 'esri/views/MapView', 'esri/core/watchUtils'], function (Map, MapView, watchUtils) {
var map = new Map({
basemap: 'osm',
});
var view = new MapView({
container: 'viewDiv',
map: map,
zoom: 7,
center: [104.071883, 30.664022], // longitude, latitude
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
4.次に、マップの初期化が完了した後、マップレンダリングのラベルを取得し、同じレベルでimgタグを追加して、次のようにいくつかの属性を指定します。
var resultDom;
view.when(function () {
//添加图片
var selectDom = document.getElementsByClassName(
'esri-view-surface esri-view-surface--inset-outline esri-view-surface--touch-none',
);
console.log(extent);
resultDom = document.createElement('img');
resultDom.src = './testquickviewphoto.png';
resultDom.className = 'mystyle';
resultDom.id = 'mystyle';
selectDom[0].appendChild(resultDom);
});
5.このようにして、画像がマップに追加されました。追加した画像を表示するには、このimgタグのスタイルを指定する必要があるため、次に、マップのビューの変化を直接監視します。スタイルと対応する場所を指定します。
let extent = { //图片的范围
xmin: 10138549.59667821,
ymin: 3449716.2722409572,
xmax: 10249869.087471481,
ymax: 3578363.913808475,
};
var absd = view.zoom;
watchUtils.when(view, 'extent', function () {
if (view.extent && document.getElementById('mystyle')) {
var lefttop = {
x: extent.xmin,
y: extent.ymax,
spatialReference: {
wkid: 102100,
},
};
var screen_lefttop = view.toScreen(lefttop);
document.getElementById('mystyle').style.top = screen_lefttop.y + 'px';
document.getElementById('mystyle').style.left = screen_lefttop.x + 'px';
//zoom未改变的情况下不重新计算image长和宽
if (absd != view.zoom) {
var rightbottom = {
x: extent.xmax,
y: extent.ymin,
spatialReference: {
wkid: 102100,
},
};
var screen_rightbottom = view.toScreen(rightbottom);
document.getElementById('mystyle').style.width =
screen_rightbottom.x - screen_lefttop.x + 'px';
document.getElementById('mystyle').style.height =
screen_rightbottom.y - screen_lefttop.y + 'px';
}
}
});
6.上記の操作を完了すると、マップに画像をロードするプロセスが正常に実装されました。これにより、マップをズームしても、追加した画像がスタックすることはありません。
添付:
すべてのコード:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Intro to MapView - Create a 2D map - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
.mystyle {
position: absolute;
top: 937px;
left: 0px;
width: 1920px;
height: 937px;
}
</style>
<link rel="stylesheet" href="http://localhost/4.15/esri/themes/light/main.css" />
<script src="http://localhost/4.15/init.js"></script>
<script>
require(['esri/Map', 'esri/views/MapView', 'esri/core/watchUtils'], function (Map, MapView, watchUtils) {
var map = new Map({
basemap: 'osm',
});
var view = new MapView({
container: 'viewDiv',
map: map,
zoom: 7,
center: [104.071883, 30.664022], // longitude, latitude
});
let extent = {
xmin: 10138549.59667821,
ymin: 3449716.2722409572,
xmax: 10249869.087471481,
ymax: 3578363.913808475,
};
var resultDom;
view.when(function () {
//添加图片
var selectDom = document.getElementsByClassName(
'esri-view-surface esri-view-surface--inset-outline esri-view-surface--touch-none',
);
console.log(extent);
resultDom = document.createElement('img');
resultDom.src = './testquickviewphoto.png';
resultDom.className = 'mystyle';
resultDom.id = 'mystyle';
selectDom[0].appendChild(resultDom);
});
var absd = view.zoom;
watchUtils.when(view, 'extent', function () {
if (view.extent && document.getElementById('mystyle')) {
var lefttop = {
x: extent.xmin,
y: extent.ymax,
spatialReference: {
wkid: 102100,
},
};
var screen_lefttop = view.toScreen(lefttop);
document.getElementById('mystyle').style.top = screen_lefttop.y + 'px';
document.getElementById('mystyle').style.left = screen_lefttop.x + 'px';
//zoom未改变的情况下不重新计算image长和宽
if (absd != view.zoom) {
var rightbottom = {
x: extent.xmax,
y: extent.ymin,
spatialReference: {
wkid: 102100,
},
};
var screen_rightbottom = view.toScreen(rightbottom);
document.getElementById('mystyle').style.width =
screen_rightbottom.x - screen_lefttop.x + 'px';
document.getElementById('mystyle').style.height =
screen_rightbottom.y - screen_lefttop.y + 'px';
}
}
});
setTimeout(reloadPhoto, 500);
function reloadPhoto() {
//console.log(extent.xmax)
//左下角
var leftbottom = {
x: extent.xmin,
y: extent.ymin,
spatialReference: {
wkid: 102100,
},
};
var screen_leftbottom = view.toScreen(leftbottom);
//右上角
var righttop = {
x: extent.xmax,
y: extent.ymax,
spatialReference: {
wkid: 102100,
},
};
var screen_righttop = view.toScreen(righttop);
document.getElementById('mystyle').style.top = screen_righttop.y + 'px';
document.getElementById('mystyle').style.left = screen_leftbottom.x + 'px';
document.getElementById('mystyle').style.width =
Math.abs(screen_righttop.x - screen_leftbottom.x) + 'px';
document.getElementById('mystyle').style.height =
Math.abs(screen_righttop.y - screen_leftbottom.y) + 'px';
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>