【发布时间】:2017-05-10 23:53:57
【问题描述】:
我有一个 mapbox 示例,我在其中执行以下操作:
1) 设置俯仰角为 60 度的视图
2) 映射画布角点以将视锥体设为梯形
3) 将方位角改变 30 度并再次获取并绘制梯形
4) 缩小以查看梯形
5) 手动将第一个梯形旋转 30 度
6) 绘制旋转后的梯形
7) 将间距更改为零以俯视图像
当我这样做时,手动旋转的梯形(图像中的红色)与使用 setBearing() 调用生成的梯形(图像中的紫色)不匹配.它似乎不正确地倾斜,我一直在查看手动旋转代码 8 小时,但无法弄清楚原因。我是在处理地球曲率旋转坐标问题还是?有人可以解决这个问题吗?谢谢!
mapboxgl.accessToken = 'pk.eyJ1IjoiZm1hY2RlZSIsImEiOiJjajJlNWMxenowNXU2MzNudmkzMndwaGI3In0.ALOYWlvpYXnlcH6sCR9MJg';
var map;
function addLayerToMap(name, points, color, width) {
map.addLayer({
"id": name,
"type": "line",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": points
}
}
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": color,
"line-width": width
}
});
}
function pointsRotate(points, cx, cy, angle){
var radians = (Math.PI / 180) * angle;
var cos = Math.cos(radians);
var sin = Math.sin(radians);
var newpoints = [];
function rotate(x, y) {
nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
ny = (cos * (y - cy)) + (-sin * (x - cx)) + cy;
return [nx, ny];
}
for(var i=0;i<points.length;i++) {
newpoints[i] = rotate(points[i][0],points[i][1]);
}
return(newpoints);
}
function convertTrapezoidToPath(trap) {
return([
[trap.Tl.lng, trap.Tl.lat], [trap.Tr.lng, trap.Tr.lat],
[trap.Br.lng, trap.Br.lat], [trap.Bl.lng, trap.Bl.lat],
[trap.Tl.lng, trap.Tl.lat] ]);
}
function getViewTrapezoid() {
var canvas = map.getCanvas();
var trap = {};
trap.Tl = map.unproject([0,0]);
trap.Tr = map.unproject([canvas.offsetWidth,0]);
trap.Br = map.unproject([canvas.offsetWidth,canvas.offsetHeight]);
trap.Bl = map.unproject([0,canvas.offsetHeight]);
return(trap);
}
map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-122.48610019683838, 37.82880236636284],
zoom: 17,
pitch: 60
});
map.on('load', function () {
// get the center and trapezoid of the zoomed in view
var center = map.getCenter();
var trapezoid = getViewTrapezoid();
// convert the view trapezoid to a path and add it to the view
var trapezoid_path = convertTrapezoidToPath(trapezoid);
addLayerToMap("viewTrapezoid",trapezoid_path,'#888',4);
// now rotate the bearing by 30 degrees to get a second view trapezoid
map.setBearing(30);
setTimeout(function() {
var trapezoid2 = getViewTrapezoid();
var trapezoid2_path = convertTrapezoidToPath(trapezoid2);
addLayerToMap("viewTrapezoid2",trapezoid2_path,'#f0f',2);
// return to a "top down" view and zoom out to show the trapezoids
map.setBearing(0);
map.setZoom(13.5);
setTimeout(function() {
map.flyTo({ pitch: 0 });
// rotate the original view trapezoid by 30 degrees and add it to the map
var newpath = pointsRotate(trapezoid_path,center.lng,center.lat,30);
addLayerToMap("rotatedTrapezoid",newpath,'#f00',2);
}, 500);
}, 500);
});
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.css' rel='stylesheet' />
<div id='map'></div>
【问题讨论】:
-
嗯 - 看起来这是两极附近经度距离变小的问题。根据这篇文章,我的计算只能在赤道附近工作:gis.stackexchange.com/questions/206698/…> 我会尝试他们的代码建议并更新...
-
好的,所以我找到了一种算法,可以根据它所在的纬度计算经度的长度。我会试一试...gis.stackexchange.com/questions/75528/…
标签: javascript rotation mapbox