openlayers结合原生webgl 图像的动态绘制tin数据保持清晰度(南极坐标系、北极坐标系的转换处理)

前言: 本文基于上篇文章的基础开始。如果没看过我的上篇文章,请移步。

效果

在这里插入图片描述
在这里插入图片描述

转换成webgl坐标系所需的地理知识

南极坐标系如下图所示
在这里插入图片描述
北极坐标系的 如理 相反
在这里插入图片描述
北极坐标系如理相反

也就是说 假如我们得到一个坐标系正确的结果,另一个就是调调正负号了。
下面以南极坐标系为说明。

经纬度坐标转换成南极坐标的显示坐标(将度数改为数字)

计算原理如下图所示
在这里插入图片描述

特别注意,以下代码只保证南极坐标系第四象限求得角度没问题,由于暂时我也只用到了第四象限得处理,所以没有对其他的去算角度。请跟着上图原理自行计算。或者根据绘制出来的图像 处理。
如果lat 是 南纬 在 -90 至0 之间,斜边的计算也是没问题的。

/**
         * 判断角度 以及象限
         * @param {Number} lat 纬度
         * @return {Info} info=>{ axis , angel}
         */
    judgeAxisAndAngel(angel) {
        // 南极下 如果是 第一象限  右半球为 东经  左半球为西经 上方顶点为0  下方顶点180
        let res = {
            angel: null,
            axis: null,
        }
        const radian = Math.PI * 0.5
        // 如果是东经
        if (angel > 0) {
            if (angel <= 90) {
                res.angel = Math.PI - Math.PI * angel / 180 - Math.PI * 0.5
                res.axis = 1
            } else {
                res.angel = Math.PI * angel / 180 - Math.PI * 0.5
                res.axis = 4
            }
        } else {
            if (angel <= -90) {
                res.angel = Math.PI - Math.PI * Math.abs(angel) / 180 - Math.PI * 0.5
                res.axis = 2
            } else {
                res.angel = Math.PI * Math.abs(angel) / 180 - Math.PI * 0.5
                res.axis = 3
            }
        }
        return res
    }
/**
     * 经纬度坐标转换成webgl坐标
     * @param {Array} coords 经纬度
     * @return {Array} pixels webgl 坐标
     */
    transfromToScreenCoords(coords) {
        // 获取 直角三角形的夹角
        let [lon, lat] = coords
        let info = this.judgeAxisAndAngel(lon)
        // 此标志位 为true 时, 说明 在第一第四象限 否则为其他
        let x = Math.cos(info.angel) * ((90 + lat)) 
        let y = Math.sin(info.angel) * ((90 + lat))
        // 根据象限  现在 xy 都只是 值 , 需要正确的 填充到对应的象限上
        //  第一象限 值 都是正的  无需调整.
        if (info.axis === 2) {
            x = -x
        } else if (info.axis === 3) {
            y = -y
            x = -x
        } else if(info.axis === 4) {
            y = -y
        }

        return [ x / 180.0,  y / 180.0 ]
    }

在这里插入图片描述

缩放与平移

经过处理顶点位置数据后,应该可以得到正确的一个初始图像。
在这里插入图片描述
但是此时 我们可以注意到, 他仍然是需要一个初始的固定的偏移比例 ,即从 外面的extent中 图像 的位置对应到当前球体内部中。
图已经截全,可以看到其实y轴方向 上 初始图 也是还没全的 ,所以 x ,y 方向上 都需要乘以比例。

static offsetScaleX = (20037508.342789244/32541383.177791517)
static offsetScaleY = (20037508.342789244/18961274.98453396)
20037508.342789244是epsg.io 上查询的包括球体的4至值。后面那个为刚开始加载此页面时,openlayers计算出来的四至的 宽的一个描述 以及高的一个描述。
后续所有的缩放以及平移 都在初始的内容上进行。

/**
     * 模型变化
     * @param {*} frameState 
     */
    changeMatrix(frameState) {
        let { gl, program } = this
        var calcMatrix = new Matrix4()
        let ratio = (this.__origin__resolution / frameState.viewState.resolution).toFixed(2)
        let center = this.transfromToScreenCoords(transform(frameState.viewState.center,frameState.viewState.projection,'EPSG:4326')) 
        // 缩放固定比例
        calcMatrix.scale(ratio * WebGLRenderer.offsetScaleX,ratio * WebGLRenderer.offsetScaleY, 1)
        calcMatrix.translate(-center[0], -center[1], 0)
        var u_modelMatrix = gl.getUniformLocation(program, 'u_modelMatrix')
        gl.uniformMatrix4fv(u_modelMatrix, false, calcMatrix.elements)
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
        gl.drawElements(gl.TRIANGLES, this.count, gl.UNSIGNED_INT, 0)
    }

北极 相关参考

/**
     * 经纬度坐标转换成webgl坐标
     * @param {Array} coords 经纬度
     * @return {Array} pixels webgl 坐标
     */
    transfromToScreenCoords(coords) {
        // 获取 直角三角形的夹角
        let [lon, lat] = coords
        let info = this.judgeAxisAndAngel(lon)
        // 此标志位 为true 时, 说明 在第一第四象限 否则为其他
        let x = Math.cos(info.angel) * ((90 - lat)) 
        let y = Math.sin(info.angel) * ((90 - lat))
        // 根据象限  现在 xy 都只是 值 , 需要正确的 填充到对应的象限上
        //  第一象限 值 都是正的  无需调整.
        if (info.axis === 2) {
            x = -x
        } else if (info.axis === 3) {
            y = -y
            x = -x
        } else if(info.axis === 4) {
            y = y
        }

        return [ x / 180.0,  y / 180.0 ]
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值