实现移动缩放方法

main
nxiaoxiao 3 years ago
parent caacca7d4a
commit 68792efd35

@ -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;
}
}

@ -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 @@
<canvas class="map" id="map"></canvas>
</div>
</div>
<script src="./ellipsode.js"></script>
<script src="../ellipsode.js"></script>
</body>
</html>
Loading…
Cancel
Save