拉伸实体
FillExtrusionsEntity 是由 实体Entity 和 FillExtrusionsModule 模块组合而成的新的实体。
FillExtrusionsEntity = Entity + FillExtrusionsModule
常用方法
FillExtrusionsEntity 是由 实体Entity 派生而来。具体 Entity 的所有属性和方法。同时也具有FillExtrusionsModule 的相关方法。
| 方法 | 描述 |
|---|---|
| getFillExtrusions | 获取拉伸对象 |
| getBorderPolyline | 获取拉伸边框对象 |
| setDepths | 设置每项的拉伸后的深度、颜色、透明度值:setDepths([{index, depth?, color2?, opacity?}])。⚠️ 实际只有 depth 生效,且是顶面的绝对坐标值(不是相对 baseHeight 的高度);color2/opacity 被写到 attribute 对象而非 .array 上,无效果;带 baseHeight 的项底面顶点也被当成顶面一起改,调用后会压扁。要改颜色/透明度用 setData |
| getVertexSymbol | 获取顶点对象 |
| isShowVertex | 是否显示顶点 |
| getVertexData | 获取顶点数据 |
| setShowVertex | 设置是否显示顶点 |
| getBorderPolyline | 获取拉伸边框对象 |
| updateStyle | 设置样式 —— updateStyle(style: MeshBasicMaterialParameters),必须传样式参数(不是无参"刷新"方法) |
| updateHightStyle | 设置高亮样式 —— updateHightStyle(style: MeshBasicMaterialParameters),同上必传参(注意官方拼写是 Hight) |
| setData | 修改数据 |
| getData | 获取数据 |
| getItemDataByFaceIndex | 通过faceIndex获取数据 |
| refreshHighlight | 刷新高亮数据 |
| setItemHighlight | 设置某项高亮与否。⚠️ setItemHighlight(id, false) 不重绘,需随后调 refreshHighlight() |
| isItemHighlight | 获取某项高亮与否 |
| clearHighlight | 清除所有高亮 |
使用示例
创建FillExtrusionsEntity
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
}
})
let data = [];
data.push({
coordinates: [[7, 3],[-4, -2],[-5, 3]],
color: "#f00",
extrude: {
depth: Math.random() + 1,
steps: 1,
bevelEnabled: false
}
})
let fillExtrusions = new vjmap3d.FillExtrusionsEntity({ //FillExtrusionsEntity
data: data
})
fillExtrusions.addTo(app)
TS 用户注意:
coordinates声明为[number,number][](或带洞的[number,number][][])——普通number[][]字面量推断不过,须as const、显式[number,number][]标注或toArray()返回值。.on("mouseover", e => ...)的事件参数 d.ts 未标类型,strict下写e =>报 implicit-any,用(e: any) =>或自行收窄;e.intersection.faceIndex运行时存在。updateStyle()/updateHightStyle()必传MeshBasicMaterialParameters;要"刷新数据"用setData(getData()),要刷高亮用refreshHighlight()(无参)。updateHightStyle({color:'#00ff00'})会抛Cannot create property 'needsUpdate' on string:实现是逐键material[k]=v然后v.needsUpdate=true——值必须传 THREE 对象(color: new THREE.Color('#00ff00')可用);它作用在高亮拉伸体(highlightFillExtrusions)的材质上,不是边框线;且参数被记进style而非highlightStyle。updateStyle(作用于fillExtrusions材质)同型实现同坑。baseHeight是数值(基准高度,世界单位),但 d.ts 里误标为boolean——按数值传参是对的,strict 下需自行断言。
创建一个复杂的拉伸对象
data.push({
// 当为多个多边形时,第一个多边形后面的多边形将掏空挖洞处理
coordinates: [[[7, -8],[-1, -1],[-8, -9],[17, -18]], [ [-2, -9],[2, -10],[2, -7],[-1, -6]]],
color: "#FFFE91", // 底部颜色
color2: "#0ff", // 顶部颜色
showBorder: true, // 显示边框线
borderColor: "#39107B",// 边框线底部颜色
borderColor2: "#EA3FF7",// 边框线顶部颜色
baseHeight: 1, // 基准高度
extrude: { // 拉伸属性
depth: Math.random() * 3 + 1,
steps: 1,
bevelEnabled: false
}
})
增加事件
fillExtrusions.pointerEvents = true; // 允许事件交互
fillExtrusions.on("mouseover", e => {
if (e?.intersection?.faceIndex !== undefined) {
let itemData = fillExtrusions.getItemDataByFaceIndex(e?.intersection?.faceIndex);
if (itemData && itemData.id) fillExtrusions.setItemHighlight(itemData.id, true)
}
})
fillExtrusions.on("mouseout", e => {
fillExtrusions.clearHighlight()
})
修改、新增、删除
调用 setData 来对数据进行增删改
// 如新增一条
data.push({
coordinates: [[7, 3],[-4, -2],[-5, 3]],
color: "#f00",
extrude: {
depth: Math.random() * 1 + 1,
steps: 1,
bevelEnabled: false
}
})
fillExtrusions.setData(data)
全部显示或隐藏边框线
// 获取模块对象
let mod = fillExtrusions.getModule(vjmap3d.FillExtrusionsModule);
mod.showBorder = true; // 设置属性
mod.setData(mod.getData()); // 刷新下
3D示例
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
stat: {
show: true,
left: "0"
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
}
})
let data = [];
data.push({
coordinates: [[7, 3],[-4, -2],[-5, 3]],
color: "#f00",
extrude: {
depth: Math.random() + 1,
steps: 1,
bevelEnabled: false
}
})
data.push({
coordinates: [[[7, -8],[-1, -1],[-8, -9],[17, -18]], [ [-2, -9],[2, -10],[2, -7],[-1, -6]]],
color: "#FFFE91", // 底部颜色
color2: "#0ff", // 顶部颜色
showBorder: true, // 显示边框线
borderColor: "#39107B",// 边框线底部颜色
borderColor2: "#EA3FF7",// 边框线顶部颜色
baseHeight: 1, // 基准高度
extrude: {
depth: Math.random() * 3 + 1,
steps: 1,
bevelEnabled: false
}
})
//
let fillExtrusions = new vjmap3d.FillExtrusionsEntity({ //FillExtrusionsEntity
data: data,
// showBorder: true, 可以全局控制是否显示边框线
highlightStyle: {
color: "#777" // 高亮时颜色
}
})
fillExtrusions.addTo(app)
//
fillExtrusions.pointerEvents = true; // 允许事件交互
fillExtrusions.on("mouseover", e => {
if (e?.intersection?.faceIndex !== undefined) {
let itemData = fillExtrusions.getItemDataByFaceIndex(e?.intersection?.faceIndex);
if (itemData && itemData.id) fillExtrusions.setItemHighlight(itemData.id, true)
}
})
fillExtrusions.on("mouseout", e => {
fillExtrusions.clearHighlight()
})
//
const ui = await app.getConfigPane({ title: "设置", style: { width: "250px", overflow: "hidden"}});
let cfg = [
{
type: 'checkbox',
label: '显示顶点',
getValue: () => fillExtrusions.isShowVertex(),
setValue: v => {
fillExtrusions.setShowVertex(v)
}
},
{
type: 'checkbox',
label: '显示边框线',
value: false,
onChange: ({ value } )=> {
// 获取模块对象
let mod = fillExtrusions.getModule(vjmap3d.FillExtrusionsModule);
mod.showBorder = value; // 设置属性
mod.setData(mod.getData()); // 刷新下
}
},
{
type: 'button',
label: '增加一个拉伸',
value: ()=> {
data.push({
coordinates: [vjmap3d.randPoint2D(),vjmap3d.randPoint2D(),vjmap3d.randPoint2D()],
color: vjmap3d.randColor(),
extrude: {
depth: Math.random() * 1 + 1,
steps: 1,
bevelEnabled: false
}
})
fillExtrusions.setData(data)
}
},
{
type: 'button',
label: '修改第一个拉伸颜色',
value: ()=> {
if (data.length > 0) {
data[0].color = vjmap3d.randColor()
}
fillExtrusions.setData(data)
}
},
{
type: 'button',
label: '删除第一个拉伸',
value: ()=> {
if (data.length == 0) {
return
}
data.splice(0, 1)
fillExtrusions.setData(data)
}
}
]
cfg.forEach(c => ui.appendChild(c));
2D地图模式示例
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: env.exampleMapId, // 地图ID
// @ts-ignore
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapLightStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
showError(res.error)
return;
}
// 获取地图范围
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapBounds);
//
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapBounds.center()), // 设置地图中心点
zoom: 2, // 设置地图缩放级别
pitch: 45,
antialias: true, // 反锯齿
renderWorldCopies: false // 不显示多屏地图
});
//
// 关联服务对象和投影对象
map.attach(svc, prj);
await map.onLoad();
//
// 创建3d图层
let mapLayer = new vjmap3d.MapThreeLayer(map, {
stat: {
show: true,
left: "0"
}
});
map.addLayer(new vjmap.ThreeLayer({ context: mapLayer }))
let app = mapLayer.app;
let data = [];
// 外面边界的cad图上点坐标
let edge = [
[587653761.9404196, 3103856376.721289],
[587602251.0620328, 3103887684.472128],
[587616705.4171646, 3103910542.4372025],
[587668345.3998574, 3103879913.002372]
].map(p => vjmap3d.toWorld(p).toArray());
// 里面洞1的cad图上点坐标
let holes1 = [
[587611243.649386, 3103892845.733727],
[587618986.3449678, 3103888191.3405075],
[587624099.183289, 3103897555.098504],
[587616962.944966, 3103901844.930998]
].map(p => vjmap3d.toWorld(p).toArray());
// 里面洞2的cad图上点坐标
let holes2 = [
[587648133.0725995, 3103883387.5836215],
[587642667.2109047, 3103873956.0132804],
[587650162.938667, 3103869450.080676],
[587655761.2825799, 3103878763.0610456]
].map(p => vjmap3d.toWorld(p).toArray());
//
let bounds = map.getMapExtent();
let depth = vjmap3d.toDist(bounds.width() / 40);// 取地图范围的宽度的1/40距离做为拉伸高度
data.push({
coordinates: [edge, holes1, holes2],
color: "#FFFE91", // 底部颜色
color2: "#0ff", // 顶部颜色
showBorder: true, // 显示边框线
borderColor: "#39107B",// 边框线底部颜色
borderColor2: "#EA3FF7",// 边框线顶部颜色
baseHeight: depth / 5, // 基准高度
extrude: {
depth: depth,
steps: 1,
bevelEnabled: false
}
})
//
let fillExtrusions = new vjmap3d.FillExtrusionsEntity({ //FillExtrusionsEntity
data: data,
// showBorder: true, 可以全局控制是否显示边框线
highlightStyle: {
color: "#777" // 高亮时颜色
}
})
fillExtrusions.addTo(app)
//
fillExtrusions.pointerEvents = true; // 允许事件交互
fillExtrusions.on("mouseover", e => {
if (e?.intersection?.faceIndex !== undefined) {
let itemData = fillExtrusions.getItemDataByFaceIndex(e?.intersection?.faceIndex);
if (itemData && itemData.id) fillExtrusions.setItemHighlight(itemData.id, true)
}
})
fillExtrusions.on("mouseout", e => {
fillExtrusions.clearHighlight()
})
//
const ui = await app.getConfigPane({ title: "设置", style: { width: "250px", overflow: "hidden"}});
let cfg = [
{
type: 'checkbox',
label: '显示顶点',
getValue: () => fillExtrusions.isShowVertex(),
setValue: v => {
fillExtrusions.setShowVertex(v)
}
},
{
type: 'checkbox',
label: '显示边框线',
value: false,
onChange: ({ value } )=> {
let mod = fillExtrusions.getModule(vjmap3d.FillExtrusionsModule);
mod.showBorder = value;
mod.setData(mod.getData());
}
},
{
type: 'button',
label: '增加一个拉伸',
value: ()=> {
data.push({
coordinates: [mapBounds.randomPoint().toArray(),mapBounds.randomPoint().toArray(),mapBounds.randomPoint().toArray()].map(p => vjmap3d.toWorld(p).toArray()),
color: vjmap3d.randColor(),
extrude: {
depth: vjmap3d.toDist(bounds.width() * (Math.random() + 0.1) / 60),
steps: 1,
bevelEnabled: false
}
})
fillExtrusions.setData(data)
}
},
{
type: 'button',
label: '修改第一个拉伸颜色',
value: ()=> {
if (data.length > 0) {
data[0].color = vjmap3d.randColor()
}
fillExtrusions.setData(data)
}
},
{
type: 'button',
label: '删除第一个拉伸',
value: ()=> {
if (data.length == 0) {
return
}
data.splice(0, 1)
fillExtrusions.setData(data)
}
}
]
cfg.forEach(c => ui.appendChild(c));