Mapbox-GL-JS + REACT,请

时间:2019-08-26 08:39:10

标签: reactjs maps toggle mapbox mapbox-gl-js

I am having trouble linking my radio button to switch the layers of my map.
Below i am adding the code snippets of the working code.
I am defining two layers which needs to be toggled from two buttons.

这是我为地图制作的课程!

    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提供的示例。 但这无济于事!

需要什么!!!!

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

从过去2天开始就参与其中!

1 个答案:

答案 0 :(得分:0)

只需在组件中定义图层对象。

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);


下面是使用复选框添加/删除图层的简单示例。

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;



输出:

enter image description here

希望这对您有帮助!