蜂鸟视图 JavaScript SDK v3.2.0 参考文档
基于官方文档 + 51 个在线实例可运行代码 + 项目源码综合整理
重要说明:官方文档存在部分错误/过时内容,本文以可运行的在线实例代码为主要依据,文档内容仅作参考。
目录
1. SDK 模块结构
模块清单
| 模块 | 文件名 | 依赖 | 功能 |
|---|---|---|---|
| 核心 | fengmap.map.min.js | 无 | 地图渲染、FMMap、覆盖物、事件、坐标转换 |
| UI 控件 | fengmap.plugin.ui.min.js | 核心 | 楼层切换、指北针、比例尺、缩放控件 |
| 分析器 | fengmap.analyser.min.js | 核心 | FMSearchAnalyser、FMNaviWalkAnalyser、FMNaviDriveAnalyser |
| 导航 | fengmap.plugin.navi.min.js | 核心+分析器 | FMNavigationWalk、FMNavigationDrive |
| 特效 | fengmap.effect.min.js | 核心 | 粒子、天空盒、水波纹、发光 |
| 特殊标注 | fengmap.plugin.markers.min.js | 核心 | 3D线、球、管道、复合标注 |
| 绘图 | fengmap.plugin.draw.min.js | 核心+分析器 | 框选、图形绘制 |
| 位置服务 | fengmap.plugin.location.min.js | 核心 | 轨迹回放 |
| 导出 | fengmap.plugin.export.min.js | 核心 | 截图、图片导出 |
| 附加图层 | fengmap.plugin.layers.min.js | 核心 | 高德/百度底图、3DTiles |
| 性能监控 | fengmap.plugin.debug.min.js | 核心 | 性能统计 |
| 数据融合 | fengmap.plugin.fusion.min.js | 核心 | 蜂鸟云融合 |
| 模型加载器 | fengmap.plugin.loader.min.js | 核心 | FBX 动态模型 |
| 第一人称 | fengmap.plugin.first.min.js | 核心 | 第一人称视角、小地图 |
引入方式
ES Module(推荐,在线实例采用)
javascript
import { FMMap, FMType, FMImageMarker, FMMarkerAnchor } from '/demos/libs/js/fengmap.map.min.js';
import { FMControlPosition, FMCompass, FMZoomBar, FMToolbar, FMScaleBar } from '/demos/libs/js/fengmap.plugin.ui.min.js';
import { FMSearchRequest, FMSearchAnalyser } from '/demos/libs/js/fengmap.analyser.min.js';
import { FMNavigationWalk } from '/demos/libs/js/fengmap.plugin.navi.min.js';Script 标签(传统方式)
html
<!-- 必须按顺序引入 -->
<script src="libs/fengmap.map.min.js"></script>
<script src="libs/fengmap.analyser.min.js"></script>
<script src="libs/fengmap.plugin.ui.min.js"></script>
<script src="libs/fengmap.plugin.navi.min.js"></script>
<!-- 其他模块按需引入 -->2. 快速开始
最简初始化(来自在线实例)
javascript
import { FMMap } from '/demos/libs/js/fengmap.map.min.js';
let map;
let options = {
container: document.getElementById('fengmap'),
appName: '蜂鸟研发SDK_2_0',
key: '57c7f309aca507497d028a9c00207cf8',
mapID: '1513361948621471746',
themeID: '1581910231660457986',
level: 2,
mapZoom: 19.5,
};
map = new FMMap(options);
map.on('loaded', function () {
console.log('地图加载完成');
});带 UI 控件的完整初始化
javascript
import { FMMap } from '/demos/libs/js/fengmap.map.min.js';
import { FMControlPosition, FMCompass, FMZoomBar, FMToolbar, FMScaleBar } from '/demos/libs/js/fengmap.plugin.ui.min.js';
let map = new FMMap(options);
map.on('loaded', function () {
// 指北针
let compass = new FMCompass({
position: FMControlPosition.RIGHT_TOP,
offset: { x: -20, y: 80 }
});
compass.addTo(map);
compass.on('click', () => map.setRotation({ rotation: 0, animate: true, duration: 0.3 }));
// 缩放控件
let zoomBar = new FMZoomBar({
position: FMControlPosition.RIGHT_TOP,
offset: { x: -20, y: 510 }
});
zoomBar.addTo(map);
// 楼层控件
let toolbar = new FMToolbar({
position: FMControlPosition.RIGHT_TOP,
floorButtonCount: 5,
offset: { x: -20, y: 80 },
viewModeControl: true,
floorModeControl: true,
needAllLayerBtn: true
});
toolbar.addTo(map);
// 比例尺
let scaleBar = new FMScaleBar({
position: FMControlPosition.RIGHT_BOTTOM
});
scaleBar.addTo(map);
});室内外一体化初始化
javascript
let options = {
container: document.getElementById('fengmap'),
appName: '蜂鸟研发SDK_2_0',
key: '57c7f309aca507497d028a9c00207cf8',
mapID: '1580485061997461505',
themeID: '1585095742545817602',
level: 1,
mapZoom: 19.5,
tile: true,
buildingOptions: {
overviewMode: FMOverviewMode.NORMAL,
buildings: [
{
buildingID: "1585093758069555202",
overviewMode: FMOverviewMode.INDOOR,
visibleLevels: [1, 2, 3],
minLevel: 19,
maxLevel: 29,
},
{
buildingID: "1585093758073749506",
overviewMode: FMOverviewMode.INDOOR,
visibleLevels: [1, 2, 3],
minLevel: 19,
maxLevel: 29,
},
]
},
};3. 核心类 FMMap
构造参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| container | HTMLElement | 是 | 地图容器(必须设置宽高) |
| appName | string | 是 | 应用名称 |
| key | string | 是 | 开发者 Key |
| mapID | string | 是 | 地图 ID |
| themeID | string | 否 | 主题 ID |
| level | number | 否 | 初始楼层 |
| mapZoom | number | 否 | 初始缩放级别 |
| viewMode | number | 否 | 视图模式(2D/3D) |
| tiltAngle | number | 否 | 倾斜角度 |
| rotation | number | 否 | 旋转角度 |
| tile | boolean | 否 | 是否显示瓦片底图 |
| preLoad | boolean | 否 | 是否预加载 |
| buildingOptions | object | 否 | 室内外一体化配置 |
核心方法
javascript
// 地图状态
map.getCenter() // 获取中心点 {x, y}
map.setCenter(center) // 设置中心点
map.getLevel() // 获取当前楼层
map.setLevel(level) // 设置楼层
map.getZoom() // 获取缩放级别
map.setZoom(zoom) // 设置缩放级别
map.getRotation() // 获取旋转角度
map.setRotation(opt) // 设置旋转角度(可动画)
map.getTilt() // 获取倾斜角度
map.setTilt(tilt) // 设置倾斜角度
map.getViewMode() // 获取视图模式
map.setViewMode(mode) // 设置视图模式
map.getBound() // 获取地图边界
map.getState() // 获取完整状态
map.setState(state) // 设置状态
// 楼层操作
map.getFloor(level) // 获取楼层对象
map.getFloorInfos() // 获取所有楼层信息
// 建筑操作(园区一体化)
map.getBuilding(buildingID) // 获取子建筑
map.getBuildings() // 获取所有子建筑
map.enterBuilding(buildingID) // 进入室内
map.exitBuilding() // 退出室内
// 视图控制
map.zoomIn() // 放大
map.zoomOut() // 缩小
map.setFitView() // 自适应视图
map.autoRotate() // 自动旋转
// 事件
map.on(event, handler) // 监听事件
map.off(event, handler) // 移除监听
// 生命周期
map.dispose() // 销毁地图(释放资源)视图模式常量
javascript
FMViewMode.MODE_2D // 4
FMViewMode.MODE_3D // 24. 搜索系统
搜索分析器初始化
javascript
import { FMSearchAnalyser, FMSearchRequest } from '/demos/libs/js/fengmap.analyser.min.js';
let analyser;
map.on('loaded', function () {
analyser = new FMSearchAnalyser({ map: map }, function () {
// 分析器初始化完成
doSearch();
});
});执行搜索
javascript
function doSearch(keyword) {
let searchRequest = new FMSearchRequest();
searchRequest.levels = [1, 2, 3, 4, 5]; // 搜索楼层范围
searchRequest.type = FMType.MODEL | FMType.LABEL; // 搜索类型
// 添加查询条件(支持多种)
searchRequest.addCondition({ 'name': { text: keyword, fuzzy: true } }); // 名称模糊搜索
searchRequest.addCondition({ 'ename': { text: keyword, fuzzy: true } }); // 英文名搜索
searchRequest.addCondition({ 'keyword': { text: keyword, fuzzy: true } }); // 关键词搜索
searchRequest.addCondition({ 'FID': ["820360010132"] }); // FID 精确搜索
searchRequest.addCondition({ 'typeID': [100000, 100100] }); // 类型 ID 搜索
analyser.query(searchRequest, (result) => {
// result: 搜索结果数组,每项包含 FID, name, ename, center, level, type, bound 等
console.log('搜索结果:', result);
result.forEach(item => {
console.log(item.name, item.FID, item.center, item.level);
});
});
}周边搜索
javascript
searchRequest.addCondition({
'circle': {
center: { x: 12619619.6, y: 2621894.3 },
radius: 10 // 半径(米)
}
});多边形查询
javascript
searchRequest.addCondition({
'polygon': [
{ x: 12619619.6, y: 2621894.3 },
{ x: 12619610.6, y: 2621893.3 },
{ x: 12619611.6, y: 2621884.3 },
{ x: 12619620.6, y: 2621885.3 },
{ x: 12619619.6, y: 2621894.3 }
]
});室内建筑搜索
javascript
searchRequest.onlyInBuilding = true;
searchRequest.buildings = [
{ buildingID: building1.buildingID, levels: building1.visibleLevels },
{ buildingID: building2.buildingID, levels: building2.visibleLevels }
];5. 路径规划与导航
导航初始化(来自在线实例)
javascript
import { FMNaviWalkAnalyser } from '/demos/libs/js/fengmap.analyser.min.js';
import { FMNavigationWalk } from '/demos/libs/js/fengmap.plugin.navi.min.js';
let navi, analyser;
let naviRequest = {
start: {
x: 13521019.18742602,
y: 4502217.816586388,
buildingID: "1585093758069555202", // 室内导航必须传 buildingID
level: 3,
size: 32,
height: 3,
url: '/images/start.png',
},
dest: {
x: 13521075.389498634,
y: 4502122.272547214,
level: 2,
buildingID: "1585093758073749506",
url: '/images/end.png',
size: 32,
height: 3,
},
};
map.on('loaded', function () {
analyser = new FMNaviWalkAnalyser({ map: map }, function () {
navi = new FMNavigationWalk({
map: map,
analyser: analyser,
locationMarkerUrl: '/images/bluedot-arrow.png',
locationMarkerSize: 48,
linePassed: true,
});
navi.setStartPoint(naviRequest.start);
navi.setDestPoint(naviRequest.dest);
navi.route(naviRequest, function (result) {
navi.drawNaviLine({ passed: true });
navi.simulate(simulateOptions);
}, function (error) {
console.log("导航错误:", error);
});
navi.on('walking', function (data) {
// data.index - 当前路段索引
// data.remain - 剩余距离(米)
updateUI(data);
});
navi.on('complete', function (data) {
console.log('导航完成');
});
});
});模拟导航参数
javascript
let simulateOptions = {
speed: 7, // 行进速度 m/s,默认 7
followPosition: true, // 位置变化时地图是否跟随居中
followAngle: false, // 方向变化时地图是否跟随
changeTiltAngle: true, // 楼层变化时是否改变倾斜角度
zoom: 21, // 导航时缩放级别
maxZoom: 22, // 最大缩放级别
};
navi.simulate(simulateOptions);导航结果结构
javascript
navi.naviResult = {
distance: 123.45, // 总距离(米)
levels: [1, 2, 3], // 经过的楼层
subs: [ // 分段数据
{
distance: 50.0,
levels: [1, 2],
instruction: { zh: "向前直行" }, // 文字指引
transfer: "TRANSFER_LIFT", // 换乘类型
buildingID: "1572530221952266242",
waypoint: {
direction: "DIRECTION_AHEAD",
points: [{ x: ..., y: ..., z: ... }]
},
}
],
buildings: { // 室内导航特有
distance: 80.0,
levels: [1, 2, 3],
buildingID: "..."
},
viapoints: [...], // 途经点
door: [...] // 门点信息
};导航控制方法
javascript
navi.setStartPoint(point) // 设置起点
navi.setDestPoint(point) // 设置终点
navi.route(option, success, error) // 路径规划
navi.drawNaviLine(opt) // 绘制导航线
navi.clearNaviLine() // 清除导航线
navi.overview(opt, callback) // 全览路径
navi.simulate(opt) // 开始模拟导航
navi.pause() // 暂停
navi.resume() // 恢复
navi.clearAll() // 清除所有
navi.dispose() // 销毁
navi.setSpeed(speed) // 设置速度
navi.setPassedLineDistance(dist) // 设置已过线距离
navi.real(opt) // 真实定位导航途经点导航
javascript
let naviRequest = {
start: { x: ..., y: ..., level: 1, buildingID: "..." },
dest: { x: ..., y: ..., level: 2, buildingID: "..." },
viapoints: [ // 途经点数组
{ x: ..., y: ..., level: 1, buildingID: "..." },
{ x: ..., y: ..., level: 2, buildingID: "..." }
],
mode: FMNaviMode.MODULE_SHORTEST, // 最短路径
priority: FMNaviPriority.PRIORITY_DEFAULT, // 优先级
};导航模式与优先级
javascript
// 导航模式
FMNaviMode.MODULE_SHORTEST // 最短路径
// 导航优先级
FMNaviPriority.PRIORITY_DEFAULT // 默认
FMNaviPriority.PRIORITY_ESCALATOR // 扶梯优先
FMNaviPriority.PRIORITY_ELEVATOR // 电梯优先6. 覆盖物系统
图片覆盖物 FMImageMarker
javascript
import { FMImageMarker, FMMarkerAnchor } from '/demos/libs/js/fengmap.map.min.js';
let marker = new FMImageMarker({
url: 'images/red.png',
x: 12619607.7,
y: 2621869.1,
anchor: FMMarkerAnchor.BOTTOM,
height: 1,
size: 32,
});
marker.addTo(floor); // 添加到楼层文字覆盖物 FMTextMarker
javascript
let textMarker = new FMTextMarker({
text: 'Hello FengMap',
x: map.getCenter().x,
y: map.getCenter().y,
fontsize: 15,
fillColor: "0, 205, 0",
strokeColor: "0, 0, 238",
plateColor: "255, 255, 51"
});
textMarker.addTo(floor);线覆盖物 FMLineMarker
javascript
import { FMSegment, FMLineMarker } from '/demos/libs/js/fengmap.map.min.js';
let segment = new FMSegment();
segment.points = [
{ x: 12619607.7, y: 2621869.1, z: 3 },
{ x: 12619610.6, y: 2621870.1, z: 3 },
{ x: 12619615.6, y: 2621875.1, z: 3 }
];
let lineMarker = new FMLineMarker({
lineSegments: [segment],
lineWidth: 2,
lineColor: "255, 0, 0"
});
lineMarker.addTo(floor);定位点覆盖物 FMLocationMarker
javascript
let locationMarker = new FMLocationMarker({
url: 'images/bluedot.png',
x: map.getCenter().x,
y: map.getCenter().y,
level: 1,
size: 32,
height: 0,
});
locationMarker.addTo(map);DOM 覆盖物 FMDomMarker
javascript
let domMarker = new FMDomMarker({
x: map.getCenter().x,
y: map.getCenter().y,
level: 1,
content: '<div style="background:white;padding:5px;">自定义内容</div>',
size: [100, 50],
});
domMarker.addTo(map);覆盖物通用方法
javascript
marker.addTo(floor) // 添加到楼层(或 map)
marker.remove() // 移除
marker.setVisible(bool) // 设置可见性
marker.setFocus() // 聚焦7. 事件系统
事件列表
| 事件 | 触发时机 | 回调参数 |
|---|---|---|
loaded | 地图数据加载完成 | event |
click | 点击地图要素 | event(含 targets 数组) |
hover | 鼠标划过地图 | event |
levelChanged | 聚焦楼层改变 | event |
move | 拖拽移动地图 | event |
update | 每帧渲染完成 | event |
viewChanged | 视口变换(旋转/缩放/拖拽/倾斜/切换楼层) | event |
visibleLevelsLoaded | 可见楼层加载完成 | event |
zoom | 地图缩放 | event |
buildingLoaded | 室内建筑数据加载完成 | event |
buildingEntered | 进入室内建筑 | event |
buildingExited | 移出室内建筑 | event |
viewModeChanged | 视图模式改变 | event |
info | 信息提示 | event |
progress | 加载进度 | event |
externalFirstLoaded | 外部模型首次加载完成 | event |
事件使用
javascript
map.on('loaded', function(event) {
console.log('地图加载完成');
});
map.on('click', function(event) {
// event.targets: 拾取的地图要素数组
// event.coords: 点击坐标 {x, y}
console.log('点击:', event.targets);
});
map.on('levelChanged', function(event) {
console.log('楼层改变:', event);
});导航事件
javascript
navi.on('walking', function(data) {
// data.index - 当前路段索引
// data.remain - 剩余距离(米)
console.log('剩余距离:', data.remain, '米');
console.log('当前指引:', navi.naviResult.subs[data.index].instruction.zh);
});
navi.on('complete', function(data) {
console.log('导航完成');
});8. UI 控件
控件位置常量
javascript
FMControlPosition.LEFT_TOP
FMControlPosition.LEFT_BOTTOM
FMControlPosition.RIGHT_TOP
FMControlPosition.RIGHT_BOTTOM控件创建
javascript
import { FMControlPosition, FMCompass, FMZoomBar, FMToolbar, FMScaleBar } from '/demos/libs/js/fengmap.plugin.ui.min.js';
// 指北针
let compass = new FMCompass({
position: FMControlPosition.RIGHT_TOP,
offset: { x: -20, y: 80 }
});
compass.addTo(map);
// 缩放控件
let zoomBar = new FMZoomBar({
position: FMControlPosition.RIGHT_TOP,
offset: { x: -20, y: 510 }
});
zoomBar.addTo(map);
// 楼层控件
let toolbar = new FMToolbar({
position: FMControlPosition.RIGHT_TOP,
floorButtonCount: 5,
offset: { x: -20, y: 80 },
viewModeControl: true,
floorModeControl: true,
needAllLayerBtn: true
});
toolbar.addTo(map);
// 比例尺
let scaleBar = new FMScaleBar({
position: FMControlPosition.RIGHT_BOTTOM
});
scaleBar.addTo(map);9. 坐标转换
经纬度 ↔ 地图坐标
javascript
import { FMCalculator } from '/demos/libs/js/fengmap.map.min.js';
// 经纬度 → 地图坐标(墨卡托米制坐标)
let mapCoord = FMCalculator.latlngToMapCoordinate({
x: 113.36397527358434,
y: 22.91600484817306
});
// 地图坐标 → 经纬度
let latlng = FMCalculator.mapCoordinateToLatlng({
x: map.getCenter().x,
y: map.getCenter().y
});屏幕坐标 ↔ 地图坐标
javascript
// 屏幕 → 地图
let mapCoord = map.coordScreenToMap(screenX, screenY);
// 地图 → 屏幕
let screenCoord = map.coordMapToScreen(mapX, mapY, z, level);几何计算
javascript
// 判断点是否在多边形内
let contain = FMCalculator.isContain(polygonPoints, { x: center.x, y: center.y });
// 计算多边形面积
let area = FMCalculator.area(polygonPoints);
// 计算两点间距离(米)
let distance = FMCalculator.distance(
{ x: 12619612.5, y: 2621854.2 },
{ x: 12619608.2, y: 2621867.9 }
);
// 矩形/圆形构造器
let rectPoints = FMCalculator.rectangleBuilder(width, height, center);
let circlePoints = FMCalculator.circleBuilder(radius, center, segments);10. 特效与高级功能
第一人称视角
javascript
import { FMMap } from '/demos/libs/js/fengmap.map.min.js';
// 需要 fengmap.plugin.first.min.js
// 第一人称视角切换
// 小地图室内外一体化
javascript
import { FMOverviewMode } from '/demos/libs/js/fengmap.map.min.js';
// 全览模式
FMOverviewMode.NORMAL // 正常
FMOverviewMode.INDOOR // 室内热力图
javascript
import { FMHeatMap } from '/demos/libs/js/fengmap.map.min.js';
let heatMap = new FMHeatMap({
data: [
{ x: 12619607.7, y: 2621869.1, value: 100 },
// ...
],
radius: 30,
});
heatMap.addTo(floor);11. 文档勘误
以下为官方文档与在线实例代码不一致的地方:
11.1 导航结果结构
| 文档描述 | 实际(来自实例代码) |
|---|---|
naviResult.levels 为经过楼层数组 | ✅ 正确 |
naviResult.subs[i].instruction.zh | ✅ 正确,中文指引 |
naviResult.buildings | ✅ 室内导航特有字段 |
11.2 搜索类型
文档中 FMType.MODEL | FMType.LABEL 的位运算用法与实例一致。
11.3 覆盖物添加
- 实例代码中
marker.addTo(floor)需要传入楼层对象 - 部分覆盖物可
addTo(map)直接添加到地图
11.4 模块引入
文档中部分示例使用全局 fengmap.FMMap,但在线实例使用 ES Module import { FMMap } from '...'。推荐使用 ES Module 方式。
附录:在线实例 Demo 完整列表
在线实例地址:https://developer.fengmap.com/fmAPI/
共 51 个可运行 demo,覆盖 12 个分类:
| 分类 | Demo 数量 | 覆盖内容 |
|---|---|---|
| 地图呈现 | 13 | 基础地图、本地化调用、初始化、地图切换、主题、坐标转换、导出图片、瓦片底图、3D瓦片、地面网格、区域掩膜、CAD图层 |
| 第一人称视角 | 2 | 相机切换、小地图 |
| 室内外一体化 | 6 | 模式切换、事件响应、搜索查询、模拟导航、聚焦显示、第一人称 |
| 界面控件 | 6 | 楼层控件、自定义楼层控件、信息窗、缩放控件、指北针控件、比例尺控件 |
| 地图控制 | 12 | 更换视频纹理、地板贴图、图标动画、图层控制、背景色、背景图片、地图交互、视图状态、模型闪烁、模型顶面、鼠标控制、渲染顺序 |
| 事件响应 | 9 | 精模加载、楼层切换、地图点击、鼠标悬停、地图加载、地图移动、视口变换、可见楼层加载、地图缩放 |
| 地图覆盖物 | 14 | 图片、文字、线、3D线、定位点、多边形、球、管道、围墙、复合、DOM、动态模型、热力图、拉伸几何体 |
| 搜索查询 | 5 | 地图选点、多条件查询、区域搜索、周边搜索、缓冲区搜索 |
| 路径规划 | 4 | 人行路径规划、人行多途径点、车行路径规划、车行多途径点 |
| 导航 | 4 | 人行模拟导航、人行真实导航、车行模拟导航、车行真实导航 |
| 应用实例 | 3 | 综合应用场景 |
| 特效 | 多种 | 粒子、天空盒、水波纹、发光等 |
文档生成时间:2025-08-21 基于:官方文档 + 51 个在线实例可运行代码 + 项目源码 在线实例代码路径:
/tmp/fengmap-demos/pages/*.code.js