|
|
|
|
@ -0,0 +1,433 @@
|
|
|
|
|
//help array;
|
|
|
|
|
let Caches = new Array(); //cache
|
|
|
|
|
let downloadRecord = new Array();
|
|
|
|
|
let dm = new Array();//尝试增加下载管理 downloadmanager
|
|
|
|
|
|
|
|
|
|
let alltilecount = 0;
|
|
|
|
|
let downtilecount = 0;
|
|
|
|
|
|
|
|
|
|
function ViewPort(canvasId, options) {
|
|
|
|
|
// allow without 'new'
|
|
|
|
|
if (!(this instanceof ViewPort)) return new ViewPort(canvasId, options);
|
|
|
|
|
this.TILESIZE = 256;//实际的底图大小
|
|
|
|
|
//init
|
|
|
|
|
this.canvas = document.getElementById(canvasId);
|
|
|
|
|
this.canvas.width = this.canvas.clientWidth;
|
|
|
|
|
this.canvas.height = this.canvas.clientHeight;
|
|
|
|
|
|
|
|
|
|
this.ctx = this.canvas.getContext('2d');
|
|
|
|
|
this.width = this.canvas.clientWidth;
|
|
|
|
|
this.height = this.canvas.clientHeight;
|
|
|
|
|
if (!options) options = {};//options could be null or undefine
|
|
|
|
|
this.minZoomLevel = options.minZoomLevel ?? 0;
|
|
|
|
|
this.maxZoomLevel = options.maxZoomLevel ?? 21;
|
|
|
|
|
this.zoomLevel = options.zoomLevel ?? 0;
|
|
|
|
|
this.dzl = options.dzl ?? 0.25; // zoomlevel offset value
|
|
|
|
|
this.rtSize = calTileSize(this.TILESIZE, this.zoomLevel);//named rtSize because real time tile size
|
|
|
|
|
|
|
|
|
|
const defaultCenterX = Math.pow(2, this.zoomLevel) * this.TILESIZE / 2;
|
|
|
|
|
const defaultCenterY = Math.pow(2, this.zoomLevel) * this.TILESIZE / 2;
|
|
|
|
|
this.xoffset = this.width / 2 - defaultCenterX;
|
|
|
|
|
this.yoffset = this.height / 2 - defaultCenterY;
|
|
|
|
|
|
|
|
|
|
//如果在options中有指定地图中心点
|
|
|
|
|
//options.centerLng && options.centerLat
|
|
|
|
|
if (options.centerLat != null && options.centerLng != null
|
|
|
|
|
&& !isNaN(options.centerLat) && !isNaN(options.centerLng)) {
|
|
|
|
|
console.log('指定中心点');
|
|
|
|
|
try {
|
|
|
|
|
({ lat: lat, lng: lng } = this.latlngPreCheck(options.centerLat, options.centerLng));
|
|
|
|
|
const my = lat2y(lat, this.zoomLevel) * this.TILESIZE;
|
|
|
|
|
const mx = lon2x(lng, this.zoomLevel) * this.TILESIZE;
|
|
|
|
|
this.xoffset = this.width / 2 - mx;
|
|
|
|
|
this.yoffset = this.height / 2 - my;
|
|
|
|
|
//console.log('check ', this.viewport2Latlng(this.width / 2, this.height / 2));
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log('使用默认中心点');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.needtiles = new Array();//需要加载的底图 实时变化
|
|
|
|
|
|
|
|
|
|
//move
|
|
|
|
|
let moveflag = false;
|
|
|
|
|
let downpoing = { x: 0, y: 0 };
|
|
|
|
|
this.canvas.onmousedown = (e) => {
|
|
|
|
|
moveflag = true;
|
|
|
|
|
[downpoing.x, downpoing.y] = [e.offsetX, e.offsetY];
|
|
|
|
|
//坐标转换 debug
|
|
|
|
|
//console.log(this.zoomLevel, e.offsetX, e.offsetY);
|
|
|
|
|
const wgs84 = this.viewport2Latlng(e.offsetX, e.offsetY);
|
|
|
|
|
console.log('clicked', wgs84);
|
|
|
|
|
}
|
|
|
|
|
this.canvas.onmouseup = (e) => {
|
|
|
|
|
moveflag = false;
|
|
|
|
|
}
|
|
|
|
|
this.canvas.onmouseout = () => {
|
|
|
|
|
moveflag = false;//从元素范围外移动回来时不会继续移动,必须松开左键,按下左键后再进行移动
|
|
|
|
|
}
|
|
|
|
|
this.canvas.onmousemove = (e) => {
|
|
|
|
|
if (moveflag) {
|
|
|
|
|
const movex = downpoing.x - e.offsetX;
|
|
|
|
|
const movey = downpoing.y - e.offsetY;
|
|
|
|
|
//实现移动逻辑
|
|
|
|
|
this.xoffset -= movex;
|
|
|
|
|
this.yoffset -= movey;
|
|
|
|
|
|
|
|
|
|
this.drawTiles();
|
|
|
|
|
downpoing.x = e.offsetX;
|
|
|
|
|
downpoing.y = e.offsetY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//scale
|
|
|
|
|
this.canvas.onwheel = (e) => {
|
|
|
|
|
const dzl = this.dzl;
|
|
|
|
|
const zoomleveloffset = (e.deltaY > 0) ? 1 * dzl : -1 * dzl;
|
|
|
|
|
const oldz = this.zoomLevel;
|
|
|
|
|
this.zoomLevel = this.zoomLevel - zoomleveloffset;
|
|
|
|
|
if (this.zoomLevel < this.minZoomLevel) {
|
|
|
|
|
this.zoomLevel = this.minZoomLevel;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.zoomLevel > this.maxZoomLevel) {
|
|
|
|
|
this.zoomLevel = this.maxZoomLevel;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//console.log(this.zoomLevel, e.offsetX, e.offsetY);
|
|
|
|
|
this.updateViewport(e.offsetX, e.offsetY, oldz, this.zoomLevel);
|
|
|
|
|
this.drawTiles();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.drawTiles();
|
|
|
|
|
|
|
|
|
|
// setInterval(() => {
|
|
|
|
|
// debug();
|
|
|
|
|
// }, 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//扩展一下Array 用以辅助进行加载底图
|
|
|
|
|
Array.prototype.remove = function (val) {
|
|
|
|
|
const index = this.indexOf(val);
|
|
|
|
|
if (index > -1) {
|
|
|
|
|
return this.splice(index, 1);
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ViewPort.prototype = {
|
|
|
|
|
latlngPreCheck(lat, lng) {
|
|
|
|
|
//数据超界处理 经度 -180 180
|
|
|
|
|
//纬度 < 85.0511287798066 (2*Math.atan(Math.pow(Math.E,Math.PI))-Math.PI/2)/Math.PI*180
|
|
|
|
|
const latlimit = 85.0511287798066;//取近似值
|
|
|
|
|
const lngp = lng - Math.floor((lng + 180) / 360) * 360;
|
|
|
|
|
if (lat < (0 - latlimit) || lat > latlimit) {
|
|
|
|
|
throw "OutMapRange";
|
|
|
|
|
}
|
|
|
|
|
return { lat: lat, lng: lngp };
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
mplatPreCheck(mx, my) {
|
|
|
|
|
//数据超界处理, 这里是对应缩放等级的地图的大小,底图大小*底图块数 注意底图块数始终为整数level时的底图块数
|
|
|
|
|
//实际只改变的底图大小,没有改变块数
|
|
|
|
|
let limit = calTileSize(this.TILESIZE, this.zoomLevel) * Math.pow(2, this.zoomLevel);
|
|
|
|
|
if (this.zoomLevel != Math.floor(this.zoomLevel)) {
|
|
|
|
|
limit = calTileSize(this.TILESIZE, this.zoomLevel) * Math.pow(2, Math.floor(this.zoomLevel + 1));
|
|
|
|
|
}
|
|
|
|
|
if (mx <= 0 || my <= 0 || mx >= limit || my >= limit) {
|
|
|
|
|
throw "OutMapRange";
|
|
|
|
|
}
|
|
|
|
|
return { x: mx, y: my };
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//-------------------------------------
|
|
|
|
|
//这几个函数是坐标转换函数
|
|
|
|
|
mplat2Viewport(mx, my) {
|
|
|
|
|
const vx = mx + this.xoffset;
|
|
|
|
|
const vy = my + this.yoffset;
|
|
|
|
|
return { x: vx, y: vy };
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
viewport2Mplat(vx, vy) {
|
|
|
|
|
const mx = vx - this.xoffset;
|
|
|
|
|
const my = vy - this.yoffset;
|
|
|
|
|
return { x: mx, y: my };
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
viewport2Latlng(vx, vy) {
|
|
|
|
|
let mplatc = this.viewport2Mplat(vx, vy); //mplat coordinates
|
|
|
|
|
mplatc = this.mplatPreCheck(mplatc.x, mplatc.y);
|
|
|
|
|
const lat = tile2lat(mplatc.y / this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const lng = tile2long(mplatc.x / this.TILESIZE, this.zoomLevel);
|
|
|
|
|
return { lat: lat, lng: lng }
|
|
|
|
|
},
|
|
|
|
|
latlng2Viewport(lat, lng) {
|
|
|
|
|
({ lat: lat, lng: lng } = this.latlngPreCheck(lat, lng));//尝试使用解构赋值
|
|
|
|
|
const my = lat2y(lat, this.zoomLevel) * this.TILESIZE;
|
|
|
|
|
const mx = lon2x(lng, this.zoomLevel) * this.TILESIZE;
|
|
|
|
|
const vp = this.mplat2Viewport(mx, my);
|
|
|
|
|
return { x: vp.x, y: vp.y };
|
|
|
|
|
},
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
|
|
|
|
|
//更新偏移值
|
|
|
|
|
updateViewport(scrollx, scrolly, oldz, newz) {
|
|
|
|
|
//计算出缩放后坐标系的偏移值
|
|
|
|
|
// xv = xm + offset ; offset = xv - xm
|
|
|
|
|
const scrollm = this.viewport2Mplat(scrollx, scrolly);
|
|
|
|
|
const basescale = Math.pow(2, newz - oldz);
|
|
|
|
|
const newscrollm = { x: scrollm.x * basescale, y: scrollm.y * basescale };
|
|
|
|
|
this.xoffset = scrollx - newscrollm.x;
|
|
|
|
|
this.yoffset = scrolly - newscrollm.y;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//过滤需要加载的底图
|
|
|
|
|
tilesFilter(tails) {
|
|
|
|
|
let news = new Array();
|
|
|
|
|
let max = Math.pow(2, this.zoomLevel);
|
|
|
|
|
if (this.zoomLevel != Math.floor(this.zoomLevel)) {
|
|
|
|
|
max = Math.pow(2, Math.floor(this.zoomLevel + 1));
|
|
|
|
|
}
|
|
|
|
|
for (let i = 0; i < tails.length; i++) {
|
|
|
|
|
const e = tails[i];
|
|
|
|
|
if (e.x >= 0 && e.y >= 0 && e.x < max && e.y < max) {
|
|
|
|
|
news.push(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return news;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//一些绘制函数
|
|
|
|
|
clearCanvas() {
|
|
|
|
|
this.ctx.clearRect(0, 0, this.width, this.height);
|
|
|
|
|
},
|
|
|
|
|
drawRect(x, y, width, height) {
|
|
|
|
|
this.ctx.strokeStyle = "white"
|
|
|
|
|
this.ctx.strokeRect(x, y, width, height);
|
|
|
|
|
},
|
|
|
|
|
drawtext(text, x, y) {
|
|
|
|
|
this.ctx.fillStyle = "white"
|
|
|
|
|
this.ctx.font = "18px serif";
|
|
|
|
|
this.ctx.textAlign = "center";
|
|
|
|
|
this.ctx.textBaseline = "middle";
|
|
|
|
|
this.ctx.fillText(text, x, y);
|
|
|
|
|
},
|
|
|
|
|
drawTiles() {
|
|
|
|
|
this.clearCanvas();
|
|
|
|
|
const viewport_left_top = this.viewport2Mplat(0, 0);
|
|
|
|
|
const viewport_right_bottom = this.viewport2Mplat(this.width, this.height);
|
|
|
|
|
const mixnum = calTileNum(viewport_left_top.x, this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const miynum = calTileNum(viewport_left_top.y, this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const maxnum = calTileNum(viewport_right_bottom.x, this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const maynum = calTileNum(viewport_right_bottom.y, this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const horicount = maxnum - mixnum + 1;
|
|
|
|
|
const verticount = maynum - miynum + 1;
|
|
|
|
|
let tails = new Array();
|
|
|
|
|
for (let i = 0; i < horicount; i++) {
|
|
|
|
|
for (let j = 0; j < verticount; j++) {
|
|
|
|
|
const x = mixnum + i;
|
|
|
|
|
const y = miynum + j;
|
|
|
|
|
tails.push({ x: x, y: y });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.needtiles = this.tilesFilter(tails);//获取当前视口要渲染的底图
|
|
|
|
|
alltilecount += this.needtiles.length;//for debug
|
|
|
|
|
//console.log(this.needtiles);
|
|
|
|
|
this.needtiles.forEach(et => {
|
|
|
|
|
const etsize = calTileSize(this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const tilev = this.mplat2Viewport(et.x * etsize, et.y * 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`;
|
|
|
|
|
// console.log(text);
|
|
|
|
|
this.drawtext(text, tilev.x + etsize / 2, tilev.y + etsize / 2);
|
|
|
|
|
this.drawTileImg(z, et.x, et.y);
|
|
|
|
|
});
|
|
|
|
|
//debug();
|
|
|
|
|
},
|
|
|
|
|
drawTileImg(z, x, y) {
|
|
|
|
|
|
|
|
|
|
const img = getImg(this, z, x, y);
|
|
|
|
|
img.then((e) => {
|
|
|
|
|
if (isTileShouldDownload(this, z, x, y)) {
|
|
|
|
|
//对e添加判断,似乎不是每一个e都是一个图片
|
|
|
|
|
if (e instanceof ImageBitmap) {
|
|
|
|
|
const etsize = calTileSize(this.TILESIZE, this.zoomLevel);
|
|
|
|
|
const tilev = this.mplat2Viewport(x * etsize, y * etsize);
|
|
|
|
|
this.ctx.drawImage(e, tilev.x, tilev.y, etsize, etsize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).catch((e) => {
|
|
|
|
|
console.log(e);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//计算实时底图大小
|
|
|
|
|
function calTileSize(tilesize, zoomLevel) {
|
|
|
|
|
let rtSize = tilesize;
|
|
|
|
|
if (zoomLevel != Math.floor(zoomLevel)) {
|
|
|
|
|
rtSize = tilesize * Math.pow(2, zoomLevel - Math.floor(zoomLevel + 1));
|
|
|
|
|
}
|
|
|
|
|
return rtSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//计算当前坐标值所在的底图编号
|
|
|
|
|
function calTileNum(coord, tilesize, zoomLevel) {
|
|
|
|
|
return Math.floor(coord / calTileSize(tilesize, zoomLevel));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=====coord about 地理坐标与墨卡托投影的相关转换方法=====
|
|
|
|
|
function lon2tile(lon, z) {
|
|
|
|
|
return (Math.floor((lon + 180) / 360 * Math.pow(2, z)));
|
|
|
|
|
}
|
|
|
|
|
function lat2tile(lat, z) {
|
|
|
|
|
return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
|
|
|
|
|
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
|
|
|
|
|
2 * Math.pow(2, z)));
|
|
|
|
|
}
|
|
|
|
|
function lon2x(lon, z) {
|
|
|
|
|
return ((lon + 180) / 360 * Math.pow(2, z));
|
|
|
|
|
}
|
|
|
|
|
function lat2y(lat, z) {
|
|
|
|
|
return ((1 - Math.log(Math.tan(lat * Math.PI / 180) +
|
|
|
|
|
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
|
|
|
|
|
2 * Math.pow(2, z));
|
|
|
|
|
}
|
|
|
|
|
function tile2long(x, z) {
|
|
|
|
|
return (x / Math.pow(2, z) * 360 - 180);
|
|
|
|
|
}
|
|
|
|
|
function tile2lat(y, 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))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========下载图片相关==================
|
|
|
|
|
//将其和viewpoint分离,方便后续修复问题和增加新的下载方式或者底图源
|
|
|
|
|
|
|
|
|
|
//判断一张底图需不需要继续下载,这里采用保守一点的下载策略,必须是先判定为需要加载的底图才开始下载
|
|
|
|
|
//传入vp以获取相关参数
|
|
|
|
|
function isTileShouldDownload(vp, z, x, y) {
|
|
|
|
|
let fz = vp.zoomLevel;
|
|
|
|
|
if (vp.zoomLevel != Math.floor(vp.zoomLevel)) {
|
|
|
|
|
fz = Math.floor(vp.zoomLevel + 1);
|
|
|
|
|
}
|
|
|
|
|
if (vp.needtiles.find(t => z == fz && t.x == x && t.y == y)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//add autonavi
|
|
|
|
|
function downloadimg(z, x, y) {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
//const url = `https://tile.openstreetmap.org/${z}/${x}/${y}.png`;
|
|
|
|
|
const url = 'http://webrd01.is.autonavi.com/' +
|
|
|
|
|
'appmaptile?lang=zh_cn&size=1&scale=1&style=8' +
|
|
|
|
|
`&x=${x}&y=${y}&z=${z}`;
|
|
|
|
|
//add downloadcheck
|
|
|
|
|
const obj = { z: z, x: x, y: y };
|
|
|
|
|
downloadRecord.push(obj); //下载前加入记录
|
|
|
|
|
let img = new Image();
|
|
|
|
|
const dmobj = { img: img, z: z, x: x, y: y };
|
|
|
|
|
img.onload = () => {
|
|
|
|
|
//console.log('downloaded' + z + '/' + x + '/' + y + '.png');
|
|
|
|
|
downloadRecord.remove(obj); //下载完成后从记录中移除
|
|
|
|
|
dm.remove(dmobj);
|
|
|
|
|
Caches.push({ img: img, z: z, x: x, y: y });//下载完成后加入缓存
|
|
|
|
|
downtilecount += 1;
|
|
|
|
|
resolve(img);
|
|
|
|
|
}
|
|
|
|
|
img.src = url;
|
|
|
|
|
dm.push(dmobj);//尝试添加管理
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//尝试优化图片下载机制 //采用下载速度比较慢的openstreetmap 测试
|
|
|
|
|
function xhrdownloadimg(z, x, y) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const url = `https://tile.openstreetmap.org/${z}/${x}/${y}.png`;
|
|
|
|
|
let imgxhr = new XMLHttpRequest();
|
|
|
|
|
imgxhr.open('GET', url, true);
|
|
|
|
|
|
|
|
|
|
//add downloadcheck
|
|
|
|
|
const obj = { z: z, x: x, y: y };
|
|
|
|
|
downloadRecord.push(obj); //下载前加入一条记录
|
|
|
|
|
const dmobj = { xhr: imgxhr, z: z, x: x, y: y };
|
|
|
|
|
|
|
|
|
|
//imgxhr.withCredentials = true;
|
|
|
|
|
imgxhr.responseType = 'blob';
|
|
|
|
|
imgxhr.onload = function (e) {
|
|
|
|
|
if (this.status === 200 && imgxhr.response) {
|
|
|
|
|
let blob = new Blob([imgxhr.response], { type: 'image/png' });
|
|
|
|
|
let img = createImageBitmap(blob);
|
|
|
|
|
Caches.push({ img: img, z: z, x: x, y: y });
|
|
|
|
|
downtilecount += 1;
|
|
|
|
|
downloadRecord.remove(obj); //下载完成后将记录移除
|
|
|
|
|
dm.remove(dmobj);
|
|
|
|
|
resolve(img);
|
|
|
|
|
} else {
|
|
|
|
|
reject('下载似乎失败了');
|
|
|
|
|
dm.remove(dmobj);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
dm.push(dmobj); //保存xhr对象 和xyz索引
|
|
|
|
|
imgxhr.send(null);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function getImg(vp, z, x, y) {
|
|
|
|
|
const found = Caches.find(e => (e.z == z && e.x == x && e.y == y));//查找缓存
|
|
|
|
|
if (found == undefined) {//缓存中没有
|
|
|
|
|
const obj = downloadRecord.find(e => e.z == z && e.x == x && e.y == y);//查找下载记录
|
|
|
|
|
if (obj == undefined) {
|
|
|
|
|
//如果缓存中没有,并且没有下载记录,需先判断是否继续加载
|
|
|
|
|
if (isTileShouldDownload(vp, z, x, y)) {//如果要继续加载
|
|
|
|
|
//let p = await downloadimg(z, x, y); //发起下载请求并等待结果
|
|
|
|
|
let p = await xhrdownloadimg(z, x, y);
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
//如果缓存中没有,但是有下载记录,需先判断是否继续加载
|
|
|
|
|
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 {//缓存中有直接返回
|
|
|
|
|
//console.log('exist' + z + '/' + x + '/' + y + '.png');
|
|
|
|
|
return found.img;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function debug() {
|
|
|
|
|
console.log('=============debug=================');
|
|
|
|
|
console.log('alltilecount', alltilecount);
|
|
|
|
|
console.log('downtilecount', downtilecount);
|
|
|
|
|
console.log('cachecount', Caches.length);
|
|
|
|
|
console.log('drecord count', downloadRecord.length);
|
|
|
|
|
console.log('dm count', dm.length);
|
|
|
|
|
console.log('=============debug=================');
|
|
|
|
|
}
|