From caacca7d4adf499c8398e892f4d38628e2ef54fe Mon Sep 17 00:00:00 2001 From: nxiaoxiao <3247747442@qq.com> Date: Sun, 11 Jun 2023 20:21:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9B=B8=E5=85=B3=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E7=9A=84=E6=96=B9=E6=B3=95=E5=92=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ellipsode.js | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 42 +++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 ellipsode.js create mode 100644 index.html diff --git a/ellipsode.js b/ellipsode.js new file mode 100644 index 0000000..6ff967a --- /dev/null +++ b/ellipsode.js @@ -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 }); +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..cbe914e --- /dev/null +++ b/index.html @@ -0,0 +1,42 @@ + + + + + + + tilerendertest + + + +
+
+ +
+
+ + + \ No newline at end of file