Newer
Older
KaiFengPC / src / views / sponeScreen / gisMF / mapboxVectorLayer.js
@jimengfei jimengfei on 1 Nov 20 KB updata
export default class newfiberMapBoxVectorLayer {
  //添加circle
  static addGeojsonCircle(layerId, geojson) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'circle',
        source: layerId,
        paint: {
          'circle-color': ['get', 'fillcolor'],
          'circle-radius': 10,
        },
      });
    }
  }
  //添加circle有标注
  static addGeojsonCircleWithLabel(layerId, geojson, minzoom) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addSource(layerId + '_label', {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'circle',
        source: layerId,
        paint: {
          'circle-color': ['get', 'fillcolor'],
          'circle-radius': 10,
        },
      });
      newfiberMapbox.map.addLayer({
        id: layerId + '_label',
        type: 'symbol',
        minzoom: minzoom ? minzoom : 0,
        source: layerId + '_label',
        paint: {
          'text-color': 'rgba(255, 255, 255, 1)',
          'text-halo-color': 'rgba(36, 94, 122, 1)',
          'text-halo-width': 2,
        },
        layout: {
          'text-field': '{name}',
          'text-font': ['KlokanTech Noto Sans Regular'],
          'text-size': 16,
          'text-line-height': 3,
          'text-anchor': 'bottom',
          'text-max-width': 50,
        },
      });
    }
  }
  //添加geojson label
  static addGeojsonLabel(layerId, geojson, textsize, textmaxwidth) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      // Add a data source containing one point feature.
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'symbol',
        source: layerId,
        paint: {
          'text-color': ['get', 'fillcolor'],
          'text-halo-color': 'rgba(250, 247, 227, 1)',
          'text-halo-width': 1,
        },
        layout: {
          'text-allow-overlap': true,
          'text-field': '{name}',
          'text-font': ['KlokanTech Noto Sans Regular'],
          'text-size': textsize ? textsize : 16,
          'text-line-height': 1,
          'text-anchor': 'bottom',
          'text-max-width': textmaxwidth ? textmaxwidth : 4,
          //'text-offset': [0, 3],
        },
      });
    }
  }
  //添加geojson Symbol
  static addGeojsonSymbol(layerId, geojson, icon, textmaxwidth, textlineheight, textOffset) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.loadImage(icon, (error, image) => {
        if (error) throw error;

        // Add the image to the map style.
        newfiberMapbox.map.addImage(layerId, image);

        // Add a data source containing one point feature.
        newfiberMapbox.map.addSource(layerId, {
          type: 'geojson',
          data: geojson,
        });
        newfiberMapbox.map.addLayer({
          id: layerId,
          type: 'symbol',
          source: layerId,
          paint: {
            'text-color': 'rgba(255, 255, 255, 1)',
            'text-halo-color': 'rgba(14, 139, 90, 1)',
            'text-halo-width': 2,
          },
          layout: {
            'icon-image': layerId,
            'text-allow-overlap': true,
            'icon-allow-overlap': true,
            'icon-anchor': 'center',
            'icon-size': 0.8,
            'text-field': '{name}',
            'text-font': ['KlokanTech Noto Sans Regular'],
            'icon-rotate': ['get', 'bearing'],
            'text-size': 16,
            'text-line-height': textlineheight ? textlineheight : 3,
            'text-anchor': 'bottom',
            'text-max-width': textmaxwidth ? textmaxwidth : 50,
            'text-offset': [0, textOffset ? textOffset : 3.5],
          },
        });
      });
    }
  }
  //添加geojson线
  static addGeojsonLine(layerId, geojson, lineWidth, lineOpacity, lineBlur) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'line',
        source: layerId,
        paint: {
          'line-color': ['get', 'fillcolor'],
          'line-width': lineWidth ? lineWidth : 3,
          'line-opacity': lineOpacity ? lineOpacity : 1,
          'line-blur': lineBlur ? lineBlur : 0,
        },
      });
    }
  }
  //添加有标注的geojson线
  static addGeojsonLineWithLabel(layerId, geojson, lineWidth, minzoom) {
    let labelGeojson = this.getGeojsonCenterPoint(geojson);
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addSource(layerId + '_label', {
        type: 'geojson',
        data: labelGeojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'line',
        source: layerId,
        paint: {
          'line-color': ['get', 'fillcolor'],
          'line-width': lineWidth ? lineWidth : 3,
        },
      });
      newfiberMapbox.map.addLayer({
        id: layerId + '_label',
        type: 'symbol',
        minzoom: minzoom ? minzoom : 0,
        source: layerId + '_label',
        paint: {
          'text-color': 'rgba(255, 255, 255, 1)',
          'text-halo-color': 'rgba(36, 94, 122, 1)',
          'text-halo-width': 2,
        },
        layout: {
          'text-field': '{name}',
          'text-font': ['KlokanTech Noto Sans Regular'],
          'text-size': 16,
          'text-line-height': 3,
          'text-anchor': 'bottom',
          'text-max-width': 50,
        },
      });
    }
  }
  //构建geojson格式
  static getGeojsonData(dataList) {
    let features = [];
    let feature = {};
    dataList.forEach(data => {
      if (data.lonLat) {
        let lonlat = data.lonLat.split(',');
        feature = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [Number(lonlat[0]), Number(lonlat[1])],
          },
          properties: data,
        };
      } else if (data.lonlat) {
        let lonlat = data.lonlat.split(',');
        feature = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [Number(lonlat[0]), Number(lonlat[1])],
          },
          properties: data,
        };
      } else if (data.lon && data.lat) {
        feature = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [Number(data.lon), Number(data.lat)],
          },
          properties: data,
        };
      } else if (data.originalX && data.originalY) {
        feature = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [Number(data.originalX), Number(data.originalY)],
          },
          properties: data,
        };
      } else if (data.longitude && data.latitude) {
        feature = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [Number(data.longitude), Number(data.latitude)],
          },
          properties: data,
        };
      }
      features.push(feature);
    });
    return {
      type: 'FeatureCollection',
      features: features,
    };
  }
  //汇水范围json
  static getPolygonGeojson(dataList) {
    let features = [];
    let feature = {};
    dataList.forEach(data => {
      if (!data.geometrys) return;
      feature = turf.feature(Terraformer.WKT.parse(data.geometrys), data);
      features.push(feature);
    });
    return {
      type: 'FeatureCollection',
      features: features,
    };
  }
  //添加geojson面
  static addGeojsonPolygon(layerId, geojson) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });

      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'fill',
        source: layerId,
        paint: {
          'fill-color': ['get', 'fillcolor'] || 'rgba(154,104,171,0.8)',
        },
      });
    }
  }

  //添加有标注的geojson面
  static addGeojsonPolygonWithLabel(layerId, geojson, minzoom, text_max_width) {
    let labelGeojson = this.getGeojsonCenterPoint(geojson);
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addSource(layerId + '_label', {
        type: 'geojson',
        data: labelGeojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'fill',
        source: layerId,
        paint: {
          'fill-color': ['get', 'fillcolor'],
        },
      });
      newfiberMapbox.map.addLayer({
        id: layerId + '_label',
        type: 'symbol',
        source: layerId + '_label',
        minzoom: minzoom ? minzoom : 0,
        paint: {
          'text-color': 'rgba(255, 255, 255, 1)',
          'text-halo-color': 'rgba(36, 94, 122, 1)',
          'text-halo-width': 2,
        },
        layout: {
          'text-field': '{name}',
          'text-font': ['KlokanTech Noto Sans Regular'],
          'text-size': 16,
          'text-line-height': 1,
          'text-max-width': !!text_max_width ? text_max_width : 50,
        },
      });
    }
  }
  //获取geojson中心点
  static getGeojsonCenterPoint(geojson) {
    let features = [];
    geojson.features.forEach(element => {
      let feature = turf.center(element, element);
      features.push(feature);
    });
    return {
      type: 'FeatureCollection',
      features: features,
    };
  }
  //添加image图层
  static addImageToMap(layerId, coordinates, imageUrl) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'image',
        url: imageUrl,
        coordinates: coordinates,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'raster',
        source: layerId,
        paint: {},
      });
    }
  }
  //添加geoserver图层
  static addWMSLayer(layerName) {
    if (!newfiberMapbox.map.getLayer(layerName)) {
      newfiberMapbox.map.addSource(layerName, {
        type: 'raster',
        // use the tiles option to specify a WMS tile source URL
        // https://docs.mapbox.comhttps://docs.mapbox.com/style-spec/reference/sources/
        tiles: [
          '/geoserver/demo/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&' +
            `layers=${layerName}`,
        ],
        tileSize: 256,
      });
      newfiberMapbox.map.addLayer({
        id: layerName,
        type: 'raster',
        source: layerName,
        paint: {},
      });
    }
  }
  //添加沿线标注
  static addLabelAlongLine(layerId, geojson) {
    if (!newfiberMapbox.map.getLayer(layerId)) {
      newfiberMapbox.map.addSource(layerId, {
        type: 'geojson',
        data: geojson,
      });
      newfiberMapbox.map.addLayer({
        id: layerId,
        type: 'symbol',
        source: layerId,
        layout: {
          'text-field': ['get', 'name'],
          'symbol-placement': 'line-center',
          'text-offset': [0, -0.5],
          //'text-anchor': 'top',
          'text-size': 20,
          'text-allow-overlap': true,
          'text-letter-spacing': 1.1,
        },
        paint: {
          'text-color': ['get', 'fillcolor'],
          'text-halo-color': 'rgba(250, 247, 227, 1)',
          'text-halo-width': 1,
        },
      });
    }
  }
  //添加轨迹动态线
  static addDynamicRoute = (layerId, geojson, icon) => {
    window.routeTimer = null;
    window.routeTimer_1 = null;
    this.addGeojsonLine(layerId, geojson, 10);
    let symbolGeojson = turf.featureCollection([
      turf.point(geojson.features[0].geometry.coordinates[0], {
        bearing: turf.bearing(
          turf.point(geojson.features[0].geometry.coordinates[0]),
          turf.point(geojson.features[0].geometry.coordinates[1])
        ),
      }),
    ]);
    let symbolGeojson_1 = turf.featureCollection([
      turf.point(geojson.features[1].geometry.coordinates[0], {
        bearing: turf.bearing(
          turf.point(geojson.features[1].geometry.coordinates[0]),
          turf.point(geojson.features[1].geometry.coordinates[1])
        ),
      }),
    ]);
    this.addGeojsonSymbol(layerId + '_Symbol', symbolGeojson, icon);
    this.addGeojsonSymbol(layerId + '_Symbol_1', symbolGeojson_1, icon);
    const lineDistance = turf.length(geojson.features[0]);
    const lineDistance_1 = turf.length(geojson.features[1]);
    const arc = [];
    const arc_1 = [];
    const steps = 100;
    for (let i = 0; i < lineDistance; i += lineDistance / steps) {
      const segment = turf.along(geojson.features[0], i);
      arc.push(segment.geometry.coordinates);
    }
    for (let i = 0; i < lineDistance_1; i += lineDistance_1 / steps) {
      const segment = turf.along(geojson.features[1], i);
      arc_1.push(segment.geometry.coordinates);
    }
    geojson.features[0].geometry.coordinates = arc;
    geojson.features[1].geometry.coordinates = arc_1;
    let counter = 0;
    let counter_1 = 0;

    const start_1 = geojson.features[1].geometry.coordinates[counter_1 >= steps ? counter_1 - 1 : counter_1];
    const end_1 = geojson.features[1].geometry.coordinates[counter_1 >= steps ? counter_1 : counter_1 + 1];
    setTimeout(() => {
      window.routeTimer = setInterval(() => {
        const start = geojson.features[0].geometry.coordinates[counter >= steps ? counter - 1 : counter];
        const end = geojson.features[0].geometry.coordinates[counter >= steps ? counter : counter + 1];
        if (!start || !end) {
          return;
        }
        symbolGeojson.features[0].geometry.coordinates = geojson.features[0].geometry.coordinates[counter];
        symbolGeojson.features[0].properties.bearing = turf.bearing(turf.point(start), turf.point(end));

        newfiberMapbox.map.getSource(layerId + '_Symbol').setData(symbolGeojson);
        counter = counter + 1;
        if (counter > steps) {
          clearInterval(window.routeTimer);
        }
      }, 100);
      window.routeTimer_1 = setInterval(() => {
        const start_1 = geojson.features[1].geometry.coordinates[counter_1 >= steps ? counter_1 - 1 : counter_1];
        const end_1 = geojson.features[1].geometry.coordinates[counter_1 >= steps ? counter_1 : counter_1 + 1];
        if (!start_1 || !end_1) {
          return;
        }
        symbolGeojson_1.features[0].geometry.coordinates = geojson.features[1].geometry.coordinates[counter_1];
        symbolGeojson_1.features[0].properties.bearing = turf.bearing(turf.point(start_1), turf.point(end_1));

        newfiberMapbox.map.getSource(layerId + '_Symbol_1').setData(symbolGeojson_1);
        counter_1 = counter_1 + 1;
        if (counter_1 > steps) {
          clearInterval(window.routeTimer_1);
        }
      }, 100);
    }, 1000);
    // if (!start || !end || !start_1 || !end_1) {
    //   return;
    // }

    // symbolGeojson_1.features[0].geometry.coordinates = geojson.features[1].geometry.coordinates[counter_1];
    // symbolGeojson_1.features[0].properties.bearing = turf.bearing(turf.point(start_1), turf.point(end_1));
  };
  //移除图层
  static removeByIds(layernameList) {
    layernameList.forEach(layerName => {
      if (newfiberMapbox.map.getLayer(layerName)) {
        newfiberMapbox.map.removeLayer(layerName);
        newfiberMapbox.map.removeSource(layerName);
      }
      if (newfiberMapbox.map.getSource(layerName)) {
        newfiberMapbox.map.removeLayer(layerName);
        newfiberMapbox.map.removeSource(layerName);
      }
    });
  }
  //添加天气效果
  static addMapboxWeather() {
    var camera, scene, renderer, control, material;
    var clock = new THREE.Clock();
    var time = 0;

    newfiberMapbox.map.addLayer({
      id: 'custom_layer',
      type: 'custom',
      renderingMode: '3d',
      onAdd: function (map, mbxContext) {
        window.tb = new Threebox(map, mbxContext, { defaultLights: true });
        camera = map.getFreeCameraOptions();

        var mesh = createRain();
        mesh = window.tb
          .Object3D({ obj: mesh, units: 'meters', bbox: false, anchor: 'center' })
          .setCoords([114.30144051057519, 34.7982491425239, 0]);
        mesh.setRotation({ x: 90, y: 0, z: 0 });
        tb.add(mesh);
      },
      render: function (gl, matrix) {
        tb.update();
        newfiberMapbox.map.triggerRepaint();
      },
    });

    //创建雨
    function createRain() {
      // 雨的盒子
      const box = new THREE.Box3(
        new THREE.Vector3(-5000, 0, -5000),
        // 下雨的范围
        new THREE.Vector3(5000, 5000, 5000)
      );

      //创建雨(雨的材质)
      material = new THREE.MeshBasicMaterial({
        transparent: true,
        opacity: 1,
        map: new THREE.TextureLoader().load('./images/drop.png'),
        depthWrite: false,
      });

      material.onBeforeCompile = function (shader, renderer) {
        const getFoot = `
            uniform float top;
            uniform float bottom;
            uniform float time;
            #include <common>
            float angle(float x, float y){
              return atan(y, x);
            }
            vec2 getFoot(vec2 camera,vec2 normal,vec2 pos){
                vec2 position;

                float distanceLen = distance(pos, normal);
                float a = angle(camera.x - normal.x, camera.y - normal.y);
                pos.x > normal.x ? a -= 0.785 : a += 0.785; 
                position.x = cos(a) * distanceLen;
                position.y = sin(a) * distanceLen;
                return position + normal;
            }
            `;
        const begin_vertex = `
            vec2 foot = getFoot(vec2(cameraPosition.x, cameraPosition.z),  vec2(normal.x, normal.z), vec2(position.x, position.z));
            float height = top - bottom;
            float y = normal.y - bottom - height * time;
            y = y + (y < 0.0 ? height : 0.0);
            float ratio = (1.0 - y / height) * (1.0 - y / height);
            y = height * (1.0 - ratio);
            y += bottom;
            y += position.y - normal.y;
            vec3 transformed = vec3( foot.x, y, foot.y );
            `;
        shader.vertexShader = shader.vertexShader.replace('#include <common>', getFoot);
        shader.vertexShader = shader.vertexShader.replace('#include <begin_vertex>', begin_vertex);

        shader.uniforms.cameraPosition = {
          value: new THREE.Vector3(0, 200, 0),
        };
        shader.uniforms.top = {
          value: 5000,
        };
        shader.uniforms.bottom = {
          value: 0,
        };
        shader.uniforms.time = {
          value: 0,
        };
        material.uniforms = shader.uniforms;
      };

      var geometry = new THREE.BufferGeometry();

      const vertices = [];
      const normals = [];
      const uvs = [];
      const indices = [];
      // 雨量
      for (let i = 0; i < 5000; i++) {
        const pos = new THREE.Vector3();
        pos.x = Math.random() * (box.max.x - box.min.x) + box.min.x;
        pos.y = Math.random() * (box.max.y - box.min.y) + box.min.y;
        pos.z = Math.random() * (box.max.z - box.min.z) + box.min.z;

        const height = (box.max.y - box.min.y) / 15;
        const width = height / 50;

        vertices.push(
          pos.x + width,
          pos.y + height / 2,
          pos.z,
          pos.x - width,
          pos.y + height / 2,
          pos.z,
          pos.x - width,
          pos.y - height / 2,
          pos.z,
          pos.x + width,
          pos.y - height / 2,
          pos.z
        );

        normals.push(pos.x, pos.y, pos.z, pos.x, pos.y, pos.z, pos.x, pos.y, pos.z, pos.x, pos.y, pos.z);

        uvs.push(1, 1, 0, 1, 0, 0, 1, 0);

        indices.push(i * 4 + 0, i * 4 + 1, i * 4 + 2, i * 4 + 0, i * 4 + 2, i * 4 + 3);
      }

      geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3));
      geometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));
      geometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
      geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indices), 1));

      var mesh = new THREE.Mesh(geometry, material);
      return mesh;
    }
    animate();

    function animate() {
      requestAnimationFrame(animate);
      render();
    }

    function render() {
      // 下雨速率
      time = (time + clock.getDelta() * 0.3) % 1;

      if (!camera) {
        return;
      }

      material.cameraPosition = camera.position;
      if (material.uniforms) {
        material.uniforms.time.value = time;
      }
    }
  }
}