diff --git a/ellipsode.js b/ellipsode.js index 6ff967a..5cbca6e 100644 --- a/ellipsode.js +++ b/ellipsode.js @@ -85,62 +85,221 @@ function tile2lat(y, z) { //https://tile.openstreetmap.org/z/x/y.png //https://tile.openstreetmap.org/15/26794/14256.png +//已知条件 lat long zoom_level 显示范围的宽高 let zoom_level = 15; let lat = 22.7490073; let long = 114.3781213; -let x = lon2x(long, zoom_level); -let y = lat2y(lat, zoom_level); +let width = 1600; +let height = 900; -let tilex = lon2tile(long, zoom_level); -let tiley = lat2tile(lat, zoom_level); +function calBasetile(lat, long, zoom_level) { + let basetile = {}; + basetile.x = lon2x(long, zoom_level);//对应zoomlevel下long的x坐标 + basetile.y = lat2y(lat, zoom_level);//对应zoomlevel下lat的y坐标 + basetile.tilex = lon2tile(long, zoom_level);//对应zoomlevel下long的x tile编号 + basetile.tiley = lat2tile(lat, zoom_level);//对应zoomlevel下lat的y tile编号 + basetile.offsetx = Math.floor((basetile.x - basetile.tilex) * 256);//相对于左上角,其点的x偏移值 + basetile.offsety = Math.floor((basetile.y - basetile.tiley) * 256);//相对于左上角,其点的y偏移值 -let offsetx = Math.floor((x - tilex) * 256); -let offsety = Math.floor((y - tiley) * 256); + basetile.minx = width / 2 - basetile.offsetx; + basetile.maxx = basetile.minx + 256; + basetile.miny = height / 2 - basetile.offsety; + basetile.maxy = basetile.miny + 256; -//计算出瓦片地图的基准坐标,假设显示的宽高为1600*900 -let width = 1600; -let height = 900; -let minx = width / 2 - offsetx; -let maxx = minx + 256; -let miny = height / 2 - offsety; -let maxy = miny + 256; + basetile.p1 = Math.floor(basetile.maxy / 256 + 0.5); + basetile.p2 = Math.floor((height - basetile.miny) / 256 + 0.5); + basetile.p3 = Math.floor(basetile.maxx / 256 + 0.5); + basetile.p4 = Math.floor((width - basetile.minx) / 256 + 0.5); + console.log(basetile); + return basetile; +} + +let basetile = calBasetile(lat, long, zoom_level); + +// let x = lon2x(long, zoom_level); +// let y = lat2y(lat, zoom_level); + +// let tilex = lon2tile(long, zoom_level); +// let tiley = lat2tile(lat, zoom_level); + +// let offsetx = Math.floor((x - tilex) * 256); +// let offsety = Math.floor((y - tiley) * 256); + +// //计算出瓦片地图的基准坐标,假设显示的宽高为1600*900 +// let minx = width / 2 - offsetx; +// let maxx = minx + 256; +// let miny = height / 2 - offsety; +// let maxy = miny + 256; //计算出四个方向各需要的块数 //p1 p2 p3 p4 上 下 左 右 -let p1 = Math.floor(maxy / 256 + 0.5); -let p2 = Math.floor((height - miny) / 256 + 0.5); -let p3 = Math.floor(maxx / 256 + 0.5); -let p4 = Math.floor((width - minx) / 256 + 0.5); +// let p1 = Math.floor(maxy / 256 + 0.5); +// let p2 = Math.floor((height - miny) / 256 + 0.5); +// let p3 = Math.floor(maxx / 256 + 0.5); +// let p4 = Math.floor((width - minx) / 256 + 0.5); //基于已知条件计算需要的各个tile -let tiles = new Array(); -tiles.push({ x: tilex, y: tiley }); -for (let i = 1; i < p4; i++) { - tiles.push({ x: tilex + i, y: tiley }); -} -for (let i = 1; i < p3; i++) { - tiles.push({ x: tilex - i, y: tiley }); -} -for (let i = 1; i < p1; i++) { - for (let j = 0; j < p3 + p4 - 1; j++) { - tiles.push({ x: tilex - p3 + 1 + j, y: tiley - i }); +function needtiles(basetile, p1, p2, p3, p4) { + let tiles = new Array(); + let tilex = basetile.tilex; + let tiley = basetile.tiley; + tiles.push({ x: tilex, y: tiley }); + for (let i = 0; i < p4; i++) { + tiles.push({ x: tilex + i + 1, y: tiley }); } -} -for (let i = 1; i < p2; i++) { - for (let j = 0; j < p3 + p4 - 1; j++) { - tiles.push({ x: tilex - p3 + 1 + j, y: tiley + i }); + for (let i = 0; i < p3; i++) { + tiles.push({ x: tilex - i - 1, y: tiley }); + } + for (let i = 0; i < p1; i++) { + for (let j = 0; j < p3 + p4 + 1; j++) { + tiles.push({ x: tilex - p3 + j, y: tiley - i - 1 }); + } + } + for (let i = 0; i < p2; i++) { + for (let j = 0; j < p3 + p4 + 1; j++) { + tiles.push({ x: tilex - p3 + j, y: tiley + i + 1 }); + } } + //console.log(tiles); + //console.log(tiles.length); + return tiles; } -console.log(tiles); -console.log(tiles.length); + +let tiles = needtiles(basetile, basetile.p1, basetile.p2, basetile.p3, basetile.p4); + //渲染问题 //通过与基准之间的位置关系计算渲染的坐标 //minx miny 即为基准tile当前渲染位置 -for (let i = 0; i < tiles.length; i++) { - const element = tiles[i]; - let renderx = (element.x - tilex) * 256 + minx; - let rendery = (element.y - tiley) * 256 + miny; - console.log({ x: renderx, y: rendery }); +// for (let i = 0; i < tiles.length; i++) { +// const element = tiles[i]; +// let renderx = (element.x - tilex) * 256 + minx; +// let rendery = (element.y - tiley) * 256 + miny; +// console.log({ x: renderx, y: rendery }); +// } + +let canvas = document.getElementById('map'); +canvas.width = map.clientWidth; +canvas.height = map.clientHeight; +let ctx = canvas.getContext('2d'); + +function clearcanvas() { + ctx.clearRect(0, 0, canvas.width, canvas.height); +} + +function drawPoint(x, y) { + ctx.fillStyle = "white" + ctx.strokeStyle = "#a35312" + ctx.beginPath(); + ctx.arc(x, y, 3, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); +} + +function drawRect(x, y) { + ctx.strokeStyle = "white" + ctx.strokeRect(x, y, 256, 256); +} + +function drawtext(text, x, y) { + ctx.fillStyle = "white" + ctx.font = "18px serif"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillText(text, x, y); +} + +function drawgrid(basetile, tiles) { + let minx = basetile.minx; + let miny = basetile.miny; + let offsetx = basetile.offsetx; + let offsety = basetile.offsety; + let tilex = basetile.tilex; + let tiley = basetile.tiley; + clearcanvas(); + drawPoint(minx + offsetx, miny + offsety); + for (let i = 0; i < tiles.length; i++) { + const element = tiles[i]; + let renderx = (element.x - tilex) * 256 + minx; + let rendery = (element.y - tiley) * 256 + miny; + //console.log({ x: renderx, y: rendery }); + drawPoint(renderx, rendery); + drawRect(renderx, rendery); + const showtext = 'x:' + element.x + ' ' + 'y:' + element.y; + //drawtext(showtext, renderx + 256 / 2, rendery + 256 / 2); + drawtext(showtext, renderx + showtext.length / 4 * 18 + 4, rendery + 9); + } +} + +drawgrid(basetile, tiles); + +// drawPoint(width / 2, height / 2); + +// const element = tiles[0]; +// let renderx = (element.x - tilex) * 256 + minx; +// let rendery = (element.y - tiley) * 256 + miny; +// drawPoint(renderx, rendery); +// drawPoint(renderx + 256 / 2, rendery + 256 / 2); +// drawRect(renderx, rendery); + +// drawtext(showtext, renderx + 256 / 2, rendery + 256 / 2); +// console.log({ x: renderx, y: rendery }); + +//实现移动缩放方法 +//缩放 +map.onwheel = (e) => { + //console.log(e); + const zoomleveloffset = (e.deltaY > 0) ? 1 : -1; + zoom_level -= zoomleveloffset; + if (zoom_level < 0) { + zoom_level = 0; + return; + } + + if (zoom_level > 19) { + zoom_level = 19; + return; + } + console.log(zoom_level); + //clearcanvas(); + //重新计算basetile + basetile = calBasetile(lat, long, zoom_level); + tiles = needtiles(basetile, basetile.p1, basetile.p2, basetile.p3, basetile.p4); + drawgrid(basetile, tiles); +} + +let moveflag = false; +let downpoing = { x: 0, y: 0 }; + +map.onmousedown = (e) => { + console.log('鼠标按下'); + moveflag = true; + downpoing.x = e.offsetX; + downpoing.y = e.offsetY; +} + +map.onmouseup = (e) => { + console.log('鼠标松开'); + moveflag = false; +} + +map.onmousemove = (e) => { + if (moveflag) { + console.log('有效位移'); + const movex = downpoing.x - e.offsetX; + const movey = downpoing.y - e.offsetY; + //实现移动逻辑 + let xp = basetile.x + movex / 256;//注意像素移动要除以256 + let yp = basetile.y + movey / 256; + long = tile2long(xp, zoom_level); + lat = tile2lat(yp, zoom_level); + basetile = calBasetile(lat, long, zoom_level); + tiles = needtiles(basetile, basetile.p1, basetile.p2, basetile.p3, basetile.p4); + drawgrid(basetile, tiles); + + downpoing.x = e.offsetX; + downpoing.y = e.offsetY; + } } \ No newline at end of file diff --git a/index.html b/index.html index cbe914e..097895d 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,8 @@ align-items: center; } .map{ - background-color: rgb(79, 38, 38); + /* background-color: #ddd; */ + background-color: #4c2626; width: 1600px; height: 900px; } @@ -37,6 +38,6 @@ - + \ No newline at end of file