如何在 react-native 中的 mapbox 地图上绘制导航线?

Posted

技术标签:

【中文标题】如何在 react-native 中的 mapbox 地图上绘制导航线?【英文标题】:How to draw a navigation line on a mapbox map in react-native? 【发布时间】:2020-10-26 15:44:58 【问题描述】:

我正在尝试使用 mapbox-sdk 从 npm 包中获取 react-native 的导航方向:

"@mapbox/mapbox-sdk": "^0.11.0"

为了渲染 mapbox-sdk 返回的方向,我使用了下面的 npm 包:

"@react-native-mapbox-gl/maps": "^8.1.0-rc.8",

我用于检索路线的代码:

import MapboxGL from '@react-native-mapbox-gl/maps'
// Mapbox SDK related package
import MapboxDirectionsFactory from '@mapbox/mapbox-sdk/services/directions'
import  lineString as makeLineString  from '@turf/helpers'
import GeoLocationService from '../../services/geolocation/GeoLocationService';
import GeoLocationCore from '@react-native-community/geolocation'

const accessToken = "ACESS_TOKEN_FROM_MAPBOX_API_DASHBOARD"
const directionsClient = MapboxDirectionsFactory(accessToken)


  constructor(props) 
    super(props);
    this.state = 
        longitude: 0,
        latitude: 0,
        orderLongitude: 0,
        orderLatitude: 0,
        route: null,
    ;
  

async componentDidMount() 
      
      const route = this.props

      // Lets say route.params contains the below object:
      //  "longitude": "33.981982", "latitude": "-6.851599"
      console.log("Params from other screen: ", route.params)

      MapboxGL.setAccessToken(accessToken)
      MapboxGL.setConnected(true);
      MapboxGL.setTelemetryEnabled(true);
      const permission = await MapboxGL.requestandroidLocationPermissions();

      let latitude, longitude;
      if(Platform.OS == "android") 
          GeoLocationService.requestLocationPermission().then(() => 
            GeoLocationCore.getCurrentPosition(
                info => 
                    const  coords  = info
    
                    latitude = coords.latitude
                    longitude = coords.longitude
                    
                    //this.setState(longitude: coords.longitude, latitude: coords.latitude)
                    this.setState(longitude: -6.873795, latitude: 33.990777, orderLongitude: route.params.longitude, orderLatitude: route.params.latitude)
                    console.log("your lon: ", longitude)
                    console.log("your lat", latitude)
                    this.getDirections([-6.873795, 33.990777], [route.params.longitude, route.params.latitude])

                ,
                error => console.log(error),
                
                    enableHighAccuracy: false,
                    //timeout: 2000,
                    maximumAge: 3600000
                
            )
        )
      
  

  getDirections = async (startLoc, destLoc) => 
      const reqOptions = 
        waypoints: [
          coordinates: startLoc,
          coordinates: destLoc,
        ],
        profile: 'driving',
        geometries: 'geojson',
      ;
      const res = await directionsClient.getDirections(reqOptions).send()
      //const route = makeLineString(res.body.routes[0].geometry.coordinates)
      const route = makeLineString(res.body.routes[0].geometry.coordinates)
      console.log("Route: ", JSON.stringify(route))
      this.setState(route: route)
      
  

我用于渲染 mapbox-sdk 获取的道路方向的代码:

  renderRoadDirections = () => 
    const  route  = this.state
    return route ? (
      <MapboxGL.ShapeSource id="routeSource" shape=route.geometry>
        <MapboxGL.LineLayer id="routeFill" aboveLayerID="customerAnnotation" style=lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84 />
      </MapboxGL.ShapeSource>
    ) : null;
  ;

我用于渲染地图和方向的代码:

render() 
   return (
       <View style= flex: 1 >
         <MapboxGL.MapView
                ref=(c) => this._map = c
                style=flex: 1, zIndex: -10
                styleURL=MapboxGL.StyleURL.Street
                zoomLevel=10
                showUserLocation=true
                userTrackingMode=1
                centerCoordinate=[this.state.longitude, this.state.latitude]
                logoEnabled=true
                >
                    this.renderRoadDirections()
            <MapboxGL.Camera
                zoomLevel=10
                centerCoordinate=[this.state.longitude, this.state.latitude]
                animationMode="flyTo"
                animationDuration=1200
            />
        </MapboxGL.MapView>
       </View>
    )

现在,当我尝试渲染 GeoJson 时,检索到的道路方向线未显示在地图上,所以我认为我的 GeoJson 可能有问题并从这里对其进行了测试,但它看起来不错:

https://geojsonlint.com/

我测试过并且看起来不错的 GeoJson:

"type":"Feature","properties":,"geometry":"type":"LineString","coordinates":[[-6.880611,33.9916],[-6.882194,33.990166],[-6.882439,33.99015],[-6.882492,33.990028],[-6.882405,33.98991],[-6.878006,33.990299],[-6.87153,33.990978],[-6.871386,33.990925],[-6.871235,33.991016],[-6.869793,33.991165],[-6.870523,33.990292]]

我想要实现的示例:

我的代码中可能有什么问题导致地图上没有显示道路方向线?

【问题讨论】:

嘿,如果你改为这个会发生什么? &lt;MapboxGL.ShapeSource id="routeSource" shape=route.geometry.coordinates&gt;? @flaky 我认为它需要一个形状对象,但我试过了,没有用。 【参考方案1】:

找到导致 &lt;LineLayer/&gt; 未在地图上显示的原因,从以下行中删除属性 aboveLayerID

<MapboxGL.LineLayer id="routeFill" aboveLayerID="customerAnnotation" style=lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84 /> 

这样就变成了:

<MapboxGL.LineLayer id="routeFill" style=lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84 />

结果:

【讨论】:

以上是关于如何在 react-native 中的 mapbox 地图上绘制导航线?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-native 项目中保存 info.plist 中的更改

如何使用给定的 nativeID 识别目标 c 中的视图(在 react-native 中给出)

如何在 react-native 中的 onPress 按钮上滚动顶部?

如何在reducer中专门使用redux来获取react-native中的API?

如何缩小 React-Native 地图

为啥我的代码不能在 web 中的 react-native 代码中运行