Как я могу использовать Esri Arcgis Map в проекте ReactJs?

Я пытаюсь использовать карту Esri. Чтобы включить карту в мой проект, вот что я нашел:

require([
    "esri/map",
    "esri/dijit/Search",
    "esri/dijit/LocateButton",
    "esri/geometry/Point",
    "esri/symbols/SimpleFillSymbol",
    "esri/symbols/SimpleMarkerSymbol",
    "esri/symbols/SimpleLineSymbol",

Но нет никакой папки esri или пакета npm. Поэтому я запутался здесь. Как esri импортируется в проект?

3 ответа

Используйте esri-loader для загрузки необходимых модулей esri. Это базовая карта рендеринга компонента.

import React, { Component } from 'react';
import { loadModules } from 'esri-loader';

const options = {
  url: 'https://js.arcgis.com/4.6/'
};

const styles =  {
  container: {
    height: '100vh',
    width: '100vw'
  },
  mapDiv: {
    padding: 0,
    margin: 0,
    height: '100%',
    width: '100%'
  },
}

class BaseMap extends Component {

  constructor(props) {
    super(props);
    this.state = {
      status: 'loading'
    }
  }

  componentDidMount() {
    loadModules(['esri/Map', 'esri/views/MapView'], options)
      .then(([Map, MapView]) => {
        const map = new Map({ basemap: "streets" });
        const view = new MapView({
          container: "viewDiv",
          map,
          zoom: 15,
          center: [78.4867, 17.3850]
        });
        view.then(() => {
          this.setState({
            map,
            view,
            status: 'loaded'
          });
        });
      })

  }

  renderMap() {
    if(this.state.status === 'loading') {
      return <div>loading</div>;
    }
  }

  render() {

    return(
          <div style={styles.container}>
            <div id='viewDiv' style={ styles.mapDiv } >
              {this.renderMap()}
            </div>
          </div>
    )
  }
}

export default BaseMap;

Это делает базовую карту, но не реагирует. Если я удаляю div вокруг view div или если я даю высоту и ширину внешнего div (окружающего viewDiv) как относительные ({ height: '100%', width: '100%'}), карта не рендерится, Понятия не имею почему. Будем благодарны за любые предложения, чтобы сделать его отзывчивым.

Альтернативный способ, описанный выше, показан в примере esri-реагировать-маршрутизатор. Это приложение использует библиотеку esri-loader для отложенной загрузки ArcGIS API только в тех компонентах / маршрутах, где это необходимо. Пример:

Сначала установите библиотеку esri-loader:

npm install esri-loader --save

Затем импортируйте функции esri-loader в любой реагирующий модуль:

import * as esriLoader from 'esri-loader'

Затем лениво загрузите ArcGIS API:

componentDidMount () {
  if (!esriLoader.isLoaded()) {
    // lazy load the arcgis api
    const options = {
      // use a specific version instead of latest 4.x
      url: '//js.arcgis.com/3.18compact/'
    }
    esriLoader.bootstrap((err) => {
      if (err) {
        console.error(err)
      }
      // now that the arcgis api has loaded, we can create the map
      this._createMap()
    }, options)
  } else {
    // arcgis api is already loaded, just create the map
    this._createMap()
  }
},

Затем загрузите и модули ArcGIS API (Dojo), необходимые для создания карты:

_createMap () {
  // get item id from route params or use default
  const itemId = this.props.params.itemId || '8e42e164d4174da09f61fe0d3f206641'
  // require the map class
  esriLoader.dojoRequire(['esri/arcgis/utils'], (arcgisUtils) => {
    // create a map at a DOM node in this component
    arcgisUtils.createMap(itemId, this.refs.map)
    .then((response) => {
      // hide the loading indicator
      // and show the map title
      // NOTE: this will trigger a rerender
      this.setState({
        mapLoaded: true,
        item: response.itemInfo.item
      })
    })
  })
}

Преимущество использования esri-loader по сравнению с подходом, показанным выше, заключается в том, что вам не нужно использовать загрузчик Dojo и набор инструментов для загрузки и сборки всего приложения. Вы можете использовать набор инструментов React по вашему выбору (веб-пакет и т. Д.).

Этот пост в блоге объясняет, как работает этот подход, и сравнивает его с другими (похожими) подходами, используемыми в приложениях, таких как esri-redux.

Вам не нужно импортировать esri api, как для ReactJS. Поскольку файл реакции будет, наконец, скомпилирован в файл js, вам нужно написать части esri как есть и смешать часть ReactJS для обработки узла dom, что является основной целью ReactJS.

Образец по ссылкам ниже здесь

define([  
   'react',  
   'esri/toolbars/draw',  
   'esri/geometry/geometryEngine',  
   'dojo/topic',  
   'dojo/on',  
   'helpers/NumFormatter'  
 ], function(  
   React,  
   Draw, geomEngine,  
   topic, on,  
   format  
 ) {  
  var fixed = format(3);  
  var DrawToolWidget = React.createClass({  
    getInitialState: function() {  
       return {  
         startPoint: null,  
         btnText: 'Draw Line',  
         distance: 0,  
         x: 0,  
         y: 0  
       };  
     },  
     componentDidMount: function() {  
      this.draw = new Draw(this.props.map);  
      this.handler = this.draw.on('draw-end', this.onDrawEnd);  
      this.subscriber = topic.subscribe(  
        'map-mouse-move', this.mapCoordsUpdate  
       );  
     },  
     componentWillUnMount: function() {  
       this.handler.remove();  
       this.subscriber.remove();  
     },  
     onDrawEnd: function(e) {  
       this.draw.deactivate();  
       this.setState({  
       startPoint: null,  
         btnText: 'Draw Line'  
       });  
    },  
    mapCoordsUpdate: function(data) {  
      this.setState(data);  
      // not sure I like this conditional check  
      if (this.state.startPoint) {  
        this.updateDistance(data);  
      }  
    },  
    updateDistance: function(endPoint) {  
      var distance = geomEngine.distance(this.state.startPoint, endPoint);  
      this.setState({ distance: distance });  
    },  
    drawLine: function() {  
      this.setState({ btnText: 'Drawing...' });  
      this.draw.activate(Draw.POLYLINE);  
      on.once(this.props.map, 'click', function(e) {  
         this.setState({ startPoint: e.mapPoint });  
         // soo hacky, but Draw.LINE interaction is odd to use  
        on.once(this.props.map, 'click', function() {  
          this.onDrawEnd();  
        }.bind(this));  
      }.bind(this))  
    },  
    render: function() {  
      return (  
        <div className='well'>  
          <button className='btn btn-primary' onClick={this.drawLine}>  
            {this.state.btnText}  
          </button>  
          <hr />  
          <p>  
             <label>Distance: {fixed(this.state.distance)}</label>  
          </p>  
        </div>  
       );  
     }  
  });  
  return DrawToolWidget;  
});  

Ниже приведены ссылки, где вы можете найти информацию в деталях.

http://odoe.net/blog/esrijs-reactjs/

https://geonet.esri.com/people/odoe/blog/2015/04/01/esrijs-with-reactjs-updated

Другие вопросы по тегам