Fazendo mapas com React

Neste artigo, você pode encontrar uma visão geral sobre diferentes bibliotecas de mapeamento React. Muitos de nossos projetos são sobre visualizações de dados e mapas. Ao longo de dois anos, temos construído a maioria de nossos aplicativos com React. No início, apenas usamos Leaflet dentro de um componente React. Agora estamos usando principalmente React Leaflet que é um wrapper React para Leaflet.

Todos os exemplos incluídos neste artigo podem ser encontrados no repositório do GitHub make-maps-with-react se você quiser brincar um pouco.

Suporte para WebGL

Antes de você começar a desenvolver o seu mapa, você deve decidir se precisa ou não de suporte WebGL. Você deve considerar o uso de WebGL se você tem um monte de recursos a serem exibidos ao mesmo tempo, digamos marcadores de 10k, por exemplo. Para um mapa normal, uma biblioteca sem suporte WebGL será suficiente.

React Leaflet

Como mencionado anteriormente, essa é a biblioteca que mais usamos. Leaflet é uma biblioteca de mapeamento muito sólida e esse é o wrapper do React. Ele é ativamente mantido e já usa a versão Leaflet 1.0.0.

A API é bastante simples se você estiver acostumado com a API Leaflet. Os componentes diferentes estão bem documentados e já existem alguns bons plugins de terceiros. Para ver o mapa, você também precisa adicionar Leaflet.css. Estamos importando isso em nosso arquivo main.styl.

Instalação:

yarn add react-leaflet leaflet react react-dom

Componente React:

Você pode encontrar o exemplo completo no repositório GitHub.

