简体   繁体   中英

How to centre a MapView on a user's current location when the Map Screen is opened? React Native Expo

How to centre the map to show a user's current location when the map screen is opened? By following the expo documentation, it should be achieved with Expo Location API? However, the documentation is unclear. I took part of the code from expo Location documentation and implemented it in my Map Screen. So, how should I integrate it in MapView to execute the getCurrentPositionAsync method and centre the map accordingly when the map screen is opened?

import React, { useContext, useState, useEffect } from "react";
import MapView from "react-native-maps";
import styled from "styled-components";
import { Searchbar } from "react-native-paper";
import { View } from "react-native";

import * as Location from 'expo-location';

const Map = styled(MapView)`
height: 100%;
width: 100%;
`;

const SearchBarContainer= styled(View)`
padding: ${(props) => props.theme.space[3]};
position: absolute;
z-index: 999;
top: 20px;
width: 100%;
`;

export const MapScreen = ({navigation}) => {

  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);

  useEffect(() => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }

      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);
    })();
  }, []);

  return (
    <> 
    <SearchBarContainer>
      <Searchbar placeholder="location"/>
    </SearchBarContainer>
    <Map showsUserLocation={true}>
      
    </Map>
    </>
  );};

You have to pass user coordinates provided by Expo location api into your map component inorder to show you current Location, also you need to set an initial state for your location with (lat,lng) as follows, and if you seek higher acuracy i would recommend to these option to your getCurrentPositionAsync

        export const MapScreen = ({navigation}) => {
        
          const [location, setLocation] = useState({
          latitude: 37.78825,
          longitude: -122.4324,
    });
          const [errorMsg, setErrorMsg] = useState(null);
          useEffect(() => {
            (async () => {
              let { status } = await Location.requestForegroundPermissionsAsync();
              if (status !== 'granted') {
                setErrorMsg('Permission to access location was denied');
                return;
              }
        
              let location = await Location.getCurrentPositionAsync({
                accuracy: Location.Accuracy.Balanced,
                enableHighAccuracy: true,
                timeInterval: 5
});
              setLocation(location);
            })();
          }, []);
        
          return (
            <> 
            <SearchBarContainer>
              <Searchbar placeholder="location"/>
            </SearchBarContainer>
            <Map region={location} showsUserLocation={true}/>
            </>
          );};

I have been struggling with this issue for a couple of days as well and I find it very weird that even though the expo MapView can show your own location on the map, it cannot return your own coördinates.

Despite that, the problem can be fixed with the following solution.

  1. Install Expo-location

expo install expo-location

  1. Import it
import * as Location from 'expo-location'
  1. Create a state
const [location, setLocation] = useState({});
  1. Create a useEffect function which retrieves your coördinates asynchronous (retrieving the location at button press may take up to 5-10 seconds which is ridiculously late regarding the user experience)
useEffect(() => {
        (async () => {
            let { status } = await Location.requestForegroundPermissionsAsync();
            if (status !== 'granted') {
                return;
            }

            let location = await Location.getCurrentPositionAsync({
                accuracy: Location.Accuracy.Balanced,
                enableHighAccuracy: true,
                timeInterval: 5
            });
            setLocation(location);
        })();
    }, []);
  1. Your Mapview needs to have a reference to talk to the MapView and set it's coördinates.
<MapView ref={mapRef}>.... </MapView>
const mapRef = React.createRef();
  1. And in the end create a function which can be triggered by a custom button to center to the users location.
const goToMyLocation = async () => {
        mapRef.current.animateCamera({center: {"latitude":location.coords.latitude, "longitude": location.coords.longitude}});
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM