Can I add a GeoJSON line like they do in the (mapbox-gl-js documentation) using react-map-gl?
Asked Answered
I

3

12

I'm trying to add a GeoJSON line to show car direction between a point A and a point B ( like they have in the official documentation of mapbox-gl-js (https://www.mapbox.com/mapbox-gl-js/example/geojson-line/)

But the docs of react-map-gl doesn't talk about that at all.

How can I achieve something similar to this using https://uber.github.io/react-map-gl/#/Documentation/introduction/introduction :

here's my code so far :

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

screen shot 2017-12-20 at 5 55 10 pm

Inaptitude answered 21/12, 2017 at 2:8 Comment(0)
K
10

You can get the mapbox-gl map object once the component mounts, then you can work with it directly. Try something like this:

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

React Refs: https://reactjs.org/docs/refs-and-the-dom.html

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

Kaliningrad answered 29/12, 2017 at 19:41 Comment(0)
C
5

Applicable for those who are using react-map-gl Version 5.0 onwards

As of October 2019, react-map-gl supports Layer and Source components, which is meant to allow developers to render Mapbox layers on the Mapbox canvas without the need to call getMap() to expose the underlying native Mapbox API.

You may refer to the original Mapbox Source and Layer documentations for the full specifications for the valid values for the Layer and Source props.

This is how the Source and Layer components can be used together with the code you have provided to generatea GeoJSON line on your map.

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>
  );
 }
}
Clementius answered 12/2, 2020 at 2:38 Comment(3)
Hello I am trying to run your code, would you mind give one example of polylineGeoJSON ?Turtle
Can you provide an exemple of what look like polylineGeoJSON and source='my-data' please ?Georgy
TypeScript definition of polylineGeoJSON: github.com/DefinitelyTyped/DefinitelyTyped/blob/…Pilocarpine
U
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>
    );
  }
}
Unskillful answered 8/11, 2019 at 5:23 Comment(1)
A code-only answer is not high quality. While this code may be useful, you can improve it by saying why it works, how it works, when it should be used, and what its limitations are. Please edit your answer to include explanation and link to relevant documentation.Whap

© 2022 - 2024 — McMap. All rights reserved.