class ReactLeafletMap extends PureComponent {      render() {      // create an array with marker components      const LeafletMarkers = markers.map(marker => (        <Marker position={marker.latlng} key={`marker_${marker.name}`}>          <Popup>            <span>{marker.name}</span>          </Popup>        </Marker>      ));        return (        <div className="map">          <Map center={mapConfig.center} zoom={mapConfig.zoom} className="map__reactleaflet">            <TileLayer              url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"              attribution='© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attribution">CARTO</a>'            />            {LeafletMarkers}          </Map>        </div>      );    }  }

Mapas Pigeon

Essa é uma biblioteca de mapeamento muito especial porque ela não tem dependências externas. Por enquanto, você pode apenas exibir sobreposições e marcadores em um mapa base, então isso pode ser útil para um mapa de localizador muito simples. Até agora, não há pop-ups para os marcadores implementados, então você precisaria encontrar sua própria lógica. Para obter mais informações, consulte a página do projeto.

Instalação

yarn add pigeon-maps pigeon-marker

Componente React

Você pode encontrar o exemplo completo no repositório GitHub.

class PigeonMaps extends PureComponent {      onMarkerClick(evt) {      console.log(evt.payload);    }      render() {      // create an array with marker components      const PigeonMarkers = markers.map(marker => (        <Marker key={`marker_${marker.name}`} anchor={marker.latlng} payload={marker.name} onClick={this.onMarkerClick} />      ));        return (        <div className="map">          <Map            width={window.innerWidth}            height={600}            defaultCenter={mapConfig.center}            defaultZoom={mapConfig.zoom}            provider={getProvider}          >            {PigeonMarkers}          </Map>        </div>      );    }  }

Google Map React

A biblioteca do Google Map React envolve o seu mapa do Google como um componente React. O legal sobre isso é que ele permite que você renderize qualquer componente React no mapa, o que lhe dá a oportunidade de criar facilmente marcadores personalizados. Outra característica útil é que os componentes fornecidos pela API do Google Maps (por exemplo, Camadas de Tráfego ou Trânsito ou uma caixa de pesquisa) também podem ser incluídos no mapa.

Certifique-se de incluir a chave da API do Google Maps. A configuração é muito simples:

Instalação:

yarn add google-map-react react

Componente React:

O exemplo completo está disponível no repositório GitHub.

const CustomMarker = ({ text }) => <div className="custom-marker"><p>{text}</p></div>;    class GoogleMapReactComponent extends PureComponent {    render() {      const GoogleMapsMarkers = markers.map(marker => (        <CustomMarker          key={`marker_${marker.name}`}          lat={marker.latlng[0]}          lng={marker.latlng[1]}          text={marker.name}        />      ));        return (        <GoogleMapReact          defaultCenter={mapConfig.center}          defaultZoom={mapConfig.zoom}          layerTypes={['TrafficLayer', 'TransitLayer']}          bootstrapURLKeys={{            key: CONFIG.GOOGLE_MAPS_API_KEY,            language: 'de'          }}        >          {GoogleMapsMarkers}        </GoogleMapReact>      );    }  }

React MapGL

Se você precisar de suporte para WebGL em seu projeto, deve considerar o uso de React MapGL. Ele é um wrapper react para Mapbox GL que usa o WebGL para fazer mapas a partir de tiles vetoriais.

A biblioteca tem uma API pequena e algumas sobreposições de amostra como scatterplot de dispersão. Outras sobreposições úteis são fornecidas, por exemplo, por deck.gl. Como exemplo, criamos um mapa simples usando a sobreposição scatterplot. Na próxima seção, você pode encontrar uma versão que usa deck.gl.

A configuração é um pouco complicada e os documentos parecem ser um pouco confusos porque o readme do repositório e os documentos são diferentes. Observe que é necessário instalar immutable e fornecer uma chave Mapbox API para começar.

Instalação:

yarn add react-map-gl immutable react react-dom

Componente React:

Você pode encontrar o exemplo completo no repositório GitHub.

class ReactMapGL extends PureComponent {    constructor(props) {      super(props);        this.state = {        viewport: {          width: window.innerWidth,          height: 600,          latitude: mapConfig.center[0],          longitude: mapConfig.center[1],          zoom: mapConfig.zoom,          isDragging: false,          startDragLngLat: mapConfig.center,          pitch: 50,          bearing: 0        }      };        this.onChangeViewport = this.onChangeViewport.bind(this);    }      onChangeViewport(viewport) {      this.setState({        viewport: { ...this.state.viewport, ...viewport }      });    }      render() {      const { viewport } = this.state;      return (        <div className="reactmapgl">          <MapGL            {...viewport}            mapboxApiAccessToken={CONFIG.MAPBOX_ACCESS_TOKEN}            perspectiveEnabled            onChangeViewport={this.onChangeViewport}          >            <ScatterplotOverlay              {...viewport}              locations={locations}              dotRadius={2}              globalOpacity={1}              compositeOperation="screen"              dotFill="#1FBAD6"              renderWhileDragging            />          </MapGL>        </div>      );    }  }

React MapGL com Deck.GL

Deck.GL foi desenvolvido pela equipe do Uber e é um framework que fornece belas sobreposições para mapas renderizados com Mapbox GL. No site do projeto, você encontrará um tutorial que mostra como implementar diferentes camadas em seu mapa. O exemplo abaixo usa o GeoJsonLayer e o ScreenGridLayer (com 50.000 pontos).

Instalação:

yarn add react-map-gl immutable react react-dom deck.gl luma.gl

Componente React:

Você pode encontrar o exemplo completo no repositório GitHub.

class ReactMapGLDeckGL extends PureComponent {    constructor(props) {      super(props);        this.state = {        viewport: {          width: window.innerWidth,          height: 600,          latitude: mapConfig.center[0],          longitude: mapConfig.center[1],          zoom: mapConfig.zoom,          isDragging: false,          startDragLngLat: mapConfig.center,          pitch: 50,          bearing: 0        },        geojson: null      };        requestJson('data/berlin_bezirke.json', (error, response) => {        if (!error) {          this.setState({ geojson: response });        }      });          this.onChangeViewport = this.onChangeViewport.bind(this);    }      onChangeViewport(viewport) {      this.setState({        viewport: { ...this.state.viewport, ...viewport }      });    }      initialize(gl) {      gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE_MINUS_DST_ALPHA, gl.ONE);      gl.blendEquation(gl.FUNC_ADD);    }      render() {      const { viewport, geojson } = this.state;        const geosjsonLayer = new GeoJsonLayer({        id: 'geojson-layer',        data: geojson,        filled: false,        stroked: true,        lineWidthMinPixels: 1,        lineWidthScale: 1,        getLineColor: d => [175, 175, 175]      });        const screenGridLayer = new ScreenGridLayer({        id: 'screen-grid-layer',        data: scatterPlotData,        cellSizePixels: 10,        minColor: [43, 140, 190, 0],        maxColor: [43, 140, 190, 255]      });        return (        <div className="reactmapgldeckgl">          <MapGL            {...viewport}            mapboxApiAccessToken={CONFIG.MAPBOX_ACCESS_TOKEN}            mapStyle="mapbox://styles/mapbox/dark-v9"            perspectiveEnabled            onChangeViewport={this.onChangeViewport}          >            <DeckGL              {...viewport}              layers={[geosjsonLayer, screenGridLayer]}              onWebGLInitialized={this.initialize}            />          </MapGL>        </div>      );    }  }

***

Christine Wiederer faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://blog.webkid.io/making-maps-with-react/.

You may also like...