反应本地地图箱动态添加的PointAnnotations放错了位置

时间:2018-09-17 15:57:24

标签: react-native mapbox mapbox-gl

我目前正在开发一个React Native应用(版本0.55.2)和mapbox / react-native(版本6.1.2-beta2) 我遇到的情况是,一些注释最初显示在地图渲染上,然后在用户缩放时加载更多注释。 第一个注释显示在正确的位置。

但是,添加新注释时,所有注释均停留在左上角。

在他们的文档https://github.com/mapbox/react-native-mapbox-gl/blob/master/docs/MapView.md之后,我试图在加载或渲染地图时调用该函数。我什至尝试了setTimeout。注释始终显示在左上方的地图上。

有什么想法我应该如何处理? 谢谢!
class map extends React.Component {
  constructor(props) {
    super(props);
    this.getMapVisibleBounds = getMapVisibleBounds.bind(this);
    this.state = {
      ...INIT_MAP_STATE
    };
  }
  //compo lifecyle
  componentDidUpdate(prevProps, prevState) {


    if (this.state.userPosition.longitude !== prevState.userPosition.longitude) {
      this.setBounds();//first annotations. works fine
    }
    if (this.state.zoomLevel !== prevState.zoomLevel) {
     this.setBounds(); //update annotations. doesn't work
    }


  }


render()=>{
const { quest, checkpoint } = this.props;
    const { selectedIndex } = this.state;
    return (
      <View style={styles.container}>
        <Mapbox.MapView
          styleURL={MAP_STYLE}
          zoomLevel={this.state.zoomLevel}
          centerCoordinate={[this.state.userPosition.longitude, 
this.state.userPosition.latitude]}
          style={styles.mapWrap}
        >
          {this.renderMap(checkpoint, "checkpoint")}
        </Mapbox.MapView>

      </View>
    );
}
setBounds = () => {
this.getMapVisibleBounds(this.map)
  .catch(err => {
    console.error(err);
  })
  .then(bounds => {
    this._setMapBounds(bounds);// set state bounds
    return this.props.onLoadQuest(bounds); //api call
  });
 }
}

//注释呈现

class checkPoint extends Component {
  constructor(props) {
    super(props);
  }



  renderAnnotations = (data, id) => {
    const uniqKey = `checkpoint_${id}`;
    return (
      <Mapbox.PointAnnotation key={uniqKey} id={uniqKey} coordinate={[data[0], data[1]]}>
        <TouchableWithoutFeedback onPress={idx => this.onSelect(id)}>
          <Image source={checkPointImg} style={styles.selfAvatar} resizeMode="contain" />
        </TouchableWithoutFeedback>
      </Mapbox.PointAnnotation>
    );
  };

  render() {
    if (!this.props.checkpoint || isEmpty(this.props.checkpoint)) {
      return null;
    }
    const { hits } = this.props.checkpoint;
    if (!Array.isArray(hits)) {
      return [];
    }

    return hits.map((c, idx) =>
      this.renderAnnotations(c._source.location.coordinates, c._source.id)
    );
  }
}

2 个答案:

答案 0 :(得分:0)

“ PointAnnotation”是旧版,请尝试将您的点作为对象传递。进行交换后,您的地图渲染速度将更快。像这样的东西。

<MapboxGL.MapView
    centerCoordinate={[ userLocation.longitude, userLocation.latitude ]}
    pitchEnabled={false}
    rotateEnabled={false}
    style={{ flex: 1 }}
    showUserLocation={true}
    styleURL={'your_style_url'}
    userTrackingMode={MapboxGL.UserTrackingModes.MGLUserTrackingModeFollow}
    zoomLevel={10}
>

    <MapboxGL.ShapeSource
        key='icon'
        id='icon'
        onPress={this._onMarkerPress}
        shape={{type: "FeatureCollection", features: featuresObject }}
        type='geojson'
        images={images}
    >
        <MapboxGL.SymbolLayer 
            id='icon'
            style={layerStyles.icon}
        />
    </MapboxGL.ShapeSource>
</MapboxGL.MapView>

其中的“ featuresObject”看起来像这样...

        let featuresObject = []

        annotation.forEach((annot, index) => {
            let lat = annot.latitude
            let lng = annot.longitude


            featuresObject[index] = {
                type: "Feature",
                geometry: {
                    type: "Point",
                    coordinates: [lng, lat]
                },
                properties: {
                    exampleProperty: propertyValue,
                }
            }
        })

Example for polygon layer

Example with custom icon

答案 1 :(得分:0)

const layerStyles = Mapbox.StyleSheet.create({
  icon: {
    iconImage: "{icon}",
    iconAllowOverlap: true,
    iconSize: 0.5,
    iconIgnorePlacement: true
  }
});
const mapboxIcon = props => {
  return (
    <Mapbox.ShapeSource
      shape={makeMapBoxGeoJson(props.datum, props.mapKey, props.name)}
      key={`${props.name}_key_${props.mapKey}`}
      id={`${props.name}_${props.mapKey}`}
      images={getIcon(props.name)}
      onPress={idx => (props.isActive ? props.onSelectId(props.mapKey) : null)}
    >
      <Mapbox.SymbolLayer
        id={`${props.mapKey}_pointlayer`}
        style={[layerStyles.icon, { iconSize: props.iconSize ? props.iconSize : 0.5 }]}
      />
    </Mapbox.ShapeSource>
  );
};