通过canvas加载geojson深入解析添加切片本质
let canvas
let ctx
let height
let width
let lastZoom = 0
const TILE_SIZE = 256
let mapCenter = [108.148732, 36.231006]
let zoom = 7
let minZoom =6
let maxZoom = 17
var resolutions = [1.40782601571, 0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.005493164063, 0.002746582031, 0.001373291016, 0.000686645508, 0.000343322754, 0.000171661377, 0.000085830688, 0.000042915344, 0.000021457672, 0.000010728836, 0.000005364418, 0.000002682209, 0.000001341105]
function createCanvas() {
canvas = document.getElementById('canvas');
canvas.height = window.innerHeight
canvas.width = window.innerWidth
height = canvas.height
width = canvas.width
ctx = canvas.getContext('2d')
ctx.translate(width / 2, height / 2)
initEvent()
}
function initMap() {
ctx.clearRect(-width / 2, -height / 2, width, height)
// ctx.save(); //保存初始状态
const centerTile = getTileRowAndCol(...mapCenter, zoom)
//中心瓦片左上角对应的像素坐标位置
let centerTilePos = [centerTile[0] * TILE_SIZE, centerTile[1] * TILE_SIZE]
//中心点对应的像素坐标位置
let centerPos = getPxFromLngLat(...mapCenter, zoom)
//差值
let offset = [centerPos[0] - centerTilePos[0], centerPos[1] - centerTilePos[1]]
let halfCanvasWidth = canvas.width / 2
let halfCanvasHeight = canvas.height / 2
let rowMinNum = Math.ceil((halfCanvasWidth - offset[0]) / TILE_SIZE)
let colMinNum = Math.ceil((halfCanvasHeight - offset[1]) / TILE_SIZE)
let rowMaxNum = Math.ceil((halfCanvasWidth - (TILE_SIZE - offset[0])) / TILE_SIZE)
let colMaxNum = Math.ceil((halfCanvasHeight - (TILE_SIZE - offset[1])) / TILE_SIZE)
for(let i = -rowMinNum; i <= rowMaxNum; i++) {
for(let j = -colMinNum; j <= colMaxNum; j++) {
let row = centerTile[0] + i
let col = centerTile[1] + j
let x = i * TILE_SIZE - offset[0]
let y = j * TILE_SIZE - offset[1]
gettile(row, col, zoom, y, x)
}
}
}
function initEvent() {
let isMouseDown = false
canvas.onmousedown = e => {
if(e.button === 0) {
isMouseDown = true
}
}
canvas.onmousemove = e => {
if(!isMouseDown) return
console.log(e.movementX, 'e.movementX')
console.log(e.movementY, 'e.movementY')
let mx = e.movementX * resolutions[zoom]
let my = e.movementY * resolutions[zoom]
mapCenter = [mapCenter[0] - mx, mapCenter[1] + my];
initMap()
}
canvas.onmouseup = e => {
isMouseDown = false
}
canvas.onmousewheel = e => {
if(e.deltaY > 0) {
if(zoom > minZoom) {
zoom--
}
} else {
if(zoom < maxZoom) {
zoom++
}
}
if(lastZoom === zoom) return
initMap()
}
}
function getPxFromLngLat(lng, lat, z) {
const resolution = resolutions[z]
const x = Math.floor((lng + 180) / resolution)
const y = Math.floor((90 - lat) / resolution)
return [y, x]
}
function gettile(row, col, zoom, x, y) {
let url = "http://10.61.5.99:6009/tdt/SxBaseMap_XX/tile/" + zoom + "/" + row + "/" + col + ".png";
let img = new Image()
img.src = url
img.onload = () => {
ctx.drawImage(img, x, y)
}
}
function getTileRowAndCol(lng, lat, z) {
let resolution = resolutions[z]
let col = Math.floor((lng + 180) / resolution / 256);
let row = Math.floor((90 - lat) / resolution * 2 / 256);
return [row, col]
}
createCanvas()
window.requestAnimationFrame(initMap)
加载完成如图所示: