Как я могу использовать 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