5
votes

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.

1
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/… - Jono
Otherwise you could try getMapBoundaries and manually check which of your markers are within those boundaries. - Jono
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 wrong - mKane
Yeah you're probably right in that case. Not ideal solution - Jono
Will try get a code snippet for you and try getMarkersFrames out - Jono

1 Answers

2
votes

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.