reactjs - deck.gl GeoJsonLayer:点击时更新特征颜色
问题描述
我正在使用 deck.gl GeoJsonLayer 在地图上显示区域。通过一个事件,我能够使这些区域可选。我正在努力解决的问题是在单击后更改特征选择中的特征颜色。
这是渲染层功能(改编自此处)
_renderLayers(props) {
const { geofeats } = props;
return [
new GeoJsonLayer({
id: 'geojson',
data: geofeats,
opacity: 0.8,
stroked: true,
filled: true,
extruded: true,
wireframe: true,
getElevation: f => 10000,
getFillColor: f =>
{
if(f.properties.selected)
{
return [200, 200, 100];
} else return [200, 100, 150];
},
getLineColor: [255, 255, 255],
pickable: true,
onHover: this._onHover,
onClick: this._onClick
})
];
}
问题是,当我通过 setState() 更新特征集合中特征的选择状态时,即使数据中表示状态更改,渲染也不会更新。
这就是我传递“geofeats”对象的方式:
render() {
const {features} = this.state;
const {mapStyle = 'mapbox://styles/mapbox/light-v9'} = this.props;
return (
<DeckGL
layers={this._renderLayers({geofeats: features})}
effects={this._effects}
initialViewState={INITIAL_VIEW_STATE}
controller={true}
>
<StaticMap
reuseMaps
mapStyle={mapStyle}
preventStyleDiffing={true}
mapboxApiAccessToken={MAPBOX_TOKEN}
/>
{this._renderTooltip}
</DeckGL>
);
}
我通过 setState 而不是通过 props 尝试了它 - 但结果是一样的。特征集合被移交给 GeoJsonLayer 但从未更新。
有人可以告诉我,我做错了什么吗?
更新:带有错误再现的要点示例:https ://gist.github.com/jaronimoe/efdbb58b3f52c2aac63362a921802cfe
解决方案
你的问题是两方面的。
首先,您永远不会为每个功能分配唯一的 ID,这最终意味着当您悬停一个项目时,每个功能都将被分配给选中。这是因为在 setFeatureSelected 中您正在比较undefined == undefined
aka ( currentID == selectedId
)。顺便说一句,您应该默认为三等式
其次,您需要告诉您GeoJsonLayer
如何更新颜色。这些是您需要进行的更改:
function setFeatureSelected(features, selfeat) {
let selectedID = selfeat.properties.id;
for (let i = 0; i < features.features.length; i++) {
let currentID = features.features[i].properties.id;
if (selectedID === currentID) {
features.features[i].properties.selected = true;
} else {
// Make sure to update the others to be false, so that way only one is ever selected
features.features[i].properties.selected = false;
}
}
return features;
}
然后你想更新initFeatureSelected
以实际注入 ID。现在我只使用数组中的索引,但如果你愿意,你可以使用更明确的东西
function initFeatureSelected(features) {
for (let i = 0; i < features.features.length; i++) {
features.features[i].properties.selected = false;
// Track each feature individually with a unique ID.
features.features[i].properties.id = i;
}
return features;
}
您需要的最后一部分是告诉GeoJsonLayer
您有新值来重新计算getFillColor
函数。这是通过updateTriggers
传递确定颜色是否应该改变的事物的值来完成的。在您的情况下,哪个是您的功能的选定 ID
new GeoJsonLayer({
id: 'geojson',
data,
opacity: 0.8,
stroked: false,
filled: true,
extruded: true,
wireframe: true,
getElevation: 50, //Math.sqrt(f.properties.valuePerSqm) * 10,
getFillColor: d => d.properties.selected ? [100, 105, 155] : [55, 205, 155], //COLOR_SCALE(f.properties.growth),
getLineColor: [255, 255, 255],
updateTriggers: {
getFillColor: [
this.state.hoveredObject
? this.state.hoveredObject.properties.id
: null
]
},
pickable: true,
onHover: this._onHover
})
推荐阅读
- smartcard - Mifare desfire apdu 命令
- jquery - 未捕获的 SyntaxError:构建后令牌无效或意外
- python - requests.exceptions.ConnectionError Python
- python - 如何通过控制扬声器通道的音量使用 python 创建环绕效果?
- bash - 在 Windows Bash 中包含 PowerShell 命令
- node.js - 导演 NodeJs 的 CSS 选择器
- python-3.x - 如何使用 Telethon 通过链接发送消息,然后启动机器人?
- encoding - 粘贴从 PDF 复制的文本?
- javascript - 将 Javascript 对象数组缩减为字符串
- javascript - 从 PugJS 调用节点 js 函数?