mapbox-gl 스타일을 효과적으로 전환하기

12870 단어 mapboxgl
안녕하세요!

known 의 일반적인 문제 mapbox-gl 에 대해 쓰고 싶습니다.
현재 솔루션에는 some proposals이 있고 일부는 workarounds 있습니다.

이 기사에서는 일반적인 시나리오를 보고 구현하려고 합니다.

문제의 조건



간단한 경우를 설명하자면 다음과 같습니다.
  • 지도에 텍스트 레이블 앞에 자체GeoJSON 소스와 해당 레이어를 추가해야 합니다.
  • 기본 스타일을 전환할 때 레이어는 지도에 남아 있어야 합니다.

  • mapbox-gl 이벤트와 함께 간단한 접근 방식을 사용합니다.

    소스 정의



    // constants.js
    const GEOJSON_FEATURE = {
      type: "Feature",
      properties: {},
      geometry: {
        type: "Polygon",
        coordinates: [
          [
            [-66.96466, 44.8097],
            [-67.79035274928509, 47.066248887716995],
            [-69.23708614772835, 47.44777598732787],
            [-71.08482, 45.3052400000002],
            [-70.64573401557249, 43.090083319667144],
            [-66.96466, 44.8097],
          ],
        ],
      },
    };
    

    지도 만들기



    // index.js
    mapboxgl.accessToken = <your token here>;
    var map = new mapboxgl.Map({
      container: "map",
      style: "mapbox://styles/mapbox/streets-v11",
      center: [-68.13734351262877, 45.137451890638886],
      zoom: 5,
    });
    

    addLayer 기능 개선



    지도에 이미 존재하지 않는 beforeId를 사용하면 오류가 발생합니다.
    이것을 피하기 위해 addLayerBefore 함수를 생성합시다.

    function addLayerBefore(addLayerFn, layer, beforeId) {
    // check beforeId defined and exists on the map
    const beforeLayer = Boolean(beforeId) && map.getLayer(beforeId);
      if (beforeLayer && beforeId === beforeLayer.id) addLayerFn(layer, beforeId);
      else {
        console.warn(
          `Not found layer with id '${beforeId}'.\nLayer '${layer.id}' added without before.`
        );
        addLayerFn(layer);
      }
    }
    


    데이터 추가 기능 정의



    채우기 레이어가 있는 Add의 GeoJSON 소스, 현재 예에서 waterway-label 이전에는 지도 텍스트 레이블 앞에 다각형이 배치됩니다.

    function addMaineLayer() {
      map.addSource("maine", {
        type: "geojson",
        data: {
          type: "Feature",
          geometry: GEOJSON_FEATURE
      });
    
      // define the function to add layer
      const addLayer = (layer, beforeId) => map.addLayer(layer, beforeId);
    
      addLayerBefore(
        addLayer,
        {
          id: "maine",
          type: "fill",
          source: "maine",
          layout: {},
          paint: {
            "fill-color": "#088",
            "fill-opacity": 0.8
          }
        },
        "waterway-label"
      );
    }
    


    설정 이벤트



    다음과 같은 경우 addMaineLayer 함수를 호출해야 합니다.
  • 맵이 처음에 load 이벤트와 함께 로드됨
  • 지도가 styledata 이벤트로 스타일을 변경함

  • map.on("load", function () {
      // add layer to the map on load
      addMaineLayer();
    
      const layerList = document.getElementById("menu");
      const inputs = layerList.getElementsByTagName("input");
    
      function switchLayer(layer) {
        // addMaineLayer fn will be called once on layer switched
        map.once("styledata", addMaineLayer);
        const layerId = layer.target.id;
        map.setStyle("mapbox://styles/mapbox/" + layerId);
      }
    
      // set toggle base style events
      for (let i = 0; i < inputs.length; i++) {
        inputs[i].onclick = switchLayer;
      }
    });
    


    결과를 확인해보자





    그건!
    다음 기사에서 우리는 이것을 RxJS로 구현하려고 합니다!

    좋은 웹페이지 즐겨찾기