# Gl多段线实体

 `GlLinesEntity` 是由 实体`Entity` 和 `GlLinesModule` 模块组合而成的新的实体。

 [GlLinesEntity](https://vjmap.com/map3d/api/classes/GlLinesEntity.html) =  [Entity](https://vjmap.com/map3d/api/classes/Entity.html) + [GlLinesModule](https://vjmap.com/map3d/api/classes/GlLinesModule.html) 

  `GlLinesEntity` 与 [PolylinesEntity](./polylinesEntity.md) 的区别是，他不能设置线宽，但性能更好。

 ## 常用方法


 `GlLinesEntity` 是由 实体`Entity` 派生而来。具体 [Entity](https://vjmap.com/map3d/api/classes/Entity.html) 的所有属性和方法。同时也具有[GlLinesModule](https://vjmap.com/map3d/api/classes/GlLinesModule.html)  的相关方法。


|方法|描述|
|:---|:---|
|[getGlLines](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#getGlLines)|获取线对象|
|[getVertexSymbol](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#getVertexSymbol)|获取顶点对象|
|[isShowVertex](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#isShowVertex)|是否显示顶点|
|[getVertexData](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#getVertexData)|获取顶点数据|
|[setShowVertex](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#setShowVertex)|设置是否显示顶点|
|[updateStyle](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#updateStyle)|**设置**样式，必传 `LineDashedMaterialParameters \| LineBasicMaterialParameters`。⚠️ 内部逐键执行 `material[k] = v; material[k].needsUpdate = true`：值为**原始类型**（`opacity: 0.5`、`transparent: true`、数字/字符串 `color`）时严格模式下抛 `TypeError`（该键已写入、后续键被跳过）；只传对象值（如 `color: new THREE.Color(...)`），或直接改 `getGlLines().material` 再设 `material.needsUpdate = true`|
|[updateHightStyle](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#updateHightStyle)|**设置**高亮样式，必传材质参数（官方拼写 `Hight`）。同样有原始值抛错问题；且它把参数记进了 `style`（覆盖普通样式记录）而非 `highlightStyle`|
|[setData](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#setData)|修改数据|
|[getData](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#getData)|获取数据|
|[getItemDataByIndex](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#getItemDataByIndex)|通过**线段序号**获取数据（射线命中的 `intersection.index` 是顶点序号，需 `Math.floor(index / 2)` 再传入）|
|[refreshHighlight](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#refreshHighlight)|刷新高亮数据|   
|[setItemHighlight](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#setItemHighlight)|设置某项高亮与否。⚠️ `setItemHighlight(id, false)` 只删记录、**不重绘**，需随后调 `refreshHighlight()`（或用 `clearHighlight()`）|  
|[isItemHighlight](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#isItemHighlight)|获取某项高亮与否|  
|[clearHighlight](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#clearHighlight)|清除所有高亮|  

    
## 使用示例


### 创建GlLinesEntity
```js
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, 0, 3],[-4, 0, -2],[-5, 0, 3]],
    color: "#00ff00"
})
data.push({
    coordinates: [[7, 0, -8],[-1, 2, -1],[-8, 1, -9],[7, 0, -8]],
    color: "#ffff00"
})
let polylines = new vjmap3d.GlLinesEntity({ //PolygonsEntity
    data: data,
    // dashed: true // 实体级选项（非数据项字段）；⚠️ 运行时未计算 lineDistances，开了仍是实线
})
polylines.addTo(app)
```

> **注意**：`GlLineItemData` 的数据项字段只有 `id`、`coordinates`、`color`（可数组，逐顶点渐变）、`showVertex`、`hidden`。GL 线宽恒为 1 像素，`lineWidth`/`dashSize`/`gapSize`/`dashScale`/`dashOffset`/`dashed` 写在数据项里**不会生效**。实体构造的 `dashed: true` 虽会换成 `LineDashedMaterial`，但源码中 `computeLineDistances()` 被注释掉、几何没有 `lineDistance` 属性，**仍渲染为实线**——`GlLinesEntity` 实际画不出虚线。要虚线或按条设置线宽请改用 [PolylinesEntity](./polylinesEntity.md)（其数据项 `dashed`/`dashSize`/`gapSize` 有效）。

### 增加事件
```
polylines.pointerEvents = true; // 允许事件交互
polylines.on("mouseover", e => {
    if (e?.intersection?.index !== undefined) {
        // LineSegments 命中的 index 是线段起点的顶点序号(0,2,4...)，除以 2 才是线段序号
        let itemData = polylines.getItemDataByIndex(Math.floor(e.intersection.index / 2));
        if (itemData && itemData.id) polylines.setItemHighlight(itemData.id, true)
    }
})
polylines.on("mouseout", e => {
    polylines.clearHighlight()
})
```

### 修改、新增、删除
调用 [setData](https://vjmap.com/map3d/api/classes/GlLinesEntity.html#setData) 来对数据进行增删改
```js
// 如新增一条
 data.push({
    coordinates: [[10, 0, 0], [20, 0, 0]],
    color: vjmap3d.randColor()
})
polylines.setData(data)
```

### 渐变色
如果`color`属性为数组时，并且颜色值不一样时，将绘制成渐变色
```js
// 如新增渐变色
 data.push({
    coordinates: [[10, 0, 0], [20, 0, 0]],
    color: ["#f00", "#0ff"]
})
polylines.setData(data)
```

<mapFrame>
<pre>
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, 0, 3],[-4, 0, -2],[-5, 0, 3]],
    color: "#00ff00"
})
data.push({
    coordinates: [[7, 0, -8],[-1, 2, -1],[-8, 1, -9],[7, 0, -8]],
    color: "#ffff00"
})
//
let polylines = new vjmap3d.GlLinesEntity({ //PolygonsEntity
    data: data,
})
polylines.addTo(app)
//
polylines.pointerEvents = true; // 允许事件交互
polylines.on("mouseover", e => {
    if (e?.intersection?.index !== undefined) {
        // LineSegments 命中的 index 是线段起点的顶点序号(0,2,4...)，除以 2 才是线段序号
        let itemData = polylines.getItemDataByIndex(Math.floor(e.intersection.index / 2));
        if (itemData && itemData.id) polylines.setItemHighlight(itemData.id, true)
    }
})
polylines.on("mouseout", e => {
    polylines.clearHighlight()
})
//
const ui = await app.getConfigPane({ title: "设置", style: { width: "250px", overflow: "hidden"}});
let cfg = [
    {
        type: 'checkbox',
        label: '显示顶点',
        getValue: () => polylines.isShowVertex(),
        setValue: v => {
            polylines.setShowVertex(v)
        }
    },
    {
        type: 'button',
        label: '增加一条线',
        value: ()=> {
            data.push({
                coordinates: [vjmap3d.randPoint3D(),vjmap3d.randPoint3D()],
                color: vjmap3d.randColor()
            })
            polylines.setData(data)
        }
    },
    {
        type: 'button',
        label: '修改第一条线颜色',
        value: ()=> {
            if (data.length > 0) {
                data[0].color = vjmap3d.randColor()
            }
            polylines.setData(data)
        }
    },
    {
        type: 'button',
        label: '删除第一条线',
        value: ()=> {
            if (data.length == 0) {
                return
            }
            data.splice(0, 1)
            polylines.setData(data)
        }
    },{
        type: 'button',
        label: '增加一条渐变色',
        value: ()=> {
            data.push({
                coordinates: [vjmap3d.randPoint3D(),vjmap3d.randPoint3D(),vjmap3d.randPoint3D()],
                // 当颜色为数组为，将绘制成渐变色
                color: [vjmap3d.randColor(), vjmap3d.randColor(), vjmap3d.randColor()]
            })
            polylines.setData(data)
        }
    }
]
cfg.forEach(c => ui.appendChild(c));
</pre>
</mapFrame>
