create
本文回答:创建 Marker —— new vjmap.Marker / setLngLat / addTo / remove / show / hide。
一、最小用法
const marker = new vjmap.Marker()
.setLngLat([113.0, 23.0]);
marker.addTo(map);
⚠️
Marker.addTo()返回undefined(d.ts 声明this,运行时无返回值——源码marker.ts重写时未 return)。不要写const m = new Marker().setLngLat(x).addTo(map)——m会是undefined,后续m.remove()报 TypeError。setLngLat/setPopup等链返回this正常,仅addTo断链。
setLngLat 接受:
[lng, lat]数组LngLat实例:new vjmap.LngLat(lng, lat){ lng, lat }对象
二、从 CAD 坐标创建
CAD 坐标必须先转经纬度:
const cadPt = [725.32, 18969.19];
const lngLat = map.toLngLat(cadPt);
new vjmap.Marker().setLngLat(lngLat).addTo(map);
三、两种构造形式
// 形式 1:只传 options
new vjmap.Marker({ color: "#f00", draggable: true });
// 形式 2:传 DOM + options
const el = document.createElement("div");
el.className = "my-marker";
new vjmap.Marker(el, { anchor: "bottom" });
// 形式 3(推荐):options.element
new vjmap.Marker({ element: el, anchor: "bottom" });
四、常用方法
| 方法 | 功能 |
|---|---|
addTo(map) |
附加到地图 |
remove() |
从地图移除 |
setLngLat(ll) |
设置 / 移动位置(会触发重绘) |
getLngLat() |
当前位置 |
getElement() |
获取底层 DOM(可 addEventListener / 改样式) |
setPopup(popup) |
绑定 Popup |
togglePopup() |
切换 Popup |
setOffset([x, y]) |
运行时改偏移 |
setRotation(deg) |
旋转 |
show() / hide() |
显隐(不从 map 里移除) |
isHidden() |
是否隐藏 |
setColor(c) |
改默认水滴颜色 |
setDraggable(b) |
启用拖拽 |
setAnimation(t) |
弹跳 / 坠落动画(见 animation) |
五、批量创建
const markers = [];
for (let i = 0; i < 100; i++) {
const m = new vjmap.Marker({ color: "#0af" })
.setLngLat(map.toLngLat(bounds.randomPoint()));
m.addTo(map); // addTo 返回 undefined,勿把链尾赋给 m
markers.push(m);
}
// 批量移除
markers.forEach(m => m.remove());
markers.length = 0;
> 500 个 Marker 建议改用 Symbol 图层,见 performance-tips。
六、更新位置(动画式)
function moveTo(marker, target, duration = 1000) {
const start = marker.getLngLat();
const startT = performance.now();
function step() {
const t = Math.min(1, (performance.now() - startT) / duration);
marker.setLngLat([
start.lng + (target.lng - start.lng) * t,
start.lat + (target.lat - start.lat) * t
]);
if (t < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
七、show / hide vs remove
| API | 行为 |
|---|---|
hide() |
DOM 仍在文档,display: none |
setVisible(v, true) |
isDisplay=true 分支=CSS display 显隐切换(等价 show()/hide()) |
setVisible(false, false) |
isDisplay 假分支调 this.remove(),等价 remove():真正移除 |
remove() |
DOM 摘除、事件解绑、_map 删除(并置 isRemoved=true) |
⚠️ remove() 不是不可逆:marker.addTo(map) 会重置 isRemoved、重建全部监听并重新挂上。
⚠️ setVisible(false,false) 之后不能用 setVisible(true,false) 恢复——它调 addTo(this._map),而 _map 已被删(addTo(undefined) 报错)。恢复要用 marker.addTo(map)。
⚠️ 更深坑:一旦误调 setVisible(true,false) 并捕获了异常,之后再 addTo(map) 会静默无效——addTo 包装在调原生方法之前就把 isShow 置 true,异常中断后 isShow 停在 true,下次 addTo 被 if (this.isShow) return 拦截。补救:marker.isShow = false 再 addTo(map)。
"DOM 摘除但保留地图登记"是内部
remove(true)/addTo(map, true)布尔参路径(removeWhenNoInMapView自动裁剪专用),公开 API 不暴露该开关。
八、常见坑
- CAD 坐标直接 setLngLat → marker 出现在赤道非洲;必须
map.toLngLat。 - 没有 addTo → 新建的 Marker 不显示。
- 元素没有尺寸 → 自定义 DOM 没 width/height 时,看起来像没创建。
- 重复创建未 remove → 同一个逻辑点反复
new Marker().addTo(map)会重影。保留引用,需要时移除。 addTo链尾赋值 →const m = new Marker().setLngLat(x).addTo(map)得到的m是undefined(addTo 无返回值,d.ts 声明this与运行时不符);先setLngLat赋值再单独addTo。Popup.addTo未被重写、正常返回this,不受影响。