前言: 本文基于上篇文章的基础开始。如果没看过我的上篇文章,请移步。
效果
转换成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 ]
}
|