高精度地圖是自動(dòng)駕駛中的基礎(chǔ)設(shè)施,地圖的數(shù)據(jù)是有眾多點(diǎn)信息組成。一般坐標(biāo)系統(tǒng)使用世界坐標(biāo),這樣很容易被3d軟件展示。
使用點(diǎn)數(shù)據(jù)繪制路面
下面是一組高精度地圖數(shù)據(jù)樣例:
{
"x": 457382.120775907,
"y": 4405077.27123374
},
{
"x": 457389.013402718,
"y": 4405066.14053764
}
在實(shí)際使用中,分為為研發(fā)和用戶兩種場(chǎng)景。研發(fā)更多追求對(duì)地圖數(shù)據(jù)更豐富的顯示,用戶產(chǎn)品追求的是良好的用戶體驗(yàn)和優(yōu)美的顯示效果。實(shí)際數(shù)據(jù)中,一般使用左右兩組數(shù)據(jù)來(lái)標(biāo)示一段路面。比如leftBoundary標(biāo)示左邊的標(biāo)線,rightBoundary標(biāo)志右邊的標(biāo)線。
如下圖:

for研發(fā)版本
我們使用threejs可以使用這樣的方式來(lái)繪制boundary數(shù)據(jù)。
let material = new THREE.LineBasicMaterial({
color,
linewidth,
transparent,
opacity
});
let geometry = new THREE.Geometry();
// 這里的point既是boundary數(shù)據(jù),只要吧他設(shè)置給geometry的vertices屬性即可。
geometry.vertices = point;
let lineSegment = new THREE.LineSegments(geometry, material);
for用戶體中版本
我們需要把點(diǎn)繪制成線在鏈接成面,在我們的認(rèn)知中行程面是一個(gè)這樣的過(guò)程。
點(diǎn)(1)-> 線(2點(diǎn))-> 面(三線|三點(diǎn))
上面我們說(shuō)過(guò)一組boundary數(shù)據(jù)是有四個(gè)點(diǎn)組成的,那么我們可以這樣做來(lái)繪制一個(gè)路面。

問(wèn)題
初始數(shù)據(jù)如左圖,如果簡(jiǎn)單鏈接肯定是形成不了一個(gè)面的。
數(shù)據(jù)加工
1. 先把leftBoundray數(shù)據(jù)push到一個(gè)數(shù)組。
2. 把rightBoundray數(shù)據(jù)翻轉(zhuǎn)push
3. 這是如果繪制會(huì)發(fā)現(xiàn)只能形成一個(gè)凹型線框并不能形成完整面。
4. 我們?nèi)サ谝粋€(gè)點(diǎn)push進(jìn)去這樣繪制就可以形成一個(gè)面了。
5. 用路徑繪制一個(gè)二維平面可以使用
示例代碼如下:
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);
});
那么通過(guò)以上5步操作我們可以得到一個(gè)完整的路面,實(shí)際效果如下。

我的blog: neverland.github.io
我的email enix@foxmail.com