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

如何在react-native-maps中绘制两个位置间的路径?

在react-native-maps中绘制两点间路径的解决方案

方法一:绘制直线路径(简单快速)

react-native-maps自带的Polyline组件可以直接在两个坐标点间绘制直线,适合不需要真实道路导航的场景。

实现步骤:

  1. 导入Polyline组件
    修改你的导入语句,添加Polyline:
import MapView, {Marker, Polyline} from 'react-native-maps';
  1. 在MapView中添加路径
    在现有Marker组件后插入Polyline,传入包含当前位置和目标位置的坐标数组:
<MapView style={styles.map} region={mapRegion}>
  <Marker coordinate={mapRegionNow} title='MarkerNow'/>
  <Marker coordinate={mapRegion} title='Marker'/>
  {/* 两点间直线路径 */}
  <Polyline
    coordinates={[
      {latitude: mapRegionNow.latitude, longitude: mapRegionNow.longitude},
      {latitude: mapRegion.latitude, longitude: mapRegion.longitude}
    ]}
    strokeWidth={3}    // 路径宽度
    strokeColor="#007AFF"  // 路径颜色,可自定义
  />
</MapView>
  1. 优化地图视野(可选)
    默认的mapRegion可能只显示目标位置,添加以下代码让两个点都处于地图视野内:
// 计算包含两个点的地图区域
const calculateMapRegion = (coords1, coords2) => {
  const minLat = Math.min(coords1.latitude, coords2.latitude);
  const maxLat = Math.max(coords1.latitude, coords2.latitude);
  const minLng = Math.min(coords1.longitude, coords2.longitude);
  const maxLng = Math.max(coords1.longitude, coords2.longitude);

  return {
    latitude: (minLat + maxLat) / 2,
    longitude: (minLng + maxLng) / 2,
    latitudeDelta: (maxLat - minLat) * 1.2, // 放大一点留边距
    longitudeDelta: (maxLng - minLng) * 1.2,
  };
};

// 当两个位置都获取到后更新地图区域
useEffect(() => {
  if (mapRegionNow.latitude !== 1.3483 && mapRegion.latitude !== 1.3483) {
    setMapRegion(calculateMapRegion(mapRegionNow, mapRegion));
  }
}, [mapRegionNow, mapRegion]);

方法二:绘制真实导航路径(贴合实际道路)

如果需要基于真实道路的导航路径,需要调用第三方地图API(如高德、谷歌)获取路线规划数据,再用Polyline绘制。

实现步骤:

  1. 调用路线规划API
    以高德地图为例,构造请求获取驾车/步行路线:
const [navigationPath, setNavigationPath] = useState([]);

const fetchNavigationPath = async () => {
  const origin = `${mapRegionNow.longitude},${mapRegionNow.latitude}`;
  const destination = `${mapRegion.longitude},${mapRegion.latitude}`;
  const apiKey = '你的高德API密钥'; // 需前往高德开发者平台申请

  try {
    const response = await fetch(
      `https://restapi.amap.com/v3/direction/driving?origin=${origin}&destination=${destination}&key=${apiKey}`
    );
    const data = await response.json();
    if (data.status === '1') {
      // 解析API返回的路径点
      const path = data.route.paths[0].steps.flatMap(step => 
        step.polyline.split(';').map(point => {
          const [lng, lat] = point.split(',');
          return {latitude: parseFloat(lat), longitude: parseFloat(lng)};
        })
      );
      setNavigationPath(path);
    }
  } catch (error) {
    console.error('获取路径失败:', error);
  }
};
  1. 绘制真实路径
    在MapView中添加基于API数据的Polyline:
{navigationPath.length > 0 && (
  <Polyline
    coordinates={navigationPath}
    strokeWidth={3}
    strokeColor="#007AFF"
  />
)}

完整修改后的代码示例

import { StyleSheet, Text, View, Dimensions, Button } from 'react-native'
import React , {useEffect, useState} from 'react'
import {ref, onValue} from 'firebase/database'
import {db} from '../firebase'
import MapView, {Marker, Polyline} from 'react-native-maps';
import * as Loc from 'expo-location';

