You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native调用默认导航选位置等地图功能实现咨询

React Native 地图功能实现方案

1. 获取用户当前位置(主动触发)

因为你仅在用户主动操作时存储位置,用expo-location单次获取即可,先申请权限再获取坐标:

import * as Location from 'expo-location';

const getUserCurrentLocation = async () => {
  // 请求前台位置权限
  const { status } = await Location.requestForegroundPermissionsAsync();
  if (status !== 'granted') {
    alert('需要开启位置权限才能获取当前位置');
    return null;
  }

  // 获取高精度单次位置
  const location = await Location.getCurrentPositionAsync({
    accuracy: Location.Accuracy.High,
  });
  
  return {
    latitude: location.coords.latitude,
    longitude: location.coords.longitude,
  };
};

// 用户点击"更新位置"按钮时调用
const handleUpdateLocation = async () => {
  const userLoc = await getUserCurrentLocation();
  if (userLoc) {
    // 此处调用后端接口将坐标存入数据库
    // await fetch('你的后端接口地址', {
    //   method: 'POST',
    //   body: JSON.stringify(userLoc),
    //   headers: { 'Content-Type': 'application/json' }
    // });
  }
};

2. 调用原生地图应用选择位置

直接用Linking构造平台专属链接,跳转原生地图应用:

import { Linking, Platform } from 'react-native';

const openNativeMapForSelection = async () => {
  let mapUrl;
  if (Platform.OS === 'ios') {
    // iOS 跳转自带地图,支持搜索选择位置
    mapUrl = 'maps://?q=选择目标位置';
  } else {
    // Android 跳转Google Maps(无则引导下载)
    mapUrl = 'geo:0,0?q=选择目标位置';
  }

  const isSupported = await Linking.canOpenURL(mapUrl);
  if (isSupported) {
    await Linking.openURL(mapUrl);
  } else {
    alert('未找到可用的地图应用');
  }
};

注:原生地图无法直接返回选择的坐标,若需获取用户选定位置,可在用户返回APP后再次调用getCurrentPositionAsync获取最新坐标。

3. 计算两点距离并展示

用Haversine公式本地计算经纬度间的直线距离,无需第三方API:

// 计算两点直线距离(单位:公里)
const calculateDistance = (lat1, lon1, lat2, lon2) => {
  const earthRadius = 6371; // 地球平均半径(公里)
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 
    Math.sin(dLon/2) * Math.sin(dLon/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  const distance = earthRadius * c;
  return distance.toFixed(2); // 保留两位小数
};

// 使用示例
const userLoc = { latitude: 31.2304, longitude: 121.4737 }; // 用户当前位置
const targetLoc = { latitude: 31.1704, longitude: 121.4337 }; // 后端返回的目标位置

const distance = calculateDistance(
  userLoc.latitude,
  userLoc.longitude,
  targetLoc.latitude,
  targetLoc.longitude
);

// 页面中可展示:`距离目标地点 ${distance} 公里`

4. 打开原生导航应用前往目标位置

同样用Linking构造导航链接,区分平台实现:

import { Linking, Platform } from 'react-native';

const openNativeNavigation = (targetLat, targetLon, targetName) => {
  let navUrl;
  if (Platform.OS === 'ios') {
    // iOS 自带地图导航(从当前位置出发)
    navUrl = `maps://?saddr=Current%20Location&daddr=${targetLat},${targetLon}&directionsmode=driving`;
  } else {
    // Android Google Maps导航
    navUrl = `google.navigation:q=${targetLat},${targetLon}&mode=d`;
  }

  Linking.openURL(navUrl).catch(err => alert('无法打开导航应用'));
};

// 使用示例:传入后端返回的目标坐标
openNativeNavigation(31.1704, 121.4337, 'Britney的位置');

关于Google Geocode的说明

你当前的需求不需要使用Google Geocode,因为所有操作都是基于经纬度直接完成,无需地址与坐标的互转。

如果后续需要添加地址/坐标互转功能,可选用以下替代方案:

  • Expo Location 内置方法:用geocodeAsync(地址转坐标)和reverseGeocodeAsync(坐标转地址),底层调用原生系统服务,无需额外API密钥:
    import * as Location from 'expo-location';
    
    // 坐标转地址
    const getAddressFromCoords = async (lat, lon) => {
      const result = await Location.reverseGeocodeAsync({ latitude: lat, longitude: lon });
      return result[0]?.formattedAddress;
    };
    
  • OpenStreetMap Nominatim:免费开源,适合非商业项目,请求限制宽松;
  • Mapbox Geocoding API:有免费额度,全球地址覆盖全面,功能稳定。

内容的提问来源于stack exchange,提问作者johnny68

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:37:23