12

我正在尝试添加一条 GeoJSON 线来显示 A 点和 B 点之间的汽车方向(就像他们在 mapbox-gl-js 的官方文档中一样(https://www.mapbox.com/mapbox-gl- js/example/geojson-line/ )

但是 react-map-gl 的文档根本没有谈到这一点。

如何使用 https://uber.github.io/react-map-gl/#/Documentation/introduction/introduction实现类似的功能:

到目前为止,这是我的代码:

class MapPage extends Component {
  constructor(props) {
    super(props);
     this.state = {
      viewport: {
       latitude: 38.63738602787579,
       longitude: -121.23576311149986,
       zoom: 6.8,
       bearing: 0,
       pitch: 0,
       dragPan: true,
       width: 600, 
       height: 600 
     }
    };
   }

render() {
  const { viewport } = this.state;

  return (
    <ReactMapGL
      {...viewport}
      mapboxApiAccessToken={MAPBOX_TOKEN}
      onViewportChange={newViewport => {
        this.setState({ viewport: newViewport });
      }}
    />
  );
 }
}

屏幕截图 2017-12-20 在 5 55 10 pm

4

3 回答 3

10

一旦组件挂载,您可以获得 mapbox-gl 地图对象,然后您可以直接使用它。尝试这样的事情:

class MapPage extends Component {
      constructor(props) {
        super(props);
         this.state = {
          viewport: {
           latitude: 38.63738602787579,
           longitude: -121.23576311149986,
           zoom: 6.8,
           bearing: 0,
           pitch: 0,
           dragPan: true,
           width: 600, 
           height: 600 
         }
        };
       }
    componentDidMount(){
      const map = this.reactMap.getMap();
      map.on('load', () => {
       //add the GeoJSON layer here
       map.addLayer({...})
      })
    }

    render() {
      const { viewport } = this.state;

      return (
        <ReactMapGL
          ref={(reactMap) => this.reactMap = reactMap} />
          {...viewport}
          mapboxApiAccessToken={MAPBOX_TOKEN}
          onViewportChange={newViewport => {
            this.setState({ viewport: newViewport });
          }}
        />
      );
     }
    }

反应参考:https ://reactjs.org/docs/refs-and-the-dom.html

GetMap():https ://uber.github.io/react-map-gl/#/Documentation/api-reference/static-map?section=methods

于 2017-12-29T19:41:30.443 回答
5

适用于使用 react-map-gl 5.0 及以上版本的用户

截至 2019 年 10 月,react-map-gl支持LayerSource组件,这意味着开发人员可以在 Mapbox 画布上渲染 Mapbox 图层,而无需调用getMap()以公开底层原生 Mapbox API。

您可以参考原始 Mapbox图层Layer文档,了解和Source道具的有效值的完整规范。

这就是如何将SourceLayer组件与您提供的代码一起使用以在地图上生成 GeoJSON 线。

class MapPage extends Component {
  constructor(props) {
    super(props);
     this.state = {
      viewport: {
       latitude: 38.63738602787579,
       longitude: -121.23576311149986,
       zoom: 6.8,
       bearing: 0,
       pitch: 0,
       dragPan: true,
       width: 600, 
       height: 600 
     }
    };
   }

render() {
  const { viewport } = this.state;

  return (
    <ReactMapGL
      {...viewport}
      mapboxApiAccessToken={MAPBOX_TOKEN}
      onViewportChange={newViewport => {
        this.setState({ viewport: newViewport });
      }}
    >
      <Source id='polylineLayer' type='geojson' data={polylineGeoJSON}>
        <Layer
          id='lineLayer'
          type='line'
          source='my-data'
          layout={{
           'line-join': 'round',
           'line-cap': 'round',
          }}
          paint={{
           'line-color': 'rgba(3, 170, 238, 0.5)',
            'line-width': 5,
          }}
        />
      </Source>
    </ReactMapGL>
  );
 }
}
于 2020-02-12T02:38:51.030 回答
0
nice job.
now try this.
import React, { Component } from 'react';
import ReactMapGL, {
  Marker,
  FullscreenControl,
  GeolocateControl,
  Source,
  Layer,
  SVGOverlay,
  HTMLOverlay,
  NavigationControl,
  LinearInterpolator,
  CanvasOverlay,
  Popup
} from 'react-map-gl';
const geojson = {
  type: 'FeatureCollection',
  features: [
    { type: 'Feature', geometry: { type: 'Point', coordinates: [73.05625599999999, 33.644543999999996] } }
  ]
};

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      markerLat: 33.644543999999996,
      markerlng: 73.05625599999999,
      showPopup: true,
      viewport: {
        width: window.innerWidth,
        height: window.innerHeight,
        latitude: 41.8662,
        longitude: -87.61694,
        zoom: 15.99,
        pitch: 40,
        bearing: 20,
        antialias: true
      }
    };
    this.re = React.createRef();
  }

  componentDidMount(){
   // window.addEventListener("resize", this.resize.bind(this));
    const map = this.reactMap.getMap();
   // console.log('map object',map.on)
    map.on('load', function() {

     //add the GeoJSON layer here
    map.addLayer({
      'id': 'room-extrusion',
'type': 'fill-extrusion',
'source': {
// GeoJSON Data source used in vector tiles, documented at
// https://gist.github.com/ryanbaumann/a7d970386ce59d11c16278b90dde094d
'type': 'geojson',
'data': 'https://docs.mapbox.com/mapbox-gl-js/assets/indoor-3d-map.geojson'
},
'paint': {
// See the Mapbox Style Specification for details on data expressions.
// https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions

// Get the fill-extrusion-color from the source 'color' property.
'fill-extrusion-color': ['get', 'color'],

// Get fill-extrusion-height from the source 'height' property.
'fill-extrusion-height': ['get', 'height'],

// Get fill-extrusion-base from the source 'base_height' property.
'fill-extrusion-base': ['get', 'base_height'],

// Make extrusions slightly opaque for see through indoor walls.
'fill-extrusion-opacity': 1
}
    })
    })
  }
  resize() {
    //alert(window.innerWidth);
    this.setState({
      viewport: {
        width: window.innerWidth,
        height: window.innerHeight
      }
    }, () => {
      //  console.log(this.state.viewport.width)
    });
  }

  render() {
    var markerLat = this.state.markerLat;
    var markerlng = this.state.markerlng
    return (
      <div>
        <ReactMapGL
          {...this.state.viewport}
          ref={(reactMap) => this.reactMap = reactMap}
          // transitionDuration={1000}
          //transitionInterpolator={new LinearInterpolator()}
          mapboxApiAccessToken={'pk.eyJ1IjoiemVlc2hhbjU1NzI2MTUiLCJhIjoiY2syaWoyNDAxMGdvbTNscGJobDZwcHAxMCJ9.tcB8DX8W-7XMY7nzX9ilvw'}
          onViewportChange={(viewport) => {
            // console.log('viewprt' , viewport)
            this.setState({
              viewport: viewport
            }, () => {
              // console.log(this.state.viewport.width)
            });
          }}
        >
          <div style={{ position: 'absolute', right: 10, top: 10 }}>
            <FullscreenControl container={document.querySelector('body')} />
          </div>
          {/*  <GeolocateControl 
          positionOptions={{enableHighAccuracy: true}}
          trackUserLocation={true}
          showUserLocation={true}
        />
  <Marker 
        latitude={this.state.markerLat} 
        longitude={this.state.markerlng} 
        offsetLeft={-20} offsetTop={-10}
        draggable ={true}

      onDragEnd={(x)=>{
        console.log('event ',x)
        this.setState({
          markerLat:x.lngLat[0],
          markerlng:x.lngLat[1]
        })
      }}
        >
  <p style={{
    background:'#000',
    fontSize:20,
    padding:5,
    alignSelf:'center',
    fontWeight:'bold',
    borderRadius:'50%',
    lineHeight:.5
  }}><span>&nbsp;</span></p>
        </Marker>

        {this.state.showPopup && <Popup
          latitude={this.state.markerLat}
          longitude={this.state.markerlng}
          closeButton={true}
          closeOnClick={false}
          onClose={() => this.setState({showPopup: false})}
          anchor="bottom"
          tipSize={10} >
          <div>You are here</div>
        </Popup>*/}


          <div style={{ position: 'absolute', bottom: 30 }}>
            <NavigationControl />
          </div>
        </ReactMapGL>
      </div>
    );
  }
}
于 2019-11-08T05:23:44.697 回答