How to add markers / annotations programatically with mapbox and react native

mapbox marker
react native-mapbox
mapbox react marker
mapbox add marker android
react-map-gl marker
mapbox icons
mapbox numbered markers
react-native-mapbox-gl example

I'm new to react native and cannot find any documentation on how to add markers / annotations programatically to the map using mapbox.

We are using geofire query, which triggers when a point of interest is withing range.

Inside the trigger I want to insert the marker.

All the documentation I found about it is this: https://www.mapbox.com/help/first-steps-react-native-sdk/ which adds the marker during initialization and render.

Here is my code so far

    render () {
        const {navigate} = this.props.navigation;
        return (
          <View style ={{flex: 1, position: 'relative'}}>
            <Mapbox.MapView
                styleURL={Mapbox.StyleURL.Dark}
                zoomLevel={15}
                centerCoordinate={[11.256, 43.770]}
                ref={map => { this.map = map; }}
                style={{flex: 1}}>
                {this.renderAnnotations([11.256, 43.770])}
            </Mapbox.MapView>


            <View style={styles.menuMainContainer}>

                {this.state.menuStatus ? <Animatable.View style={styles.menuSubcontainer}  animation={"bounceIn"}>
                    <View style={{justifyContent: 'space-between', justifyContent: 'center', flex: 1, marginBottom: 50}}>
                      <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
                        <MenuOptions imageSource={Images.lightIcon} menuTag="trash" name="Basureros"/>
                        <MenuOptions imageSource={Images.lightIcon} menuTag="holes" name="Huecos"/>
                      </View>
                      <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
                        <MenuOptions imageSource={Images.lightIcon} menuTag="hydrants" name="Hidrantes"/>
                        <MenuOptions imageSource={Images.lightIcon} menuTag="parking" name="Estacionamiento"/>
                      </View>
                      <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
                        <MenuOptions imageSource={Images.lightIcon} menuTag="others" name="Otros"/>
                      </View>
                    </View>
                  </Animatable.View> : null
                }
            </View>

            <View style ={styles.bottomContainer}>

              <TouchableOpacity  style={styles.buttons}>
                <Text style={styles.buttonText}>Boton_1</Text>
              </TouchableOpacity>
              <TouchableOpacity onPress ={this._takePhotofromCamera} style={styles.buttons}>
                <Text style={styles.buttonText}>Agregar Reportes</Text>
              </TouchableOpacity>
              <TouchableOpacity style={styles.buttons} onPress = {() => this.toggleMenuStatus()}>
                <Text style={styles.buttonText}>Boton_3</Text>
              </TouchableOpacity>
            </View>

      </View>

        )
      }
    }


    renderAnnotations = (location) =>{
        console.log('entro renderan2')
        return(
          <Mapbox.PointAnnotation
            key='pointAnnotation'
            id='pointAnnotation'
            coordinate={location}>

            <View style={styles.annotationContainer}>
              <View style={styles.annotationFill} />
            </View>
            <Mapbox.Callout title='Look! An annotation!' />
          </Mapbox.PointAnnotation>


      )
      }

    this.state.geoQuery.on("key_entered", function(key, location, distance) {
           console.log(key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)");
this.renderAnnotations();
})

I'm getting: Error: this.renderAnnotations is not a function

I also tried copying the entire function inside this.state.geoQuery, no error, but markers are not showing either.

this.state.geoQuery.on("key_entered", function(key, location, distance) {
       console.log(key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)");
       return(
         <Mapbox.PointAnnotation
           key='pointAnnotation'
           id='pointAnnotation'
           coordinate={location}>

           <View style={styles.annotationContainer}>
             <View style={styles.annotationFill} />
           </View>
           <Mapbox.Callout title='Look! An annotation!' />
         </Mapbox.PointAnnotation>
     )});

Thanks

After chatting directly with Mapbox support, they told me PointAnnotation is legacy and should use ShapeSource and SymbolLayer instead, it have a LOT better performance. Here is how to do it:

    <Mapbox.MapView
                key='mainmap'
                textureMode={true}
                pitch={60}
                ref={(c) => this._map = c}
                onPress={this.onPress}
                styleURL={Mapbox.StyleURL.Light}
                zoomLevel={17}
                maxZoomLevel={20}
                minZoomLevel={15}
                centerCoordinate={this.initCenterLocation()}
                style={{ flex: 1 }}
                showUserLocation={true}
                userTrackingMode={Mapbox.UserTrackingModes.FollowWithHeading}
            >
                <Mapbox.ShapeSource
                    id='exampleShapeSource'
                    shape={this.state.featureCollection}
                    onPress={(feature) => this.onShapeSourceLayer(feature)}
                    images={{ assets: ['pin', 'm1_marker', 'm2_marker', 'm3_marker', 'm4_marker'] }}>
                    <Mapbox.SymbolLayer id='exampleIconName' minZoomLevel={1} style={stylesIcon.icon} />
                </Mapbox.ShapeSource>
            </Mapbox.MapView>

Insert new annotations / points:

    this.setState({
            featureCollection: Mapbox.geoUtils.addToFeatureCollection(
                this.state.featureCollection,
                Mapbox.geoUtils.makeFeature({ type: 'Point', coordinates: location }, { icon: iconImage, key: key }),
            ),
        });

