React native maps get visible markers
Asked Answered
S

1

7

On iOS when using map kit we are able to get the current annotations inside of the visible map rect. Here is a small snippet using swift

Array(myMap.annotations(in: myMap.visibleMapRect))

Is there any comparable method or callback in this library?

My basic use is to know when a user changed region (pinch to zoom etc) and to get an array of the current markers still visible.

Snatchy answered 7/7, 2019 at 23:38 Comment(11)
Haven't tried it but have you taken a look at getMarkersFrames method? Check here - github.com/react-native-community/react-native-maps/blob/master/…Pontificals
Otherwise you could try getMapBoundaries and manually check which of your markers are within those boundaries.Pontificals
Would you have a snippet of getMarkersFrames or a sample of how I would compute getMapBoundaries to the coordinates I have in markers? The latter seems like it may be very slow. If I have 6,000 pins, and having to iterate over them 1 by 1 every time a region is set. Maybe I'm wrongSnatchy
Yeah you're probably right in that case. Not ideal solutionPontificals
Will try get a code snippet for you and try getMarkersFrames outPontificals
Thank you. I appreciate it.Snatchy
@Pontificals Any luck on that snippet?Snatchy
Hey @mKane, this is the example from the library itself (github.com/react-native-community/react-native-maps/blob/master/…), I've tried it out on snack (snack.expo.io/@jonoh/playful-toffee) but it didn't log the markers as I assume you need a native deployment on an actual device (not through snack) to make it work. Hope it helps!Pontificals
As has been said before, this will only work with iOS though.Pontificals
Yes that is fine. I will run through it today. Thank you!Snatchy
My pleasure! Let me know if it works :)Pontificals
P
4

There is a getMarkersFrames function to do that, but it is iOS only, and that's why I never used one in my apps.

I solved the same problem by using the RBush library to store markers: https://github.com/mourner/rbush. It allows to easily select points in the selected region. And it does it fast by using an R-tree. Example:

getInitialState() {
    return {
        region: {
            latitude: 37.78825,
            longitude: -122.4324,
            latitudeDelta: 0.0922,
            longitudeDelta: 0.0421,
        },
    };
}

componentWillMount() {
    this.tree = new RBush();
    fetch().then((points) => {
        // RBush expects the point to have minX, maxX, minY, maxY
        // but it could be configured.
        this.tree.load(points);
    });
}

onRegionChangeComplete(region) {
    // Get points that are inside the region.
    visibleItems = this.tree.search({
        // Provide the coordinates of the south-west, north-east corners of the region.
        minX: region.longitude - region.longitudeDelta,
        minY: region.latitude - region.latitudeDelta,
        maxX: region.longitude + region.longitudeDelta,
        maxY: region.latitude + region.latitudeDelta
    });
    this.setState({ region, visibleItems });
}

render() {
    return (
        <MapView
            region={this.state.region}
            onRegionChangeComplete={this.onRegionChangeComplete}
        />
    );
}

My app uses the same approach except I do initial markers loading and search in redux and redux-saga.

If you doesn't need to show that many markers, you can use simpler approach by storing points in the array. Then on each region change loop through all of the places and select those that are inside the region.

Plump answered 10/7, 2019 at 20:19 Comment(6)
I will look into this. Im confused by the componentWillMount code. where does the fetch code come from?Snatchy
@Snatchy That's just an example of fetching data from the server. All of the points has to be loaded to the tree after you have received them.Plump
@Snatchy I already showed this in componentWillMount. In my example fetch() is a function from Fetch API, shown just as a generic example. Can you show how do you load your points, and what data your points have (latitude, longitude, something else)?Plump
ah ok so this.tree.load is what in takes my points. Ok I understand. Let me try my code with this. Are you able to provide an example of the getMarkersFrames for iOS so I can compare?Snatchy
@Snatchy I never tried getMarkersFrames because it is iOS only, but I have to implement both iOS and Android.Plump
ok thanks. I am definitely looking for an example of getMarkersFrames but thank youSnatchy

© 2022 - 2024 — McMap. All rights reserved.