arn*_*bro 6 mapbox reactjs mapbox-gl react-native mapbox-gl-js
使用react-native-mapbox-gl/maps,当aSymbolLayer动态添加到a时ShapeSource,似乎没有显示,或者ShapeSource没有更新。
这是要重现的示例:根据CustomIcon示例,我用下面的代码替换了代码。要重现,只需执行示例,复制粘贴代码来代替CustomIcon.js示例中的现有代码。
import React from 'react';
import { View, Text } from 'react-native';
import MapboxGL from '@react-native-mapbox-gl/maps';
import sheet from '../styles/sheet';
import BaseExamplePropTypes from './common/BaseExamplePropTypes';
import Page from './common/Page';
import Bubble from './common/Bubble';
const styles = {
icon: {
iconAllowOverlap: true,
},
view: {
width: 60,
height: 60,
borderColor: 'black',
borderWidth: 1,
alignItems: 'center',
justifyContent: 'center'
},
text: {
fontSize: 50
}
};
const customIcons = ['', '', '', '', '']
class CustomIcon extends React.Component {
constructor(props) {
super(props);
this.state = {
featureCollection: {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
coordinates: [-73.970895, 40.723279],
type: 'Point'
},
id: 1,
properties: {
customIcon: customIcons[0]
}
}]
},
};
this.onPress = this.onPress.bind(this);
this.onSourceLayerPress = this.onSourceLayerPress.bind(this);
}
onPress(e) {
const feature = {
type: 'Feature',
geometry: e.geometry,
id: Date.now(),
properties: {
customIcon: customIcons[this.state.featureCollection.features.length]
}
};
this.setState(({ featureCollection }) => ({
featureCollection: {
type: 'FeatureCollection',
features: [
...featureCollection.features,
feature
]
}
}));
}
onSourceLayerPress(e) {
const feature = e.nativeEvent.payload;
console.log('You pressed a layer here is your feature', feature); // eslint-disable-line
}
render() {
return (
<Page {...this.props}>
<MapboxGL.MapView
ref={c => (this._map = c)}
onPress={this.onPress}
style={sheet.matchParent}
>
<MapboxGL.Camera
zoomLevel={9}
centerCoordinate={[-73.970895, 40.723279]}
/>
<MapboxGL.ShapeSource
id="symbolLocationSource"
hitbox={{width: 20, height: 20}}
onPress={this.onSourceLayerPress}
shape={this.state.featureCollection}
>
{this.state.featureCollection.features.map((feature, ind) => (
<MapboxGL.SymbolLayer
id={"symbolLocationSymbols" + feature.id}
key={feature.id}
filter={['==', 'customIcon', customIcons[ind]]}
minZoomLevel={1}
style={styles.icon}
>
<View style={styles.view}>
<Text style={styles.text}>
{feature.properties.customIcon}
</Text>
</View>
</MapboxGL.SymbolLayer>
))}
</MapboxGL.ShapeSource>
</MapboxGL.MapView>
<Bubble>
<Text>Tap to add an icon</Text>
</Bubble>
</Page>
);
}
}
export default CustomIcon;
Run Code Online (Sandbox Code Playgroud)
我们可以看到,点击地图会改变状态,添加一个要素,但不会在地图上显示该要素。我们怎样才能ShapeSource动态更新呢?
关于该主题的整个讨论都在这里:https://github.com/react-native-mapbox-gl/maps/issues/248
简而言之:我想使用动态 SVG SymbolLayer(例如,这样我可以更改颜色),但这是不可能的:提供 SymbolLayer任何子组件都不是正确的方法。
Images我们需要并行使用ShapeSource和SymbolLayer,因为Images可以动态更新。
这是一个代码示例:
import React from 'react';
import MapboxGL from '@react-native-mapbox-gl/maps';
const myImages = {
'image-1': 'path/to/image-1',
'image-2': 'path/to/image-2'
}
const createFeature = ({
showPin,
icon = 'image-1', // as long as any added feature has an icon belonging to the static myImages, it works.
coordinates,
id
}) => ({
// https://github.com/react-native-mapbox-gl/maps/blob/master/docs/ShapeSource.md -> shapeSource prop
// https://geojson.org
// this has a geoJSON shape
type: 'Feature',
id,
properties: {
showPin,
icon
},
geometry: {
type: 'Point',
coordinates,
}
})
class MyMarkers extends React.Component {
state = {
featureCollection: MapboxGL.geoUtils.makeFeatureCollection(),
}
componentDidMount() {
this.updateFeatures()
}
componentDidUpdate(prevProps) {
// update features based on any criteria
if (conditionOnProps(prevProps, this.props)) this.updateFeatures()
}
updateFeatures() {
const featureCollection = MapboxGL.geoUtils.makeFeatureCollection()
for (let feature of this.props.features) {
MapboxGL.geoUtils.addToFeatureCollection(
featureCollection,
createFeature(feature)
)
}
this.setState({ featureCollection });
}
onPress = (e) => {
const feature = e.nativeEvent.payload;
this.props.doAnythingWithPressedFeature(feature);
}
render() {
return (
<>
<MapboxGL.Images images={myImages} />
<MapboxGL.ShapeSource
id='markersShape'
shape={this.props.featureCollection}
onPress={this.onPress}
>
<MapboxGL.SymbolLayer
id='markersSymbol'
filter={['==', 'showPin', true]}
style={{
iconAllowOverlap: true,
iconImage: ['get', 'icon'],
}}
/>
</MapboxGL.ShapeSource>
</>
)
}
}
export default MyMarkers;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4266 次 |
| 最近记录: |