高德地图meshLine使用两个点画3D曲线
效果图:
高德官方示例的meshLine用了4个点画线,贝塞尔曲线2个点就能画,另外2个点应该是用来确定曲线垂直方向的弯曲,实现图上的需求只需要2个点,当然还需要一个弯曲度的参数,也就是曲线顶点到两点直线之间的距离。本人数学不好,只能拿官方的例子来改,源码见:MeshLine-线 Line-示例中心-地图 JS API | 高德地图API
var map = new AMap.Map("container", {
mapStyle: 'amap://styles/darkblue', //设置地图的显示样式
resizeEnable: true,
center: [114, 30],
zoom: 5.5,
viewMode: '3D',
pitch: 40 //3D地图倾斜度
});
const object3Dlayer = new AMap.Object3DLayer();
const center = {lng:114.301803,lat:30.599835}; //起点
const points = [ //终点集合,这些点最终和起点连线
{lng:104.075809, lat:30.651239},
{lng:113.543028, lat:22.186835},
{lng:106.551643, lat:29.562849},
{lng:102.710002, lat:25.045806},
{lng:116.407394, lat:39.904211},
{lng:112.562678, lat:37.873499},
{lng:112.983602, lat:28.112743},
{lng:108.954347, lat:34.265502},
{lng:121.473662, lat:31.230372},
{lng:120.152585, lat:30.266597},
{lng:119.295143, lat:26.100779},
{lng:106.705463, lat:26.600055},
{lng:109.194828, lat:27.755017},
{lng:116.369774, lat:28.000249},
{lng:106.766385, lat:31.892508}
];
for (let i = 0; i < points.length; i++) {
const point = points[i];
const meshLine = new AMap.Object3D.MeshLine({
path: computeBezier(center,point, 180), //计算曲线
height: getEllipseHeight(180, 4500000, 20), //计算高度 maxHeight可自定义
color: 'rgba(55,129,240, 1)', //线条颜色
width: 1 //线条宽度
});
meshLine.transparent = true;
object3Dlayer.add(meshLine);
meshLine['backOrFront'] = 'both';
}
map.add(object3Dlayer);
function computeBezier(center,point, numberOfPoints) {
let dt;
let i;
const curve = [];
dt = 1.0 / (numberOfPoints - 1);
for (i = 0; i < numberOfPoints; i++) {
curve[i] = pointOnCubicBezier(center,point, i * dt);//计算曲线
}
return curve;
}
function getEllipseHeight(count, maxHeight, minHeight) {
const height = [];
const radionUnit = Math.PI / count;
for (let i = 0; i < count; i++) {
const radion = i * radionUnit;
height.push(minHeight + Math.sin(radion) * maxHeight);
}
return height;
}
function pointOnCubicBezier(center,point, t) {
let cx;
let cy;
cx = (point.lng - center.lng);
cy = (point.lat - center.lat);
const lng = (cx * t) + center.lng;
const lat = (cy * t) + center.lat;
return new AMap.LngLat(lng, lat);
}