Skip to content

一、绘制多条线

1. 多条线

  • 数据结构
    json5
    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "type": "LineString",
            "coordinates": [
              [
                93.55957031249999,
                41.21172151054787
              ],
              [
                93.955078125,
                29.267232865200878
              ],
              [
                103.7548828125,
                29.916852233070173
              ]
            ]
          }
        }
      ]
    }
  • geojson.io 上显示 line-string-1.png

二、绘制多线条

1. 核心代码

  • 数据解析
    js
      /**
       * 处理地图经纬度数据
       */
      initMultipleLine() 
      {
        this.#mapData?.features?.map(item => {
          const areas = item.geometry.coordinates;
          const areaVector = { coordinates: [] };
          areas.map(area => {
            areaVector.coordinates.push(this.lnglatToVector(area))
          })
          this.#vector3Json.push(areaVector);
        })
        // 绘制模块
        const group = new Group();
        this.#vector3Json.map(vector => {
          const mesh = this.drawLine(vector.coordinates);
          group.add(mesh);
        })
        this.scene.add(group);
      }
  • 绘制线条
    js
      /**
       * 绘制线条
       */
      drawLine(points = [])
      {
        const geometry = new BufferGeometry();
        const pointsTotal = []
        points.map(point => {
          pointsTotal.push(...point)
        })
        const vertices = new Float32Array(pointsTotal);
        // 写法一:
        geometry.setAttribute('position', new BufferAttribute(vertices, 3))
        // 写法二:
        // geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3))    
     
        // 材质
        const material = new LineBasicMaterial({
          color: "#007cff",
          transparent: true,
          opacity: 0.5,
        });
        // 合并
        const mesh = new Line(geometry, material);
        return mesh;
      }

2. 完整示例

  • 代码示例

    js
    import ThreeBase from "./ThreeBase";
    import * as D3 from 'd3-geo';
    import axios from "axios";
    import {Group, LineBasicMaterial, Line, BufferGeometry, BufferAttribute} from 'three';
    
    
    /**
     * 绘制多条线
     */
    export default class ThreeMultiplePolygonMap extends ThreeBase {
    
      #projection;
      #mapData;
      #vector3Json = [];
    
      constructor() {
        super();
      }
    
      initMapData() {
        return axios.get('geojson/line.json').then(res => {
          this.#mapData = res.data;
        })
      }
    
      initObj() {
        this.initMapData().then(() => {
          this.initMultipleLine()
        })
      }
    
      /**
       * 绘制线条
       */
      drawLine(points= []) {
        const geometry = new BufferGeometry();
        const pointsTotal = []
        points.map(point => {
          pointsTotal.push(...point)
        })
        const vertices = new Float32Array(pointsTotal);
        geometry.setAttribute('position', new BufferAttribute(vertices, 3))
    
        // 材质
        const material = new LineBasicMaterial({
          color: "#007cff",
          transparent: true,
          opacity: 0.5
        });
        // 合并
        const mesh = new Line(geometry, material);
        return mesh;
      }
    
      /**
       * 处理地图经纬度数据
       */
      initMultipleLine() {
        this.#mapData?.features?.map(item => {
          const areas = item.geometry.coordinates;
          const areaVector = { coordinates: [] };
          areas.map(area => {
            areaVector.coordinates.push(this.lnglatToVector(area))
          })
          this.#vector3Json.push(areaVector);
        })
        // 绘制模块
        const group = new Group();
        this.#vector3Json.map(vector => {
          const mesh = this.drawLine(vector.coordinates);
          group.add(mesh);
        })
        this.scene.add(group);
      }
    
      lnglatToVector(lnglat) {
        if (!this.#projection) {
          this.#projection = D3.geoMercator()
            .center([112.946332, 28.236672])
            .scale(400)
            .translate([0,0]);
        }
        const [y, x] = this.#projection([...lnglat]);
        const z = 0;
        return [y, x, z];
      }
    }
  • 效果展示

    line-string-map.png

Released under the MIT License.