Mapbox-GL-JS + REACT:链接单选按钮切换地图图层

Mapbox-GL-JS + REACT: linking radio button to switch the layers of the map

我在链接我的单选按钮以切换地图图层时遇到问题。

下面我添加了工作代码的代码片段。

我正在定义两个图层,需要通过两个按钮进行切换。

这是我为地图制作的class!

export default class Application extends React.Component {
      map;
    
      constructor(props) {
        super(props);
        this.state = {
          active: radios[0],
        };
      }
    
      componentDidUpdate() {
        this.setVisibility();
      }
    
      componentDidMount() {
        const map = new mapboxgl.Map({
          container: this.mapContainer,
          style: {
            version: 8,
            // "glyphs":'http://localhost:7755/{fontstack}/{range}.pbf',
            // "sprite": "https://openmaptiles.github.io/klokantech-basic-gl-style/sprite",
            sources: {
              esri: {
                type: "raster",
                tiles: [
                  "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
                ]
              }
            },
            layers: [
              {
                id: "baselayer",
                type: "raster",
                source: "esri",
                minzoom: 3,
                maxzoom: 15
              }
            ]
          },
          center: [77.594, 16.9716],
          hash: true,
          zoom: 5
        });
    
        map.on("load", function() {
            map.addLayer({
            id: "district",
            type: "fill",
            source: {
              type: "vector",
              tiles: ["http://localhost:8080/data/karnataka12/{z}/{x}/{y}.pbf"],
              minzoom: 0,
              maxzoom: 6
            },
            "source-layer": "karnataka",
            layout: {
              visibility: "visible"
            },
            paint: {
              "fill-color": "#cbffcb",
              "fill-opacity": 0.3,
              "fill-outline-color": "blue"
            }
          });
          map.addLayer({
            id: "district2",
            type: "fill",
            source: {
              type: "vector",
              tiles: ["http://localhost:8080/data/andhrapradesh/{z}/{x}/{y}.pbf"],
              minzoom: 0,
              maxzoom: 6
            },
            "source-layer": "andhrapradesh",
            layout: {
              visibility: "none"
            },
            paint: {
              "fill-color": "#f4c430",
              "fill-opacity": 0.3,
              "fill-outline-color": "green"
            }
          });
           function switchLayer(props, layer_id) {
      if ( this.state.vision[i] === true ) {
        map.setLayoutProperty( id, 'visibility', 'none');
      } else {
        map.setLayoutProperty( id, 'visibility', 'visible');
      }
    };

    });

   

  }

这是包含两个切换按钮的导航栏的代码!

class Settings extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          active: {},
          value: "",
          checked: true
        };
      }
    
     
      handleInputChange = event => {
        this.setState({
          [event.target.name]: event.target.value
        });
        console.log("")
      };
    
      handleSubmit = event => {
        event.preventDefault();
        const data = this.state;
        console.log(data);
      };
    
      componentDidMount() {
        document.addEventListener("click", this.handleSettingClick, false);
      }
    
      componentWillUnmount() {
        document.removeEventListener("click", this.handleSettingClick, false);
      }
    
      handleSettingClick = e => {
        if (this.node1.contains(e.target)) {
          return;
        } else {
          this.props.onCloseClick();
        }
      };
    
      // onCheck = (e) => {
      //   this.setState({
      //     checked: !this.state.checked
      //   });
      // }; //for the state of toggle key checked or not
    
      render() {
        console.log("This button was toggled: " + this.state.value);
    
        const renderRadios = (radios, i) => {
          return (
            <label>
              <div >
                <Radio
                  toggle
                  label={radios.value}
                  // onChange={this.onCheck.bind(this)}
                  onChange={() => this.setState({ active: radios[i]})}               // checked={radios.value}
                />
              </div>
              <br />
              <br />
            </label>
          );
        };
    
        return (
          <div ref={node1 => (this.node1 = node1)}>
            <nav
              style={{
                marginTop: "60px",
                height: "100%",
                padding: "15px 15px 15px 20px",
                background: "#fff",
                boxShadow: "0px 0px 1px 0px #000",
                position: "fixed",
                top: "0",
                right: "-590px",
                minWidth: "590px",
                zIndex: "2",
                transform: "translateX(-100%)",
                transition: "transform 0.3s ease-out",
                overflowY: "scroll"
              }}
            >
              <svg
                style={{
                  width: "40px",
                  height: "40px",
                  cursor: "pointer",
                  padding: "5px 0px 5px 0px",
                  fill: "#00894a"
                }}
                onClick={this.props.onCloseClick}
              >
                <path d="M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z"></path>
              </svg>
    
              <h1 style={{ marginLeft: "5px", marginTop: "5px" }}>Settings</h1>
              <br/>
    
              <div>
                <form onSubmit={this.handleSubmit}>
                  <Input
                    fluid
                    action="Search"
                    placeholder="Search..."
                    name="You searched: "
                    onChange={this.handleInputChange}
                    autoFocus
                  />
                </form>
              </div>
              <br />
              <br />
    
              <Divider />
              <Divider />
              <Divider />
    
              <br />
              <div id="toggle">{radios.map(renderRadios)}</div>
              <br />
    
              <Divider />
              <Divider />
              <Divider />
    
            </nav>
          </div>
        );
      }
    }

