添加相关计算的方法和逻辑
parent
b88ba1b23f
commit
caacca7d4a
@ -0,0 +1,146 @@
|
|||||||
|
//椭球相关参数计算
|
||||||
|
const a = 6378137; //长半轴 a
|
||||||
|
const f = 1 / 298.257223563; //扁率 (a-b)/a
|
||||||
|
const b = a * (1 - f);//短半轴 b
|
||||||
|
const e = Math.sqrt(a * a - b * b) / a;//椭球第一偏心率
|
||||||
|
|
||||||
|
// console.log(a);
|
||||||
|
// console.log(f);
|
||||||
|
// console.log(b);
|
||||||
|
// console.log(e);
|
||||||
|
// console.log(e*e);
|
||||||
|
|
||||||
|
function degToRad(deg) {
|
||||||
|
return deg / 180 * Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
function radToDeg(rad) {
|
||||||
|
return rad / Math.PI * 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wgs84ToWebMercator(lat, lon) {
|
||||||
|
let x = a * lon;
|
||||||
|
let y = a * Math.log(Math.tan(Math.PI / 4 + lat / 2));
|
||||||
|
return { x: x, y: y };
|
||||||
|
}
|
||||||
|
|
||||||
|
function webMercatorToWgs84(x, y) {
|
||||||
|
let lon = x / a;
|
||||||
|
let lat = 2 * Math.atan(Math.pow(Math.E, y / a)) - Math.PI / 2;
|
||||||
|
return { lon: lon, lat: lat }
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(wgs84ToWebMercator(degToRad(50), degToRad(50)));
|
||||||
|
// console.log(wgs84ToWebMercator(degToRad(49.99999999999999), degToRad(49.99999999999999)));
|
||||||
|
// let wgs = webMercatorToWgs84(5565974.539663678, 6446275.841017158);
|
||||||
|
// console.log(wgs);
|
||||||
|
// console.log('lat: ' + radToDeg(wgs.lat) + ','
|
||||||
|
// + 'lon:' + radToDeg(wgs.lon));
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(2 * Math.atan(Math.pow(Math.E, 0 / a)) - Math.PI / 2);
|
||||||
|
// console.log(radToDeg(webMercatorToWgs84(5565974.539663678, 0).lat));
|
||||||
|
|
||||||
|
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))));
|
||||||
|
}
|
||||||
|
|
||||||
|
//test
|
||||||
|
//22.7490073, 114.3781213 z=15
|
||||||
|
//let mappiece = Math.pow(2, zoom_level); //一个方向的地图块数 1块256个像素
|
||||||
|
|
||||||
|
// console.log(lon2tile(long, zoom_level));
|
||||||
|
// console.log(lat2tile(lat, zoom_level));
|
||||||
|
// console.log(lon2x(long, zoom_level));
|
||||||
|
// console.log(lat2y(lat, zoom_level));
|
||||||
|
|
||||||
|
// console.log('----------------------');
|
||||||
|
// console.log(tile2long(26794, zoom_level));
|
||||||
|
// console.log(tile2long(26794 + 1 / 256, zoom_level));
|
||||||
|
|
||||||
|
//https://tile.openstreetmap.org/z/x/y.png
|
||||||
|
//https://tile.openstreetmap.org/15/26794/14256.png
|
||||||
|
|
||||||
|
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 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 width = 1600;
|
||||||
|
let height = 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);
|
||||||
|
|
||||||
|
//基于已知条件计算需要的各个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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(tiles);
|
||||||
|
console.log(tiles.length);
|
||||||
|
|
||||||
|
//渲染问题
|
||||||
|
//通过与基准之间的位置关系计算渲染的坐标
|
||||||
|
//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 });
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>tilerendertest</title>
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.main{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: white;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
.container{
|
||||||
|
flex:1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.map{
|
||||||
|
background-color: rgb(79, 38, 38);
|
||||||
|
width: 1600px;
|
||||||
|
height: 900px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main">
|
||||||
|
<div class="container">
|
||||||
|
<canvas class="map" id="map"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="./ellipsode.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue