如何在 ReactJs 项目中使用 Esri Arcgis Map?

Posted

技术标签:

【中文标题】如何在 ReactJs 项目中使用 Esri Arcgis Map?【英文标题】:How can I use Esri Arcgis Map in ReactJs Project? 【发布时间】:2017-02-20 15:03:39 【问题描述】:

我正在尝试使用 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如何在项目中导入?

【问题讨论】:

【参考方案1】:

使用 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 周围的 div,或者如果我将外部 div(围绕 viewDiv)的高度和宽度作为相对值( height: '100%', width: '100%'),则地图不会呈现.不知道为什么。任何使其响应的建议将不胜感激。

【讨论】:

您能帮我在地图上显示与每个标记位置对应的弹出窗口或信息窗口吗? ***.com/questions/69630872/…【参考方案2】:

上述方法的另一种方法是esri-react-router-example 中演示的方法。该应用程序使用一个名为esri-loader 的库来延迟加载ArcGIS API,仅在需要它的组件/路由中。示例:

首先,安装 esri-loader 库:

npm install esri-loader --save

然后在任何react模块中导入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 工具链(webpack 等)。

此blog post 解释了此方法的工作原理,并将其与esri-redux 等应用程序中使用的其他(类似)方法进行了比较。

【讨论】:

仅供参考,您在使用 esri-loader 时不需要需要延迟加载 ArcGIS API。相反,您可以通过 index.html 中的脚本标签加载 ArcGIS API,例如 &lt;script src="//js.arcgis.com/3.18compact/"&gt;&lt;/script&gt;。在这种情况下,componentDidMount() 的上述代码将只是 this._createMap() 你能帮我在***.com/questions/69630872/…***.com/questions/69630872/…这里点击标记位置显示弹出窗口或信息窗口【参考方案3】:

您不需要像 ReactJS 那样导入 esri api。由于 react 文件最终会编译为 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

【讨论】:

以上是关于如何在 ReactJs 项目中使用 Esri Arcgis Map?的主要内容,如果未能解决你的问题,请参考以下文章

如何在ASP.NET MVC ReactJS项目中使用“import”?

如何在reactjs中切换项目数组

在 ReactJS 中删除项目,使用 useState 和 useContext

Xamarin效果第十七篇之AR GIS

如何在 ReactJS 中预览视频

如何在 reactjs 中使用单个 ListItem 映射路由?