Search code examples
iosreact-nativereact-native-mapsapple-maps

Apple Map zoom out/in based on Radius change by user in React-native-maps


I have a requirement to zoom out/in Apple maps based on radius change by the user in react-native-maps.

I have used a react-native-slider to change the radius on the map.based on slider value change radius drawn on the map will be changed. Now with this, Map also should be zoomed out/in based on radius. How can I achieve this in the best possible way?

Below is my code:

<MapView
          minZoomLevel={this.state.minZoomLevel}
          maxZoomLevel={this.state.maxZoomLevel}
          moveOnMarkerPress={true}
          //provider={PROVIDER_GOOGLE}
          style={styles.mapView}
          showsUserLocation={true}
          followsUserLocation={false}
          region={this.state.region}
          loadingEnabled={true}
        >
          <Marker coordinate={this.state.markers.latlng} />
          <Circle
            center={this.state.markers.latlng}
            radius={userRadius}
            strokeColor={colors.black}
          />
        </MapView>

calculateMapZoomLevel = () => {
    const { userRadius } = this.state;
    var zoomLevel = 11;

    var compRadius = userRadius + userRadius / 2;
    var scale = compRadius / 500;
    zoomLevel = Math.round(16 - Math.log(scale) / Math.log(2));

    return zoomLevel;
  };

handleSliderValueChange = (value) => {
    const rondedRadius = Math.round(value * 1609);
    const sliderValue = Math.round(value);
    const radiusInMiles = sliderValue;

    this.setState({
      userRadius: rondedRadius,
      sliderValue,
      radiusInMiles,
    });
    const zoomLevel = this.calculateMapZoomLevel();
    this.setState({
      maxZoomLevel: zoomLevel,
    });
  };

Solution

  • You can actually have latitudeData and longitudeData properties under region for the MapView:

    const [delta, setDelta] = useState(some_initial_value);
    
    region={{
          latitude: xx,
          longitude: xx,
          latitudeDelta: delta,
          longitudeDelta: delta
        }}
    

    What I'd do is create a function that calculates the delta given the userRadius. As you update the delta, the map will zoom in/out.

    Another option might be using animateToRegion() for a smoother transition, but personally I've never used it.