react-esri-leaflet
v2.0.1
Published
react components for esri-leaflet
Downloads
14,629
Maintainers
Readme
Requirements
Requires react^18, react-leaflet^4, and esri-leaflet^3.
Installation
To use these components you must install certain dependencies yourself:
npm i react react-dom leaflet react-leaflet esri-leaflet
with all of your underlying packages installed,
npm i react-esri-leaflet
Components
react-esri-leaflet offers the following components:
Native Components:
- <BasemapLayer />
- <FeatureLayer />
- <TiledMapLayer />
- <ImageMapLayer />
- <DynamicMapLayer />
Plugins:
- <EsriLeafletGeoSearch />
- <HeatmapLayer />
- <ClusterLayer />
- <VectorBasemapLayer />
- <VectorTileLayer />
Use
Import any of the components and use them in a <MapContainer />
:
import React from "react";
import { MapContainer } from "react-leaflet";
import { BasemapLayer, FeatureLayer } from "react-esri-leaflet";
import EsriLeafletGeoSearch from "react-esri-leaflet/plugins/GeoSearch";
const Map = () => {
return (
<MapContainer zoom={zoom} center={center}>
<BasemapLayer name="DarkGray" />
<FeatureLayer url={featureLayerURL} />
<EsriLeafletGeoSearch useMapBounds={false} position="topright" />
</MapContainer>
);
};
Using esri-leaflet Plugins
If you want to use any of the esri-leaflet plugins, you must first install their underlying packages and any associated css. Each plugin has its own requirements, which you can find in the esri-leaflet docs. Plugins are imported not from the main package, but from the /plugins/<PluginName>
subfolder, like this:
import EsriLeafletGeoSearch from "react-esri-leaflet/plugins/EsriLeafletGeoSearch";
EsriLeafletGeoSearch
You must first install the underlying esri-leaflet-geocoder
:
npm i esri-leaflet-geocoder
You will also need to include the css in your html header, as explained in the esri-leaflet-geocoder documentation. You can then use the <EsriLeafletGeoSearch />
component. See the Use section for examples.
HeatmapLayer
First install the underlying dependencies:
npm i leaflet.heat esri-leaflet-heatmap
You can then use the <HeatmapLayer />
component.
ClusterLayer
First install the underlying dependencies:
npm i leaflet.markercluster esri-leaflet-cluster
You can then use the <ClusterLayer />
component.
VectorBasemapLayer and VectorTileLayer
First install the underlying dependencies:
npm i esri-leaflet-vector
You can then use the <VectorBasemapLayer />
and <VectorTileLater />
components.
Props
All react-esri-leaflet components inherit their props from the underlying esri-leaflet component options. You can find the options for each esri-leaflet layer in their documentation. However, certain options are available or necessary for react-esri-leaflet components:
<EsriLeafletGeoSearch
providers={{
arcgisOnlineProvider: {
token: your_token,
label: "ArcGIS Online Results",
maxResults: 10
},
featureLayerProvider: {
url: feature_layer_url,
label: 'Featurelayer Provider Results'
bufferRadius: 5000
}
}}
/>;
Events
Events can be accessed in the same way as described in the react-leaflet documentation, using the eventHandlers
prop. All events are inherited from their underlying esri-leaflet component. For example:
<FeatureLayer
url={'featureLayerURL'}
eventHandlers={{
loading: () => console.log('featurelayer loading'),
load: () => console.log('featurelayer loaded')
}} />
<EsriLeafletGeoSearch
position="topright"
eventHandlers={{
requeststart: () => console.log('Started request...'),
requestend: () => console.log('Ended request...'),
results: (r) => console.log(r)
}} />
Methods
Many of the methods on esri-leaflet layers can be handled through react props. For example, a <FeatureLayer />
accepts the where
prop, which applies a server side filter on the features in the layer. Using vanilla esri-leaflet, the getWhere
and setWhere
methods are available on the layer. With react-esri-leaflet, you can manage the setting and getting of many layer properties with react:
const Map = () => {
const [minPopulation, setMinpopulation] = useState(1000);
return (
<MapContainer zoom={zoom} center={center}>
<FeatureLayer
where={`Population > '${minPopulation}'`}
url={featureLayerURL}
/>
<button onClick={() => setMinpopulation(5000)}>
Set min population to 5000
</button>
</MapContainer>
);
};
In this way, you can 'get' or 'set' your prop by accessing the state variable used to control it, or setting that state variable.
Other methods on esri-leaflet components are less related to presentational logic, and more related to analysis or interacting with the root dataset. For example, calling query
or eachFeature
on a featureLayer will not affect the presentation logic. In this sense, all methods not directly affecting the presentational logic of your layers (read: everything but the setters and getters) should be accessed by getting a ref
to the underlying esri-leaflet layer. For example:
const Map = () => {
const featureLayerRef = useRef();
const queryFeature = () => {
featureLayerRef.current
.query()
.within(latlngbounds)
.where("Direction = 'WEST'")
.run(function (error, featureCollection) {
console.log(featureCollection);
});
};
return (
<MapContainer zoom={zoom} center={center}>
<FeatureLayer ref={featureLayerRef} url={featureLayerURL} />
<button onClick={queryFeature}>Run a Query</button>
</MapContainer>
);
};
Using Authenticated Layers
Any esri layers that require authentication accept a token
prop. A react-esri-leaflet layer that requires a token
should be conditionally rendered based on the availability of the token. For example, a typical token getting function is as follows:
async function authenticateEsri(client_id, client_secret, expiration) {
const authservice = "https://www.arcgis.com/sharing/rest/oauth2/token";
const url = `${authservice}?client_id=${client_id}&client_secret=${client_secret}&grant_type=client_credentials&expiration=${expiration}`;
let token;
await fetch(url, {
method: "POST"
})
.then((res) => res.json())
.then((res) => {
token = res.access_token;
})
.catch((error) => {
console.error(error);
});
return token;
}
On component mount, you can call this function, save the token to state, and conditionally render the layer based on the state variable:
const Map = (props) => {
const [token, setToken] = useState(null);
useEffect(() => {
async function getToken() {
const token = await authenticateEsri();
setToken(token);
}
getToken();
}, []);
return (
<MapContainer zoom center>
{token && (
<>
<ImageMapLayer
token={token}
url="https://landscape6.arcgis.com/arcgis/rest/services/World_Land_Cover_30m_BaseVue_2013/ImageServer"
/>
<VectorBasemapLayer name="ArcGIS:Streets" token={token} />
</>
)}
</MapContainer>
);
};
Alternatives
You don't necesarily need an esri-leaflet component to bring esri layers into leaflet. You can use an esri service url with a react-leaflet TileLayer
. For example:
<TileLayer url="https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}">
is equivalent to
<Basemap name="Oceans">
Esri also offers react-arcgis, which is a react wrapper for the ArcGIS Javascript API, but that takes you outside the realm of leaflet.
License
MIT License