(经纬度转平面坐标、平面坐标转经纬度坐标)
/**
* @description: 设置坐标投影
* @param {} projection 坐标投影变化
* @return {}
*/
setProjection(projection) {
this._projection = projection;
//const bound: Bound = this._projection.bound;
//this._ctx.setTransform(256 * Math.pow(2, this._zoom) / (bound.xmax - bound.xmin) * bound.xscale , 0, 0, 256 * Math.pow(2, this._zoom) / (bound.ymax - bound.ymin) * bound.yscale, this._canvas.width / 2, this._canvas.height / 2);
//center为经纬度,转化为平面坐标
const origin = this._projection.project(this._center as any);
const bound: Bound = this._projection.bound;
// 已知:地理坐标origin,转换后屏幕坐标,即canvans的中心,【this.canvans.width / 2, this.canvans.height / 2】
// 求:屏幕坐标转换矩阵=Ma初始矩阵:地理坐标转屏幕坐标
const a = 256 * Math.pow(2, this._zoom) / (bound.xmax - bound.xmin) * bound.xscale;
const d = 256 * Math.pow(2, this._zoom) / (bound.ymax - bound.ymin) * bound.yscale;
const e = this._canvas.width / 2 - a * origin[0];
const f = this._canvas.height / 2 - d * origin[1];
this._ctx.setTransform(a, 0, 0, d, e, f);
}
//响应滚轮缩放
_onWheel(event) {
event.preventDefault();
const sevsitivity = 5;
if (Math.abs(event.deltaY) <= sevsitivity) return;
const delta = event.deltaY < 0 ? -1 : 1;
let scale = 1;
if (delta < 0) {
// 放大
scale *= delta * -2;
} else {
// 缩小
scale /= delta * -2;
}
let zoom = Math.round(Math.log(scale));
if (zoom > 0) {
// 放大
zoom = this._zoom + zoom >= 20 ? 20 - this._zoom : zoom;
} else if (zoom < 0) {
// 缩小
zoom = this._zoom + zoom <= 3 ? 3 - this._zoom : zoom;
}
if (zoom == 0) return;
this._zoom += zoom;
scale = Math.pow(2, zoom);
// 交互设计表现为 鼠标当前位置 屏幕坐标不变,进行缩放 即 x2 = x1 y2 = y1
// 其他设定:变换前矩阵(a1,0,0,d1,e1,f1)变换矩阵(a,0,0,d,e,f)变换后矩阵(a2,0,0,d2,e2,f2)
// scale已经通过滚轮变换得到, 且a=d=scale ,求e和f
// 1.将原屏幕坐标x1转换成地理坐标 x0 = (x1 -ee1) / a1
// 2.地理坐标x0 转换成现屏幕坐标x2 a2 *x0 + e2 = x2, e2 = x2 - a2 * x0,代入1式 e2 = x2 - a2 * (x1 - e1) / a1
// 3.已知scale = a2 / a1 故 e2 = x2 - scale * (x1- e1)
// 4.另矩阵变换 a1 * e + e1 = e2
// 5.联立3和4求得 e = (x2 - scale * (x1 - e1) - e1) / a1
const matrix = (this._ctx as any).getTransform();
const a1 = matrix.a, e1 = matrix.e, x1 = event.x, x2 = x1;// 放大到中心点 x2 = this._canvas.width / 2
const e = (x2 - scale * (x1 - e1) - e1) / a1;
const d1 = matrix.d, f1 = matrix.f, y1 = event.y, y2 = y1;//放大到中心点 y2 = this._canvas.height / 2
const f = (y2 - scale * (y1 - f1) - f1) / d1;
this._ctx.transform(scale, 0, 0, scale, e, f);
this.redraw();
}