【问题标题】:Here map integration in react-native mobile app这里地图集成在 react-native 移动应用程序中
【发布时间】:2020-01-22 17:32:39
【问题描述】:

我正在尝试在 react-native 项目中实现 heremap api。虽然搜索得到了 https://www.npmjs.com/package/react-native-heremaps 。但是没有合适的文档可以使用这个库。我是反应原生的新手。请给我一些实施建议。

【问题讨论】:

  • 您想从这里使用什么?我曾经需要一个路由计算 API,我用 HERE 开发了它,所以如果你只需要在这里计算路由,然后在 react native 中显示它,我可以帮助你
  • 我想用heremap显示标记并绘制折线。你能帮我做这件事吗?
  • 好的,我给你写一个答案。

标签: react-native react-native-android here-api


【解决方案1】:

!如果您不使用 expo,请发表评论,我会稍微更改答案!

首先,您可能知道您需要在HERE Developer webiste 创建一个帐户。

创建帐户后,您必须创建一个项目(您可以免费获得免费增值计划,它有很多免费的请求,如果您需要更多,请升级)。之后,您需要在您的项目页面上为 REST 和 XYZ HUB API/CLI “生成应用程序”。这样,您将收到 APP ID 和 APP CODE。至此,HERE 开发者账号设置就完成了。

现在让我们跳到 React Native。

首先,您需要安装一个名为 react-native-maps 的 npm 包,我们将使用它来显示 HERE 提供的数据。可以看安装说明here

在此之后,假设您已经创建了一个将显示地图的组件。你需要导入这个:

import { Marker, Polyline } from 'react-native-maps'
import { MapView } from 'expo'

这样我们的地图就差不多准备好了。

在此示例中我将使用axios,但如果您愿意,您可以使用fetch 向 HERE 发出请求。

所以我们导入 axios(如果您从未使用过它,您可以了解更多关于它的信息here):

import axios from 'axios'

现在,您应该在某个州或某个地方准备好这两个位置的坐标,它应该看起来像这样:

constructor(props){
    super(props)
    this.state = {
        startingLocation: {
            latitude: "xx.x",
            longitude: "yy.y",
        },
        finishLocation: {
           latitude: "xx.x",
           longitude: "yy.y",
        }
    }
}

“xx.x”和“yy.y”是你想要的实际坐标。

因此,现在当您获得开始和结束位置的坐标时,您可以向 HERE API 项目发出请求。就这么简单(我从here得到这个api):

// I will create a function which will call this, you can call it whenever you want
_getRoute = () => {
    // we are using parseFloat() because HERE API expects a float
    let from_lat = parseFloat(this.state.startingLocation.latitude)
    let from_long = parseFloat(this.state.startingLocation.longitude)
    let to_lat = parseFloat(this.state.finishLocation.latitude)
    let to_long = parseFloat(this.state.finishLocation.longitude)
    // we will save all Polyline coordinates in this array
    let route_coordinates = []
    axios.get(`https://route.api.here.com/routing/7.2/calculateroute.json?app_id=PUT_YOUR_APP_ID_HERE&app_code=PUT_YOUR_APP_CODE_HERE&waypoint0=geo!${from_lat},${from_long}&waypoint1=geo!${to_lat},${to_long}&mode=fastest;bicycle;traffic:disabled&legAttributes=shape`).then(res => {
        // here we are getting all route coordinates from API response
        res.data.response.route[0].leg[0].shape.map(m => {
            // here we are getting latitude and longitude in seperate variables because HERE sends it together, but we
            // need it seperate for <Polyline/>
            let latlong = m.split(',');
            let latitude = parseFloat(latlong[0]);
            let longitude = parseFloat(latlong[1]);
            routeCoordinates.push({latitude: latitude, longitude: longitude});
        }
        this.setState({
            routeForMap: routeCoordinates,
            // here we can access route summary which will show us how long does it take to pass the route, distance etc.
            summary: res.data.response.route[0].summary,
            // NOTE just add this 'isLoading' field now, I'll explain it later
            isLoading: false,
        })
    }).catch(err => {
        console.log(err)
    })
}

注意这里有几件事需要注意。首先,您必须将 APP ID 和 APP CODE 替换为 HERE 项目中的实际 APP ID 和 APP CODE。 第二个注意,我在请求 URL 的末尾添加了&amp;legAttributes=shape,但它不在文档中。我把它放在那里是为了让折线坐标实际上具有正确的形状,如果你不放它,它只会响应道路转弯的坐标,并且折线会越过建筑物和东西,它看起来很糟糕。

好的。所以现在我们有了坐标来制作折线,让我们这样做。

<MapView>
  <Polyline coordinates={this.state.routeForMap} strokeWidth={7} strokeColor="red" geodesic={true}/>
  <Marker coordinate={{latitude: this.state.startingLocation.latitude, longitude: this.state.startingLocation.longitude}} title="Starting location"/>
  <Marker coordinate={{latitude: this.state.finishLocation.latitude, longitude: this.state.finishLocation.longitude}} title="Finishlocation"/>
</MapView>

说明: Polyline.coordinates 将映射我们提供的所有坐标并绘制一条折线。 strokeWidth 就是你想要的线条有多粗,而 strokeColor 显然是线条的颜色。

现在,您应该将region 添加到您的 MapView 组件,让它知道您想在地图上显示的初始区域是什么。所以我建议你做这样的事情:

在state中,定义一个region字段,使其与起始位置坐标相同,然后设置delta,让view更大一点。

// so in state just add this
region: {
  latitude: parseFloat("xx.x"),
  longitude: parseFloat("yy.y"),
  latitudeDelta: 0.0922,
  longitudeDelta: 0.0421,
}

现在,将 region={this.state.region} 添加到 MapView。

您现在就完成了,但让我们确保每次都能正常工作。您需要确保 HERE API 请求在地图呈现之前完成。我会这样做:

// in your state define field to control if loading is finished
isLoading: true,

现在,你可以在 React Native 提供的 componendDidMount() 生命周期函数中调用我们之前创建的函数 _getRoute()。像这样:

componentDidMount() {
  // when this function is finished, we will set isLoading state to false to let program know that API request has finished and now we can render the map
  this._getRoute()
}

所以最后一步是在你的 render() 函数中控制isLoading

render() {
  if(this.state.isLoading) {
    return (
      <Text>Loading...(you could also use <ActivityIndicator/> or what ever you want to show while loading the request)</Text>
    )
  } else {
    // just put everything we already did here + stuff you already have
  }
}

原来如此。我试图让它尽可能详细,以方便您和其他需要帮助的人。

如果有什么不清楚或不起作用或您需要更多帮助,请随时问我!我总是很乐意提供帮助:D

【讨论】:

  • 是否需要实现“react-native-maps”谷歌密钥?因为我不想使用谷歌地图或钥匙。我将如何在后台显示地图。
  • 您不需要 google 密钥,只需忽略它并向 HERE 发出请求,然后您将在地图视图上显示该数据。
  • 当我同时使用 expo 地图和 react-native 地图时,它给了我“试图注册两个具有相同名称 AIRMap 的视图”错误。为什么??
  • 您是否有 2 个来自“expo”和“react-native-maps”的相同进口?如果你能把你的导入贴在这里会更好。
  • 对不起,我很困惑。你为什么使用 react-native-maps?看起来 OP 想要使用 HEREMaps SDK。
猜你喜欢
  • 2021-06-13
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
  • 2017-03-13
  • 1970-01-01
相关资源
最近更新 更多