react-native应用集成地理逆编码

一、背景

最近,在项目中需要集成定位功能,在网上搜集资料之后,决定采用逆地理定位功能进行实现,那么让我们看看逆地理定位功能是怎么实现
的。

二、思路

主要过程分为两部分:
(1):一是获取定位点的经纬度;
(2):二是使用一步骤获取的经纬度,进行调用能够解析经纬度的接口API,进行对应地理信息的获取.
在解决上述问题的过程中使用了百度逆地理高德逆地理定位功能,如下所示分别是高德逆地理和百度逆地理的访问文档

高德地理/逆地理编码文档地址
百度地理/逆地理解析文档地址

三、解决方法

首先要解决的是公共问题,也就是经纬度的获取,在这里,我们使用react-native提供的接口Geolocation进行获取,
说到这里,我们就得去了解一下Geolocation是什么东西?

1. Geolocation信息说明

Geolocation就是react-native官方提供的用于提供基本定位信息和经纬度信息的API,使用Geolocation时需要获取相应的系统权限
(1)权限说明

  • IOS系统:
    需要在Info.plist中增加NSLocationWhenInUseUsageDescription字段来启用定位功能。如果你使用react-native init创建项目,定位会被默认启用。

  • Android系统:
    需要请求访问地理位置的权限,你需要在AndroidManifest.xml文件中加入如下一行:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

(2)方法

  • static requestAuthorization()
    根据pList上配置的密钥请求合适的位置权限。
    如果设置NSLocationAlwaysUsageDescription,它将请求始终授权,但如果设置NSLocationWhenInUseUsageDescription,它将请求InUse授权。
  • static getCurrentPosition(geo_success: Function, geo_error?: Function, geo_options?: GeoOptions)
    成功时会调用geo_success回调,参数中包含最新的位置信息。
    支持的选项:timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
    选项的含义如下所示:
    • timeout:指定获取地理位置时的超时时间,默认不限时
    • maximumAge:最长有效期,此参数用来指定多久再次获取位置
    • enableHighAccuracy:指示浏览器获取高精度的位置,默认为false,开启后浏览器可能花费更长的时间获取更精确的位置数据
      对于该方法请求成功之后,会有下面返回结果:
      • 1.经度:coords.longitude
      • 2.纬度:coords.latitude
      • 3.精确度:coords.accurary
      • 4.海拔:coords.altitude
      • 5.海拔准确度:coords.altitudeAcurary
      • 6.行进方向:coords.heading
      • 7.地面速度:coords.speed
      • 8.时间戳:new Date(position.timestamp)
        当然,我们也可能遇到请求失败的问题,那么,请求失败都有下面这几种情况
        1.用户拒绝定位、2.请求超时、3.暂时获取不到定位信息、4.未知错误
  • static watchPosition(success: Function, error?: Function, options?: GeoOptions)
    持续监听位置,每当位置变化之后都调用success回调。
    支持的选项:timeout (ms), maximumAge (ms), enableHighAccuracy (bool), useSignificantChanges (bool)

  • static clearWatch(watchID: number)
    清除位置监听,位置监听id可由watchPosition方法返回

  • static stopObserving()

    如下面代码,我们能够进行获取到经纬度


  componentDidMount() {
    this._getLocation();
    this.watchPosition = this._getWatchPosition();
  }

  componentWillUnmount() {
    navigator.geolocation.clearWatch(this.watchPosition);
  }

  _getLocation = () => {
    navigator.geolocation.getCurrentPosition(
      (initialPosition) => this.setState({ initialPosition }, () => {
        this._getAddress();
      }),
      (error) => alert(error.message),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
    );
  };

  _getWatchPosition = () => {
    return navigator.geolocation.watchPosition(
      (lastPosition) => {
        this.setState({ lastPosition }, () => { this._getAddress(); });
      },
      (error) => alert(error.message),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
    );
  };

其中initialPositionlastPosition的对象内容一直,只不过一个是初始化的时候的经纬度信息,一个是当前最新的经纬度信息,其返回结果如下所示:



geolocation数据结构

注意:在上面代码中,navigator.geolocation指的不是导航器,而是Geolocation的一个类,能够获取到定位的经纬度信息
我分别使用代码,进行了两种api的调用,如下代码:

2.高德逆地理解析

在高德逆地理解析中,需要首先进行获取高德账号Key。
参考下面文章即可:高德key的申请及使用说明

创建界面如下所示,在创建时我们选择web服务选项:



amap生成key页面

在获取key之后,我们就可以说是所有要准备的东西都已经准备好了,也就是有了Geolocation获取的经纬度,也有了能够正常访问的逆地理解析API,那我们就将
经纬度进行介绍,
首先我们进行判断api能否使用,通过我们手动拼接URL,然后在浏览器地址栏输入,如下界面即为正常

  • 1.输入的url
https://restapi.amap.com/v3/geocode/regeo?key=高德申请的key&poitype=all&radius=3000&output=json&extensions=all&roadlevel=0&location=120.19698604,30.11286062

