高精度地圖是自動駕駛中的基礎設施,地圖的數據是有衆多點信息組成。一般座標系統使用世界座標,這樣很容易被3d軟件展示。
使用點數據繪製路面
下面是一組高精度地圖數據樣例:
{
"x": 457382.120775907,
"y": 4405077.27123374
},
{
"x": 457389.013402718,
"y": 4405066.14053764
}
在實際使用中,分爲爲研發
和用戶
兩種場景。研發更多追求對地圖數據更豐富的顯示,用戶產品追求的是良好的用戶體驗和優美的顯示效果。實際數據中,一般使用左右兩組數據來標示一段路面。比如leftBoundary標示左邊的標線,rightBoundary標誌右邊的標線。
如下圖:
for研發版本
我們使用threejs
可以使用這樣的方式來繪製boundary
數據。
let material = new THREE.LineBasicMaterial({
color,
linewidth,
transparent,
opacity
});
let geometry = new THREE.Geometry();
// 這裏的point既是boundary數據,只要吧他設置給geometry的vertices屬性即可。
geometry.vertices = point;
let lineSegment = new THREE.LineSegments(geometry, material);
for用戶體中版本
我們需要把點繪製成線在鏈接成面,在我們的認知中行程面是一個這樣的過程。
點(1)-> 線(2點)-> 面(三線|三點)
上面我們說過一組boundary數據是有四個點組成的,那麼我們可以這樣做來繪製一個路面。
問題
初始數據如左圖,如果簡單鏈接肯定是形成不了一個面的。
數據加工
1. 先把leftBoundray數據push到一個數組。
2. 把rightBoundray數據翻轉push
3. 這是如果繪製會發現只能形成一個凹
型線框並不能形成完整面。
4. 我們去第一個點push進去這樣繪製就可以形成一個面了。
5. 用路徑繪製一個二維平面可以使用
示例代碼如下:
function getShapeGeometryFromPoints(path) {
let shape = new THREE.Shape();
// 如果需要繪製弧度需要使用 shape.bezierCurveTo( 25, 25, 20, 0, 0, 0 );
shape.setFromPoints(point);
return new THREE.ShapeGeometry(shape);
}
road.forEach(edge => {
let path = [];
edge.forEach(({point, type}) => {
if ('RIGHT_BOUNDARY' === type) {
point = point.reverse();
point.push(path[0]);
}
path = [...path, point];
});
if (!path.length) {
return;
}
let geometry = getShapeGeometryFromPoints(path);
let material = new THREE.MeshLambertMaterial({
color: 0x444444
});
let mesh = new THREE.Mesh(geometry, material);
});
那麼通過以上5步操作我們可以得到一個完整的路面,實際效果如下。
- 我的blog: neverland.github.io
- 我的email [email protected]