我参考了mapbox提供的例子。 但这于事无补!

**需要什么:**

当我们在设置窗格中点击切换按钮时,图层应该被添加,当我们再次点击切换按钮时,图层应该被删除!

只是你必须在组件中定义图层对象。

const layer= {
  'id': 'urban-areas-fill',
  'type': 'fill',
  'source': {
  'type': 'geojson',
  'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson'
  },
  'layout': {},
  'paint': {
  'fill-color': '#f08',
  'fill-opacity': 0.4
  }
};

使用以下两种方法在单击切换按钮时删除图层

// pass id of layer
map.removeLayer('urban-areas-fill');
map.removeSource('urban-areas-fill');

然后使用下面的方法添加图层

map.addLayer(layer);


下面是带有复选框的 add/remove 层的简单示例。

class MapGL extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      layers: [
        {
          name: 'Urban Areas',
          layer: {
            'id': 'urban-areas-fill',
            'type': 'fill',
            'source': {
              'type': 'geojson',
              'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson'
            },
            'layout': {},
            'paint': {
              'fill-color': '#f08',
              'fill-opacity': 0.4
            }
          }
        },
        {
          name: 'Urban Areas - 1',
          layer: {
            'id': 'urban-areas-fill-1',
            'type': 'fill',
            'source': {
              'type': 'geojson',
              'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson'
            },
            'layout': {},
            'paint': {
              'fill-color': '#f08',
              'fill-opacity': 0.4
            }
          }
        },
        {
          name: 'Urban Areas - 2',
          layer: {
            'id': 'urban-areas-fill-2',
            'type': 'fill',
            'source': {
              'type': 'geojson',
              'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson'
            },
            'layout': {},
            'paint': {
              'fill-color': '#f08',
              'fill-opacity': 0.4
            }
          }
        },
        {
          name: 'Urban Areas - 3',
          layer: {
            'id': 'urban-areas-fill-3',
            'type': 'fill',
            'source': {
              'type': 'geojson',
              'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson'
            },
            'layout': {},
            'paint': {
              'fill-color': '#f08',
              'fill-opacity': 0.4
            }
          }
        }
      ]
    };
    this.map = null;
  }

  componentDidMount() {
    this.map = new mapboxgl.Map({
      container: this.mapContainer,
      style: 'mapbox://styles/mapbox/streets-v9',
      center: [77.594, 16.9716],
      hash: true,
      zoom: 5
    });
  }

  handleLayers(e, layer) {
    if (e.target.checked) {
      this.map.addLayer(layer);
    }
    else {
      this.map.removeLayer(layer.id);
      this.map.removeSource(layer.id);
    }
  }

  render() {
    const { layers } = this.state;
    return (
      <div>
        {layers.map(x => <label style={{ marginRight: 20 }}>
          <input type="checkbox" style={{ marginRight: 5 }} onChange={e => this.handleLayers(e, x.layer)} />{x.name}
        </label>
        )}
        <div ref={el => this.mapContainer = el} className="absolute top right left bottom" />
      </div>
    );
  }
}

export default MapGL;



输出:

希望对您有所帮助!