如何解决如何在 React Leaflet 中使用 onEachCountry 刷新 GeoJSON choropleth?
我是 JS、React 和 Leaflet 的新手,但我认为到目前为止我已经做到了。 我有一个正确显示咖啡信息的 choropleth。不幸的是,当我更改 onEachCountry 中的数据时,更改不会反映出来,因为这不是一个状态。也许我可以以某种方式使 onEachCountry 循环中的每一层成为一个状态?或者我可以在 JSX 中调用一些简单的刷新选项吗?
我试过对 onEachCountry 使用 useEffect,我也试过控制台日志并且数据正在更新,只是没有显示。其他传单挂钩在更改时似乎更容易更新。
非常感谢任何帮助。
import React,{ useState,useEffect } from "react";
import { MapContainer,GeoJSON,TileLayer } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import "./ChoroMap.css";
import NavBarCountry from "../NavBarCountry";
// from Choro
const ChoroMap = ({ countries,coffees,onChangeLegend }) => {
const [selectedStat,setSelectedStat] = useState("Producers");
useEffect(() => {
onEachCountry();
},[selectedStat]);
const onProducersClick = function () {
onChangeLegend("Producers");
setSelectedStat("Producers");
};
const onExportersClick = function () {
onChangeLegend("Exporters");
setSelectedStat("Exporters");
};
const onFarmsClick = function () {
onChangeLegend("Farms");
setSelectedStat("Farms");
};
function legend(stat,comparisonArray) {
if (stat >= comparisonArray[0]) {
return "#741f1f";
} else if (stat >= comparisonArray[1] && stat < comparisonArray[0]) {
return "#9c2929";
} else if (stat >= comparisonArray[2] && stat < comparisonArray[1]) {
return "#d75e5e";
} else if (stat >= comparisonArray[3] && stat < comparisonArray[2]) {
return "#c57979";
} else if (stat >= 0 && stat < comparisonArray[3]) {
return "#f1b1b1";
}
}
function stripNumber(numberString) {
const number = Number(numberString.replace(/[^\d.-]/g,""));
return number;
}
const onEachCountry = (country,layer) => {
if (country) {
// defaults
layer.options.fillOpacity = 1;
layer.options.weight = 0.6;
layer.options.color = "white";
// country name from JSON
const name = country.properties.ADMIN;
const countryObj = coffees.find((coffee) => coffee.country ===
name);
if (countryObj != null) {
if ((selectedStat == "Producers")) {
layer.bindPopup(`${name}
${countryObj.production_volume}`);
const productionVol =
stripNumber(countryObj.production_volume);
const foundColor = legend(
productionVol,[10_000_000,5_000_000,2_000_000,500_000]
);
layer.options.fillColor = foundColor;
}
else if ((selectedStat == "Exporters")) {
layer.bindPopup(`${name} ${countryObj.export_volume}`);
const exportVol = stripNumber(countryObj.export_volume);
const foundColor = legend(
exportVol,500_000]
);
layer.options.fillColor = foundColor;
}
else if ((selectedStat == "Farms")) {
layer.bindPopup(`${name} ${countryObj.number_of_farms}`);
const numberOfFarms =
stripNumber(countryObj.number_of_farms);
const foundColor = legend(
numberOfFarms,[5,10,15,20]
);
layer.options.fillColor = foundColor;
}
console.log('onEachCountry',layer.options.fillColor)
}
}
};
return (
<div>
<NavBarCountry
onProducersClick={onProducersClick}
onExportersClick={onExportersClick}
onFarmsClick={onFarmsClick}
/>
<MapContainer
className="map"
attributionControl={false}
zoom={2.5}
center={[10,10]}
>
<GeoJSON data={countries} onEachFeature={onEachCountry}/>
</MapContainer>
</div>
);
};
export default ChoroMap;
解决方法
我试着理解你的问题,如果你只是想在地图中刷新你的 geoJSON 样式,而不是使用 choropleth,你最好试试这个。它更灵活,可以像 choropleth 一样动态
首先,我建议您使用类组件而不是使用函数并将您的 react-leaflet 版本更改为 2.7.0。这是因为我使用那个版本并且它的工作非常好。而且就我在 react-leaflet 的经验而言,没有太多讨论是谈论新版本,这就是为什么我建议您使用 2.7.0
数据
这将帮助您设置将在 WebGIS 中显示的 geojson 文件
<GeoJSON
data={this.state.isMyGeoJSON}
/>
onEachFeature
用于设置每次对图层或特征进行操作时将调用的所有函数。我建议你在某个地方把它做成箭头函数,因为以后有很多函数可以在 onEachFeature 上调用。举个例子
<GeoJSON
onEachFeature={this.onEachFeature}
/>
将此 onEachFeature 函数放在 render() 之前{
onEachFeature = (feature,layer) => {
console.log(fetaure) //array of feature
console.log(layer) //array of layer
console.log(layer.feature) //array of feature
//you must remember,feature is part of layer,so it's up to you how to call it later
layer.on({
mouseover : this.onMouseOver,mouseout : this.onMouseOut,mouseclick : this.onMouseClick
})
//i will show you example of onMouseOver
onMouseOver = (event) => {
event.target.setStyle({
color : "yellow"
})
render(){
...
正如您在那里看到的,有一个示例如何更改颜色,但是如果您想单击某个按钮并更改地图的颜色,该怎么办。这简单!首先,我再次建议您将默认样式放在 onEachFeature 中。为什么?因为我通常使用我的 GeoJSON 样式作为我的动态样式,让我举个例子
//add this inside your onEachFeature for example
onEachFeature = (feature,layer) => {
layer.options.color : "blue" //change line all layer line color to blue,this work beacuse onEachFeature is loop function that are calling all layer one by one,so this thing will help you to change all your layer line color options to blue
//still confused? try to call console.log(layer.options) for experiment
}
该图层选项可以由您的 layer.onMouse 更改。但是如果我们想用地图外的按钮来改变它呢?或任何功能?你可以试试这个!
风格
这里应该是您放置默认样式的地方,但在本示例中,让我告诉您如何使您的默认样式动态化。如果我记得,有人在某个论坛上这样说,“如果你想改变它的风格,GeoJSON 中的样式就可以与函数调用一起使用”。然后我创建了这样的实验。
<GeoJSON
style={this.stateMapTheme}
/>
在我的 this.state 里面我是这样写的
this.state = {
mapTheme : this.firstStyle
}
让我们看看,我们要改变这个fillColor,因为我们已经在onEachFeature里面设置了默认颜色为蓝色,所以让我们做两个例子
//example of using data with if else
firstStyle(feature){
if (data < 20){
return{
fillColor : "red"
}
} else {
return{
fillColor: "660000" //dark red
}
secondStyle(feature){
return{
fillColor : "green"
}
}
在地图之外的某个地方创建 div
<div onClick={()=> {this.setState({mapTheme : this.secondStyle}) }}>green</div>
<div onClick={()=> {this.setState({mapTheme : this.firstStyle}) }}>red</div>
如果您想了解有关 react-leaflet 的更多信息,可以查看此信息,这将帮助您根据数据更改颜色 Medium React-Leaft by Deddy Setiawan
react-leaflet 示例的结果可以检查 here
如果您仍然无法理解我的解决方案,请让我从评论部分帮助您
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。