const Location = ({route}) => {
  const paramKey = route.params.paramKey1
  console.log(paramKey)
  var lo, ke;
  const [todoDatak, setToDoDatak] = useState([])
  const [todoDatal, setToDoDatal] = useState([])
  const [mapRegion, setMapRegion] = useState({
    latitude: 1.3483,
    longitude: 103.6831,
    latitudeDelta: 0.005,
    longitudeDelta:0.0005,
  })
  const [mapRegionNow, setMapRegionNow] = useState({
    latitude: 1.3483,
    longitude: 103.6831,
    latitudeDelta: 0.005,
    longitudeDelta:0.0005,
  })
  const [navigationPath, setNavigationPath] = useState([]);

  const userLocation = async()=>{
    let { status } = await Loc.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        alert('获取位置权限失败');
        return;
      }
      let location = await Loc.getCurrentPositionAsync({enableHighAccuracy:true});
      setMapRegionNow({
          latitude:location.coords.latitude,
          longitude:location.coords.longitude,
          latitudeDelta:0.005,
          longitudeDelta:0.0005,
      });
      console.log(location.coords.latitude, location.coords.longitude)
  }

  // 计算包含两个点的地图区域
  const calculateMapRegion = (coords1, coords2) => {
    const minLat = Math.min(coords1.latitude, coords2.latitude);
    const maxLat = Math.max(coords1.latitude, coords2.latitude);
    const minLng = Math.min(coords1.longitude, coords2.longitude);
    const maxLng = Math.max(coords1.longitude, coords2.longitude);

    return {
      latitude: (minLat + maxLat) / 2,
      longitude: (minLng + maxLng) / 2,
      latitudeDelta: (maxLat - minLat) * 1.2,
      longitudeDelta: (maxLng - minLng) * 1.2,
    };
  };

  // 获取真实导航路径(以高德为例)
  const fetchNavigationPath = async () => {
    const origin = `${mapRegionNow.longitude},${mapRegionNow.latitude}`;
    const destination = `${mapRegion.longitude},${mapRegion.latitude}`;
    const apiKey = '你的高德API密钥'; // 替换为你的密钥

    try {
      const response = await fetch(
        `https://restapi.amap.com/v3/direction/driving?origin=${origin}&destination=${destination}&key=${apiKey}`
      );
      const data = await response.json();
      if (data.status === '1') {
        const path = data.route.paths[0].steps.flatMap(step => 
          step.polyline.split(';').map(point => {
            const [lng, lat] = point.split(',');
            return {latitude: parseFloat(lat), longitude: parseFloat(lng)};
          })
        );
        setNavigationPath(path);
      }
    } catch (error) {
      console.error('获取路径失败:', error);
    }
  };

  useEffect (() => {
    const starCountRef = ref(db, "food/" + paramKey);
    onValue(starCountRef, (snapshot) =>{
      ke = snapshot.key;
      setToDoDatak(ke)
      // 注意:这里需要补充从firebase获取目标位置经纬度的逻辑
      // 示例:const data = snapshot.val();
      // setMapRegion({
      //   latitude: data.latitude,
      //   longitude: data.longitude,
      //   latitudeDelta: 0.005,
      //   longitudeDelta:0.0005,
      // });
      setToDoDatal(lo)
    });
    userLocation();
  }, [])

  // 更新地图区域和获取路径
  useEffect(() => {
    if (mapRegionNow.latitude !== 1.3483 && mapRegion.latitude !== 1.3483) {
      setMapRegion(calculateMapRegion(mapRegionNow, mapRegion));
      // fetchNavigationPath(); // 需要真实路径时取消注释
    }
  }, [mapRegionNow, mapRegion])

  return (
    <View style = {styles.container}>
       <Text style = {styles.header}>Shop Name</Text>
       <Text style = {styles.text}>{todoDatak}</Text>
     
       <View style={styles.container}>
        <MapView style={styles.map} region={mapRegion}>
          <Marker coordinate={mapRegionNow} title='MarkerNow'/>
          <Marker coordinate={mapRegion} title='Marker'/>
          {/* 直线路径 */}
          <Polyline
            coordinates={[
              {latitude: mapRegionNow.latitude, longitude: mapRegionNow.longitude},
              {latitude: mapRegion.latitude, longitude: mapRegion.longitude}
            ]}
            strokeWidth={3}
            strokeColor="#007AFF"
          />
          {/* 真实导航路径,启用时取消注释 */}
          {/* {navigationPath.length > 0 && (
            <Polyline
              coordinates={navigationPath}
              strokeWidth={3}
              strokeColor="#007AFF"
            />
          )} */}
        </MapView>
        <Button title= 'Get Location' onPress={userLocation}/>
      </View> 
    </View>
  )
}

export default Location

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    fontSize: 20,
    fontWeight: 'bold',
    margin: 10,
  },
  text: {
    fontSize: 16,
    marginHorizontal: 10,
    marginBottom: 10,
  },
  map: {
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height * 0.7,
  },
})

提示:代码中firebase部分需要补充目标位置经纬度的获取逻辑,否则目标位置会一直是默认值。若使用真实导航路径,需替换为自己的地图API密钥。

内容的提问来源于stack exchange,提问作者L.Calvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:23:16