注意:上面的key需要进行修改为自己的在高德申请的key,才能够进行访问到数据

  • 2.回车之后获取的数据界面
    请求结果数据展示

    注意:如上所示,能够通过浏览器访问到数据,则说明接口可以正常使用,也就是我们可以通过自己的请求进行请求数据了

  • 3.如下代码所示为完整请求过程

_getAddress = () => {
    // 经度:positionData.longitude
    // 纬度:positionData.latitude
    // 最后一步 todo:高德逆地理编码转
    // lat<纬度>,lng<经度>

    const aMapLocationConfig = {
      key: '这里填写你自己申请的key,我的就不让你用了',
      poitype: 'all',
      radius: 3000,
      output: 'json',
      extensions: 'all',
      roadlevel: 0,
    };
    const aMapLocationURL = 'https://restapi.amap.com/v3/geocode/regeo'; //GET请求

    // callback=renderReverse&location=35.658651,139.745415&output=json&pois=1&ak=您的ak
    // radius=3000&output=json&extensions=all&roadlevel=all&location=30.11286062,120.19698604
    // ?output=xml&location=116.310003,39.991957&key=<用户的key>&radius=1000&extensions=all
    const { lastPosition } = this.state;
    if (!lastPosition) return null;
    const { longitude, latitude } = lastPosition.coords;
    const location = longitude + ',' + latitude;
    const aMapUrl = aMapLocationURL + '?' + Qs.stringify({ ...aMapLocationConfig }) + '&location=' + location;

    InteractionManager.runAfterInteractions(() => {
      gaxios(aMapUrl)
        .then((response) => {
          this.setState({
            address: response
          }, () => {
          });
        }).catch((error) => {
          console.log('获取地址信息出错' + error);
        });
    });
  };
3.百度逆地理解析

同样的,对于百度逆地理解析也需要进行获取key值,如下面文档说明百度逆地理解析的申请及说明文档
按照说明文档中的,我们需要进行创建应用
创建界面如下所示:
baidu
在创建应用时,需要注意的是应该创建应用类型为服务端的类型,然后我们就能够进行请求api获取逆地理解析的详细信息了,如下所示:

在创建应用之后,我们就能够进行请求api获取
逆地理解析的详细信息了,代码如下所示:
首先我们进行判断api能否使用,通过我们手动拼接URL,然后在浏览器地址栏输入,如下界面即为正常

  • 1.输入的url
http://api.map.baidu.com/geocoder/v2/?location=30.1128606254,120.1969860408&output=json&pois=1&ak=百度申请的ak

注意:上面的ak需要进行修改为自己的ak,才能够进行访问到数据,同时,为了能够获取到数据,先将ip白名单设置为0.0.0.0/0,如下所示:
url地址

  • 2.回车之后获取的数据界面
    结果数据

    #注意#:如上所示,能够通过浏览器访问到数据,则说明接口可以正常使用,也就是我们可以通过自己的请求进行请求数据了

  • 3.如下为完整请求过程

   _getAddress = () => {
     // 经度:positionData.longitude
     // 纬度:positionData.latitude
     // 最后一步 todo:百度地图逆地理编码转
     // lat<纬度>,lng<经度>

     const baiduLocationConfig = {
       // callback: 'renderReverse',
       ak: '这里填写你自己申请的ak,我的就不让你用了',
       pois: 1,
       output: 'json',
       latest_admin: 1,
       language_auto: 1,
       extensions_town: true,
       extensions_road: true,
       radius: 1000,
     };
     const baiduLocationURL = 'https://api.map.baidu.com/geocoder/v2/'; //GET请求
     // callback=renderReverse&location=35.658651,139.745415&output=json&pois=1&ak=您的ak

     const { lastPosition } = this.state;
     if (!lastPosition) return null;
     const { longitude, latitude } = lastPosition && lastPosition.coords;
     const location = latitude + ',' + longitude;
     const baiduUrl = baiduLocationURL + '?' + Qs.stringify({ ...baiduLocationConfig }) + '&location=' + location;

     InteractionManager.runAfterInteractions(() => {
       gaxios(baiduUrl)
         .then((response) => {
           this.setState({
             address: response
           }, () => {
           });
         }).catch((err) => {
           console.log('获取地址信息出错', err);
         });
     });
   };
四、效果展示

发送请求之后,我们能够看到如下效果,在请求之后,我将请求到的数据进行了分类,进行对其中具体的字段进行了说明:

1.高德地图请求效果

高德效果展示

2.百度地图请求效果

百度效果展示

五 演示代码github地址

GitHub地址:https://github.com/suwu150/react-native-locations
,能够直接通过git clone进行克隆运行,运行命令如下所示:

1.克隆项目

git clone https://github.com/suwu150/react-native-locations.git

2.进入项目,安装依赖文件库

cd react-native-locations
npm install

3.运行项目
ios:

 react-native run-ios

Android:

react-native run-android

注意:在运行安卓项目的时候,必须手动打开模拟器


猜你喜欢

转载自blog.csdn.net/suwu150/article/details/80935563