Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ BicMap is built on top of the following open-source projects:
* [Vue 3](https://vuejs.org) + [Vite](https://vite.dev) — Example portal and build toolchain
* [urdf-loader](https://github.com/gkjohnson/urdf-loaders) — URDF robot model loading
* [Fabric.js](https://fabricjs.com) — Canvas-based drawing engine for the map editor in the example portal
* [PCL.js](https://github.com/PointCloudLibrary/pcl) — Point cloud processing via WebAssembly

## Contributors

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ BicMap 构建于以下开源项目之上:
* [Vue 3](https://vuejs.org) + [Vite](https://vite.dev) — 示例门户与构建工具链
* [urdf-loader](https://github.com/gkjohnson/urdf-loaders) — URDF 机器人模型加载
* [Fabric.js](https://fabricjs.com) — 示例门户中地图编辑器的 Canvas 绘图引擎
* [PCL.js](https://github.com/PointCloudLibrary/pcl) — 点云处理

## Contributors

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"maplibre-gl": "3.6.2",
"three": "0.149.0",
"urdf-loader": "^0.12.5",
"pcl.js": "^1.16.0",
"vue": "^3.5.13"
},
"devDependencies": {
Expand Down
11 changes: 11 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions src/bicMap/core/pointClouds/pointCloud3D.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const DEFAULT_OPTIONS = {
[1, '#ff5a5a']
],
zRange: [0, 5],
// 逐点颜色 Float32Array(长度 = 点数 × 3,分量 0~1)。传入后优先于 pointColor / colorMap,
// 供调用方自带 RGB / 强度等着色结果的场景使用
colors: null,
heightScale: 1,
heightOffset: 0,
sizeAttenuation: false,
Expand Down Expand Up @@ -56,6 +59,7 @@ function getColorFromZ(z, range, colorMap) {
* @param {Object} map - maplibre 地图实例
* @param {Array<[number,number,number?]>} points - 点云数据 [lng, lat, z?]
* @param {Object} [options]
* @param {Float32Array} [options.colors] - 逐点颜色(长度 = 点数 × 3,分量 0~1),优先级高于 pointColor / colorMap
* @returns {Object} 控制器:update / show / hide / remove / getPoints / getOptions
*/
export function createPointCloud3D(map, points = [], options = {}) {
Expand Down Expand Up @@ -112,13 +116,13 @@ export function createPointCloud3D(map, points = [], options = {}) {
const colors = new Float32Array(count * 3)
const baseColor = hexToRgb(opts.pointColor)
const invMPM = 1 / metersPerMercator
const srcColors = opts.colors && opts.colors.length >= count * 3 ? opts.colors : null

for (let i = 0; i < count; i++) {
const p = pointsData[i]
const z = p.length > 2 && p[2] !== undefined ? p[2] : 0
const altitude = z * opts.heightScale + opts.heightOffset
const mc = maplibregl.MercatorCoordinate.fromLngLat({ lng: p[0], lat: p[1] }, altitude)
const color = opts.useColorMap ? getColorFromZ(z, opts.zRange, opts.colorMap) : baseColor

const o = i * 3
// 东向米:mercator x 正方向即东,直接用
Expand All @@ -127,9 +131,17 @@ export function createPointCloud3D(map, points = [], options = {}) {
positions[o + 1] = -(mc.y - originMC.y) * invMPM
// 上向米:mercator z 正方向即高度,直接用
positions[o + 2] = (mc.z - originMC.z) * invMPM
colors[o] = color[0]
colors[o + 1] = color[1]
colors[o + 2] = color[2]

if (srcColors) {
colors[o] = srcColors[o]
colors[o + 1] = srcColors[o + 1]
colors[o + 2] = srcColors[o + 2]
} else {
const color = opts.useColorMap ? getColorFromZ(z, opts.zRange, opts.colorMap) : baseColor
colors[o] = color[0]
colors[o + 1] = color[1]
colors[o + 2] = color[2]
}
}

if (geometry) geometry.dispose()
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions src/examples/expand/PcdViewer/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* @Description: PCD 点云查看器常量配置(默认参数、配色、SLAM 底图与对齐参数)
* @FilePath: src/examples/expand/PcdViewer/constants.js
*/

// 点大小(three.js PointsMaterial.size,单位像素)
export const DEFAULT_POINT_SIZE = 1.3
export const MIN_POINT_SIZE = 0.3
export const MAX_POINT_SIZE = 6
export const POINT_SIZE_STEP = 0.1

// 着色模式
export const COLOR_MODE = {
HEIGHT: 'height', // 按高度渐变
RGB: 'rgb', // 使用点云自带 RGB
INTENSITY: 'intensity', // 使用点云自带反射强度
SINGLE: 'single' // 单一颜色
}

export const DEFAULT_COLOR_MODE = COLOR_MODE.RGB

export const COLOR_MODE_LABEL = {
[COLOR_MODE.HEIGHT]: '高度',
[COLOR_MODE.RGB]: 'RGB',
[COLOR_MODE.INTENSITY]: '强度',
[COLOR_MODE.SINGLE]: '单色'
}

// 高度渐变配色(t ∈ [0,1] → 颜色),近似 turbo 色带,低→高
export const HEIGHT_COLOR_STOPS = [
[0, '#3b4cc0'],
[0.25, '#22c1dc'],
[0.5, '#48d17a'],
[0.75, '#f4d03f'],
[1, '#e74c3c']
]

// 单一着色模式下的点颜色
export const SINGLE_COLOR = '#38e1ff'

// 无底图时用黑色托点云
export const BG_COLOR = '#051230cc'

// SLAM 底图与 campus_vbr.pcd 共用同一套栅格:一个像素一格,XY 原位贴合。
// resolution 0.2 对应源点云约 0.15~0.2m 的平面间距
export const SLAM_MAP = {
startX: -163,
startY: -136,
xGridCount: 1608,
yGridCount: 1358,
resolution: 0.2,
zoomFactor: 2
}

// SLAM 底图在笛卡尔坐标系下的跨度与中心(米)
export const SLAM_WIDTH = SLAM_MAP.xGridCount * SLAM_MAP.resolution
export const SLAM_HEIGHT = SLAM_MAP.yGridCount * SLAM_MAP.resolution
export const SLAM_CENTER = [SLAM_MAP.startX + SLAM_WIDTH / 2, SLAM_MAP.startY + SLAM_HEIGHT / 2]

// cartesianToGPS 会把 SLAM 米数再乘一次 resolution × zoomFactor 才落到真实经纬度,
// 高度方向必须用同一系数,否则点云会被竖直拉伸
export const SLAM_GEO_SCALE = SLAM_MAP.resolution * SLAM_MAP.zoomFactor

// 内置场景点云。pcd 放在本目录 samples/,由 index.vue 用 Vite ?url 引入,
// 这样 dev / build:web 都会打进产物,npm 库发布不会带上示例资源。
// 底图是点云的俯视投影,XY 原位贴合;但点云是 2.5D 高度场,最低点贴地后
// 主体(墙体/楼面,大约 7~8m)仍悬在平面底图上方,所以要再压一截离地高度。
export const SCENE_PRESETS = [
{ id: 'campus', label: '园区扫描' }
]

// 点云在 SLAM 坐标系中的摆放参数:x/y 为平移量(米)、rotation 为绕 Z 轴角度、z 为离地高度。
// 默认零变换给外部 PCD;内置场景的额外偏移写在 SCENE_PRESETS[].align
export const DEFAULT_ALIGN = {
x: 0,
y: 0,
z: 0,
rotation: 0,
scale: 1
}

// 平移滑块量程:以底图跨度为界,够把点云从一角推到另一角
export const OFFSET_X_RANGE = [-SLAM_WIDTH, SLAM_WIDTH]
export const OFFSET_Y_RANGE = [-SLAM_HEIGHT, SLAM_HEIGHT]

export const ALIGN_STEP = 0.5
export const ROTATION_STEP = 1
export const SCALE_RANGE = [0.1, 5]
export const SCALE_STEP = 0.1
export const HEIGHT_RANGE = [-10, 30]
export const HEIGHT_STEP = 0.5

// 初始视角,三项互不影响,改完刷新或点「重置视角」生效
export const MAP_VIEW = {
pitch: 60, // 俯仰角(度),0 正俯视,越大越斜
bearing: -15, // 旋转角(度),顺时针,0 为正北
zoom: 19 // 缩放;null 表示按底图自适应
}

// 体素降采样:叶子尺寸(米),0 表示关闭
export const DEFAULT_LEAF_SIZE = 0
export const MAX_LEAF_SIZE = 0.5
export const LEAF_SIZE_STEP = 0.01

// 统计离群点去除(StatisticalOutlierRemoval)参数
export const SOR_MEAN_K = 30
export const SOR_STDDEV_MUL = 1
Loading
Loading