更新 'viewport.js'

修复下载中断机制,以获取慢网速下的更优秀的加载效果
main
alimu 2 years ago
parent 7e6ff9f752
commit cc4bb60a02

@ -1,11 +1,12 @@
//help array; //help array;
let Caches = new Array(); //cache let Caches = new Array(); //cache
let downloadRecord = new Array(); //let downloadRecord = new Array();
let dm = new Array(); //尝试增加下载管理 downloadmanager let dm = new Array(); //尝试增加下载管理 downloadmanager
let alltilecount = 0; let alltilecount = 0;
let downtilecount = 0; let downtilecount = 0;
function ViewPort(canvasId, options) { function ViewPort(canvasId, options) {
// allow without 'new' // allow without 'new'
if (!(this instanceof ViewPort)) return new ViewPort(canvasId, options); if (!(this instanceof ViewPort)) return new ViewPort(canvasId, options);
@ -32,8 +33,8 @@ function ViewPort(canvasId, options) {
//如果在options中有指定地图中心点 //如果在options中有指定地图中心点
//options.centerLng && options.centerLat //options.centerLng && options.centerLat
if (options.centerLat != null && options.centerLng != null if (options.centerLat != null && options.centerLng != null &&
&& !isNaN(options.centerLat) && !isNaN(options.centerLng)) { !isNaN(options.centerLat) && !isNaN(options.centerLng)) {
console.log('指定中心点'); console.log('指定中心点');
try { try {
({ lat: lat, lng: lng } = this.latlngPreCheck(options.centerLat, options.centerLng)); ({ lat: lat, lng: lng } = this.latlngPreCheck(options.centerLat, options.centerLng));
@ -233,16 +234,31 @@ ViewPort.prototype = {
} }
} }
this.needtiles = this.tilesFilter(tails); //获取当前视口要渲染的底图 this.needtiles = this.tilesFilter(tails); //获取当前视口要渲染的底图
let z = this.zoomLevel; //这里的几行代码的逻辑是用到了5个函数里面后面可以想一下怎么重构
if (this.zoomLevel != Math.floor(this.zoomLevel)) {
z = Math.floor(this.zoomLevel + 1);
}
//尝试在这里移除不需要继续下载的内容
let indexs = new Array();
dm.forEach(d => {
if (d.z !=z) {
if(this.needtiles.find(e=>e.x==d.x&&e.y==d.y)==undefined){
d.xhr.abort();
console.log('中断请求');
dm.remove(d);
}
}
});
alltilecount += this.needtiles.length; //for debug alltilecount += this.needtiles.length; //for debug
//console.log(this.needtiles); //console.log(this.needtiles);
this.needtiles.forEach(et => { this.needtiles.forEach(et => {
const etsize = calTileSize(this.TILESIZE, this.zoomLevel); const etsize = calTileSize(this.TILESIZE, this.zoomLevel);
const tilev = this.mplat2Viewport(et.x * etsize, et.y * etsize); const tilev = this.mplat2Viewport(et.x * etsize, et.y * etsize);
this.drawRect(tilev.x, tilev.y, etsize, etsize); this.drawRect(tilev.x, tilev.y, etsize, etsize);
let z = this.zoomLevel;//这里的几行代码的逻辑是用到了5个函数里面后面可以想一下怎么重构
if (this.zoomLevel != Math.floor(this.zoomLevel)) {
z = Math.floor(this.zoomLevel + 1);
}
const text = `${z}/${et.x}/${et.y}.png`; const text = `${z}/${et.x}/${et.y}.png`;
// console.log(text); // console.log(text);
this.drawtext(text, tilev.x + etsize / 2, tilev.y + etsize / 2); this.drawtext(text, tilev.x + etsize / 2, tilev.y + etsize / 2);
@ -287,22 +303,27 @@ function calTileNum(coord, tilesize, zoomLevel) {
function lon2tile(lon, z) { function lon2tile(lon, z) {
return (Math.floor((lon + 180) / 360 * Math.pow(2, z))); return (Math.floor((lon + 180) / 360 * Math.pow(2, z)));
} }
function lat2tile(lat, z) { function lat2tile(lat, z) {
return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
2 * Math.pow(2, z))); 2 * Math.pow(2, z)));
} }
function lon2x(lon, z) { function lon2x(lon, z) {
return ((lon + 180) / 360 * Math.pow(2, z)); return ((lon + 180) / 360 * Math.pow(2, z));
} }
function lat2y(lat, z) { function lat2y(lat, z) {
return ((1 - Math.log(Math.tan(lat * Math.PI / 180) + return ((1 - Math.log(Math.tan(lat * Math.PI / 180) +
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
2 * Math.pow(2, z)); 2 * Math.pow(2, z));
} }
function tile2long(x, z) { function tile2long(x, z) {
return (x / Math.pow(2, z) * 360 - 180); return (x / Math.pow(2, z) * 360 - 180);
} }
function tile2lat(y, z) { function tile2lat(y, z) {
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z); var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))));
@ -352,13 +373,13 @@ function downloadimg(z, x, y) {
//尝试优化图片下载机制 //采用下载速度比较慢的openstreetmap 测试 //尝试优化图片下载机制 //采用下载速度比较慢的openstreetmap 测试
function xhrdownloadimg(z, x, y) { function xhrdownloadimg(z, x, y) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const url = `https://tile.openstreetmap.org/${z}/${x}/${y}.png`; const url = `https://b.tile.openstreetmap.org/${z}/${x}/${y}.png`;
let imgxhr = new XMLHttpRequest(); let imgxhr = new XMLHttpRequest();
imgxhr.open('GET', url, true); imgxhr.open('GET', url, true);
//add downloadcheck //add downloadcheck
const obj = { z: z, x: x, y: y }; //const obj = { z: z, x: x, y: y };
downloadRecord.push(obj); //下载前加入一条记录 //downloadRecord.push(obj); //下载前加入一条记录
const dmobj = { xhr: imgxhr, z: z, x: x, y: y }; const dmobj = { xhr: imgxhr, z: z, x: x, y: y };
//imgxhr.withCredentials = true; //imgxhr.withCredentials = true;
@ -369,12 +390,14 @@ function xhrdownloadimg(z, x, y) {
let img = createImageBitmap(blob); let img = createImageBitmap(blob);
Caches.push({ img: img, z: z, x: x, y: y }); Caches.push({ img: img, z: z, x: x, y: y });
downtilecount += 1; downtilecount += 1;
downloadRecord.remove(obj); //下载完成后将记录移除 //downloadRecord.remove(obj); //下载完成后将记录移除
dm.remove(dmobj); dm.remove(dmobj);
console.log('dm下载完成减少');
resolve(img); resolve(img);
} else { } else {
reject('下载似乎失败了'); reject('下载似乎失败了');
dm.remove(dmobj); dm.remove(dmobj);
console.log('dm下载失败减少');
} }
}; };
dm.push(dmobj); //保存xhr对象 和xyz索引 dm.push(dmobj); //保存xhr对象 和xyz索引
@ -385,49 +408,30 @@ function xhrdownloadimg(z, x, y) {
async function getImg(vp, z, x, y) { async function getImg(vp, z, x, y) {
const found = Caches.find(e => (e.z == z && e.x == x && e.y == y)); //查找缓存 const found = Caches.find(e => (e.z == z && e.x == x && e.y == y)); //查找缓存
if (found == undefined) { //缓存中没有 if (found == undefined) { //缓存中没有
const obj = downloadRecord.find(e => e.z == z && e.x == x && e.y == y);//查找下载记录 console.log('缓存中没有' + z + '/' + x + '/' + y + '.png');
if (obj == undefined) { //这里不需要判断是否继续加载,在还未开始下载图片前,这里可以说是立即执行的
//如果缓存中没有,并且没有下载记录,需先判断是否继续加载 console.log(isTileShouldDownload(vp, z, x, y));//always true
if (isTileShouldDownload(vp, z, x, y)) {//如果要继续加载 const dmobj = dm.find(e => (e.z == z && e.x == x && e.y == y));
//let p = await downloadimg(z, x, y); //发起下载请求并等待结果 if (dmobj == undefined) {
//如果缓存中没有,并且没有下载记录 发起下载请求并等待结果
let p = await xhrdownloadimg(z, x, y); let p = await xhrdownloadimg(z, x, y);
return p; return p;
} }
else {//有下载记录就不用继续下载了
} else { console.log(vp.zoomLevel, vp.xoffset, vp.yoffset);
//如果缓存中没有,但是有下载记录,需先判断是否继续加载 return Promise.reject('需要等待下载完成');
if (isTileShouldDownload(vp, z, x, y)) {//如果要继续加载
return Promise.reject('需要等待下载完成或者重新发起请求');
} else {
//不需要继续加载了,但是下载请求已经发起
//不知道提前卸载掉img会不会让下载终止不然就只能考虑xmlhttprequest了 其有abort方法可以退出下载
//测试是不行需转为xmlhttprequest实现
// dm.remove(dm.find(e => (e.z == z && e.x == x && e.y == y)));
// console.log("may something work");
//xhr 中断请求
const dmobj = dm.find(e => (e.z == z && e.x == x && e.y == y));
if (dmobj) {
dmobj.xhr.abort();
dm.remove(dmobj);
console.log("主动中断 ", { z: z, x: x, y: y });
}
}
} }
} else { //缓存中有直接返回 } else { //缓存中有直接返回
//console.log('exist' + z + '/' + x + '/' + y + '.png'); console.log('缓存中有' + z + '/' + x + '/' + y + '.png');
return found.img; return found.img;
} }
} }
function debug() { function debug() {
console.log('=============debug================='); console.log('=============debug=================');
console.log('alltilecount', alltilecount); console.log('alltilecount', alltilecount);
console.log('downtilecount', downtilecount); console.log('downtilecount', downtilecount);
console.log('cachecount', Caches.length); console.log('cachecount', Caches.length);
console.log('drecord count', downloadRecord.length);
console.log('dm count', dm.length); console.log('dm count', dm.length);
console.log('=============debug================='); console.log('=============debug=================');
} }
Loading…
Cancel
Save