On annotation Press function:

onShapeSourceLayer(e) {

    const feature = e.nativeEvent.payload;

    this.setState({
        annotationKey: feature.properties.key
    }, function () {

        this.togglePostModal(true)
    });

}

Add markers to a map | Help, Mapbox offers several ways to add markers to a map. Use the MGLAnnotationView class if you need your annotations change dynamically or be animated. There are many different ways to style point data in Mapbox Studio, Mapbox GL JS, the Mapbox Maps SDKs for iOS and Android, and the Mapbox Static Images API.In this guide, we point you to example code and tutorials that illustrate how to add a few markers to a map across different platforms.

I user react-native-maps so I wouldn't know exactly but what you are asking it is exactly in the documentation: https://www.mapbox.com/help/first-steps-react-native-sdk/#add-an-annotation

Edit: Your error is coming here right?

 this.state.geoQuery.on("key_entered", function(key, location, distance) {
           console.log(key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)");
this.renderAnnotations();
})

If so, probably the issue is that "this" is out of scope from your function when it triggers.

Try this:

 this.state.geoQuery.on("key_entered", (key, location, distance) => {
           console.log(key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)");
this.renderAnnotations();
})

Adding markers and shapes | Maps SDK | iOS, Hello, According to the doc javascript/components/SymbolLayer.js StyleSheet. create({ symbol: { iconImage: icon, iconSize: 1, iconOffset: [0, -32], can have visible markers on a layer, with invisible annotations on top of them. (not like they are when you declare new layers in your mapbox style), and� As of the 7.0.0 release of the Mapbox Maps SDK for Android, much of the code on this page has been deprecated. To add icons, text, lines, or polygons to the map, use the Mapbox Annotation Plugin for Android. The Annotation Plugin simplifies annotations and provides additional flexibility for displaying data.

Simple :

constructor() {
   this.state = {
      myMarker: [0, 0]//intial 0
   };
}

<Mapbox.MapView key='mainmap'> 
    <Mapbox.PointAnnotation
       key="key1"
       id="id1"
       title="Test"
       coordinate={this.state.myMarker}>
    </Mapbox.PointAnnotation>
</Mapbox.MapVie>


update latitude and longitude : 
   updateMyMarker(data){
   this.setState({myMarker: [data.Lng, data.Lat]})
}

annotation vs SymbolLayer � Issue #825 � nitaliano/react-native , So a good idea would be to be able to programmatically bring to front the MarkerView when I tried to add some bringToFront / bringToBack to RNMGL MarkerView from '@react-native-mapbox-gl/maps'; const Marker = ({coordinate, id, @xseignard that is because we set zPosition on point annotations. Using many MGLAnnotationViews can cause slow performance, so if you need to add a large number of annotations, consider using more performant MGLStyleLayers instead, detailed below. In summary, using annotations provide a familiar interface to MapKit’s annotation implementation, with built-in dragging and selection support.

react-native-mapbox-gl/maps, The key to rendering MapBox markers in your React Native application is implementing In the article: “Getting Started with the Mapbox Maps SDK for React Native,” I covered the MapView is the return value of our renderAnnotations() method. Here, we create a for-loop, which iterates over the state.coordinates array. The Mapbox Annotation Plugin simplifies the way to set and adjust the visual properties of annotations on a Mapbox map. The Mapbox Maps SDK for Android provides developers with fine-grain control over the appearance and location of map annotations. In this context, "annotations" means circles, polygons, lines, text, and icons.

How To Show Points On A Mapbox Map With React Native, Currently, when I change dynamically width of annotation, the marker looks like it added pins don't render at all and app throws error while adding new pin. Bobby Sudekum of Mapbox fame is doing a really great job on his React Native Mapbox GL Module. react-native-mapbox-gl A Mapbox GL React Native module for creating custom maps Example MapboxGLMap: var map = React.createClass({ getInitialState: function() { return { mapLocation: { latitude: 0, longitude: 0 }, center: { latitude: 40.72345355209305, longitude: -73.99343490600586

react-native-mapbox-gl/Lobby, In this lesson we'll create a MapView with react-native-maps. We'll use the onPress function to add Markers to the map and then we'll use the custom map� Install React Native Mapbox with the following command: npm install @mapbox/react-native-mapbox-gl --save. If you’re using yarn, use the one given below: yarn add @mapbox/react-native-mapbox-gl. Now make some native changes to your project as the installation guide given in the following links: Android. iOS. That’s all need for Mapbox react

Comments
  • Hi Ricardo, could you post the full code, like what is iconImage, are you able to have different images for each points? Thanks
  • Ricardo can you answer this question stackoverflow.com/questions/55036420/…
  • When i call this.renderAnnotations i get "it's not a function" I'll update the post with the code
  • Im getting syntax error, I have no clue about this kind of syntaxis /App/Containers/MainScreen.js: Unexpected token, expected , (295:74) 293 | }); 294 | > 295 | this.state.geoQuery.on("key_entered", () => (key, location, distance){ { | ^ 296 | console.log(key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)"); 297 | this.renderAnnotations(); 298 | }})
  • My bad. Had a typo. See now.
  • Thanks for your quick reply, now it enters the function, however it is still not showing the marker, it behaves exactly like pasting the function code inside