react-native 接百度地图API (显示周边poi)

目的:显示周边poi及搜索poi功能(给自己的笔记,省去了很多基础步骤,有问题的可以先去了解RN跟android以及Ios原生的通信)

Android

  • 环境配置按照官网提供的文档来就行比较简单

BaiDuLocationModule.java

package com.demo.baidulocation; // 自己的包名import java.util.List;
import org.json.JSONObject;
import org.json.JSONArray;import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiSortType;import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.Callback;public class BaiDuLocationModule extends ReactContextBaseJavaModule{private ReactApplicationContext mContext;public LocationClient mLocationClient = null;private Callback locationCallback;private Callback searchCallback;PoiSearch poiSearch;double lat = 0;double lng = 0;BaiDuLocationModule(ReactApplicationContext reactContext) {super(reactContext);mContext = reactContext;}@Overridepublic String getName() {return "BaiDuLocation";}// 获取地理位置@ReactMethodpublic void startLocation( Callback locationCallback) {this.locationCallback = locationCallback;mLocationClient = new LocationClient(getReactApplicationContext());     //声明LocationClient类mLocationClient.registerLocationListener(myListener);    //注册监听函数LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系int span = 0;option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要option.setOpenGps(true);//可选,默认false,设置是否使用gpsoption.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要mLocationClient.setLocOption(option);mLocationClient.start();}/*** 定位回掉*/public BDLocationListener myListener = new BDLocationListener() {@Overridepublic void onReceiveLocation(final BDLocation bdLocation) {JSONObject data = new JSONObject();mLocationClient.unRegisterLocationListener(this);mLocationClient.stop();lat = bdLocation.getLatitude();lng = bdLocation.getLongitude();try{data.put("code", bdLocation.getLocType());data.put("latitude", bdLocation.getLatitude());data.put("longitude", bdLocation.getLongitude());data.put("addr", bdLocation.getAddrStr()); // 详细地址data.put("province", bdLocation.getProvince()); // 省data.put("city", bdLocation.getCity()); // 市data.put("district", bdLocation.getDistrict()); // 区if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果data.put("type","gps");  // 定位方式} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果data.put("type","internet");  // 定位方式} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {data.put("error", "网络不通导致定位失败,请检查网络是否通畅");} else if (bdLocation.getLocType() == BDLocation.TypeCriteriaException) {data.put("error", "无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");} else {data.put("error", "定位失败,请打开定位权限");}List<Poi> list = bdLocation.getPoiList();// POI数据JSONArray poiList = new JSONArray();if (list != null) {for (Poi p : list) {JSONObject obj = new JSONObject();obj.put("name", p.getName());obj.put("detaill", p.getAddr());poiList.put(obj);}data.put("poiList", poiList);} else {data.put("poiList", "null");}} catch (Exception e){}locationCallback.invoke(data.toString());}};@ReactMethodpublic void stopLocation() {}// 检索地理位置@ReactMethodpublic void searchLocation(final String keyword, Callback searchCallback) {this.searchCallback = searchCallback;poiSearch = PoiSearch.newInstance();//创建POI检索实例poiSearch.setOnGetPoiSearchResultListener(poiSearchResultListener);poiSearch.searchNearby(new PoiNearbySearchOption().sortType(PoiSortType.distance_from_near_to_far).keyword(keyword).radius(10000).pageCapacity(50).pageNum(0).location(new LatLng(lat, lng)));}//创建POI检索监听public OnGetPoiSearchResultListener poiSearchResultListener = new OnGetPoiSearchResultListener() {@Overridepublic void onGetPoiResult(PoiResult poiResult) {//获取POI检索结果if (poiResult == null || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {// 检索失败searchCallback.invoke("-1");} else if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {/*** PoiInfo中包含了经纬度、城市、地址信息、poi名称、uid、邮编、电话等等信息;有了这些,你是不是可以可以在这里画一个自定义的图层了,然后添加点击事件,做一些操作了呢*/List<PoiInfo> poiInfos = poiResult.getAllPoi();//poi列表JSONArray poiList = new JSONArray();if (poiInfos != null) {for (PoiInfo p : poiInfos) {JSONObject obj = new JSONObject();try{obj.put("name", p.name);obj.put("detaill", p.address);poiList.put(obj);} catch (Exception e){}}searchCallback.invoke(poiList.toString());} else {searchCallback.invoke("-1");}// searchCallback.invoke(JSON.toJSONString(poiInfos));// Log.e("poiDatassss", JSON.toJSONString(poiInfos));} else {searchCallback.invoke("-1");}return;}@Overridepublic void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {//获取某个Poi详细信息//获取Place详情页检索结果}@Overridepublic void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {}@Overridepublic void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {//查询室内poi检索结果回调}};
}

IOS

  • 环境配置比较麻烦,按照官网的方法导入framework会报错,要在 Build Settings>Search Paths>Framework Search Paths里添加你下载的sdk的路径(把整个文件夹拖入添加列表自动生成路径)

BaiDuLocation.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import "BaiDuLocation.h"
typedef void (^PoiSearchBlcok)(id object);
@interface BaiDuLocation : NSObject<RCTBridgeModule>@end

BaiDuLocation.m

#import <Foundation/Foundation.h>
#import "BaiDuLocation.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>
#import <BaiduMapAPI_Search/BMKSearchComponent.h>
#import <BMKLocationKit/BMKLocationComponent.h>
#import <CoreLocation/CLLocationManager.h>@interface BaiDuLocation ()<BMKPoiSearchDelegate, BMKLocationAuthDelegate, BMKLocationManagerDelegate, BMKGeneralDelegate>@property (nonatomic, strong) BMKMapManager *mapManager; //主引擎类
@property (nonatomic, strong) BMKLocationManager *locationManager;
@property (nonatomic, strong) BMKPoiSearch *poiSearch;
@property (nonatomic, copy) PoiSearchBlcok poiSearchBlcok;@end@implementation BaiDuLocationNSString *lat;
NSString *lng;- (void)configAK {[[BMKLocationAuth sharedInstance] checkPermisionWithKey:@"这里填写自己申请的ak" authDelegate:self];_mapManager = [[BMKMapManager alloc] init];[_mapManager start:@"这里填写自己申请的ak" generalDelegate:self]; // 这个初始化时给POI周边检索用的;没有这个提示检索成功但是死都不进回调;官方文档也没提醒;很坑!!!!_poiSearch = [[BMKPoiSearch alloc] init]; //初始化POI周边检索对象_poiSearch.delegate = self; //设置POI城市检索代理
}// 导出模块,不添加参数即默认为这个类名
RCT_EXPORT_MODULE();// 导出方法,桥接到js的方法返回值类型必须是void
RCT_EXPORT_METHOD(startLocation:(RCTResponseSenderBlock)callback) {[self configAK];dispatch_sync(dispatch_get_main_queue(),^ {if ([CLLocationManager locationServicesEnabled] && ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways)) {// 定位功能可用_locationManager = [[BMKLocationManager alloc] init]; //初始化实例_locationManager.delegate = self; //设置delegate_locationManager.coordinateType = BMKLocationCoordinateTypeBMK09LL; //设置返回位置的坐标系类型_locationManager.distanceFilter = kCLDistanceFilterNone; //设置距离过滤参数_locationManager.desiredAccuracy = kCLLocationAccuracyBest; //设置预期精度参数_locationManager.activityType = CLActivityTypeAutomotiveNavigation; //设置应用位置类型_locationManager.pausesLocationUpdatesAutomatically = NO; //设置是否自动停止位置更新//_locationManager.allowsBackgroundLocationUpdates = YES; //设置是否允许后台定位_locationManager.locationTimeout = 15; //设置位置获取超时时间_locationManager.reGeocodeTimeout = 15; //设置获取地址信息超时时间[self requestLocation: callback]; //请求一次定位} else if ([CLLocationManager authorizationStatus] ==kCLAuthorizationStatusDenied) {callback(@[@"null"]);}});
}- (void)requestLocation: (RCTResponseSenderBlock)callback {[_locationManager requestLocationWithReGeocode:YES withNetworkState:YES completionBlock:^(BMKLocation * _Nullable location, BMKLocationNetworkState state, NSError * _Nullable error) {if (error) {callback(@[@"null"]);} else if (location) {//得到定位信息NSMutableDictionary *_dict = [NSMutableDictionary dictionary];NSString *province = @"null"; NSString *city = @"null";NSString *district = @"null"; NSString *locationDescribe = @"null";NSString *addr = @"null";if (location.rgcData.province) { province = location.rgcData.province; }if (location.rgcData.city) { city = location.rgcData.city; }if (location.rgcData.district) { district = location.rgcData.district; }if (location.rgcData.locationDescribe) { locationDescribe = location.rgcData.locationDescribe; }if (location.rgcData) {addr = [NSString stringWithFormat:@"%@%@%@%@%@",province, city, district, location.rgcData.street, location.rgcData.streetNumber];}lat = [NSString stringWithFormat:@"%f", location.location.coordinate.latitude];lng = [NSString stringWithFormat:@"%f",location.location.coordinate.longitude];[_dict setObject: [NSString stringWithFormat:@"%f", location.location.coordinate.latitude] forKey:@"latitude"];[_dict setObject: [NSString stringWithFormat:@"%f",location.location.coordinate.longitude] forKey:@"longitude"];[_dict setObject: addr forKey:@"addr"]; // 地址详情[_dict setObject: province forKey:@"province"];  // 省[_dict setObject: city forKey:@"city"]; // 市[_dict setObject: district forKey:@"district"]; // 区[_dict setObject: locationDescribe forKey:@"locationDescribe"]; // 语义化信息if (location.rgcData.poiList) {NSMutableArray *_array = [NSMutableArray array];for (BMKLocationPoi * poi in location.rgcData.poiList) {// 具体属性可以参考官方文档的BMKLocationPoi类NSDictionary *dict = @{@"name" : poi.name,@"detaill" : poi.addr,};[_array addObject: dict];// NSLog(@"poi = %@, %@, %f, %@, %@", poi.name, poi.addr, poi.relaiability, poi.tags, poi.uid);}[_dict setObject:_array forKey:@"poiList"];} else {[_dict setObject:@"null" forKey:@"poiList"];}NSError *error = nil;NSData *jsonData = [NSJSONSerialization dataWithJSONObject:_dictoptions:NSJSONWritingPrettyPrintederror:&error];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];callback(@[jsonString]);} else {callback(@[@"null"]);}_locationManager.delegate = nil;}];
}RCT_EXPORT_METHOD(searchLocation: (NSString *)keyword callback:(RCTResponseSenderBlock)callback) {//初始化请求参数类BMKNearbySearchOption的实例BMKPOINearbySearchOption *nearbyOption = [[BMKPOINearbySearchOption alloc] init];nearbyOption.keywords = @[keyword]; //检索关键字,必选CLLocationCoordinate2D coor;coor.latitude = [lat doubleValue];coor.longitude = [lng doubleValue];nearbyOption.location = coor; //检索中心点的经纬度,必选nearbyOption.radius = 10000; //检索半径,单位是米。nearbyOption.isRadiusLimit = NO; //是否严格限定召回结果在设置检索半径范围内。默认值为false。// nearbyOption.sortType = DISTANCE_FROM_NEAR_TO_FOR; //poi列表顺序nearbyOption.pageIndex = 0; //分页页码,默认为0,0代表第一页,1代表第二页,以此类推nearbyOption.pageSize = 50; //单次召回POI数量,默认为10条记录,最大返回20条。BOOL flag = [_poiSearch poiSearchNearBy:nearbyOption]; //发起POI周边检索请求if (flag) {// NSLog(@"POI周边检索成功");self.poiSearchBlcok = callback;} else {// NSLog(@"POI周边检索失败");callback(@[@"-1"]);}
}#pragma mark - BMKPoiSearchDelegate
- (void)onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPOISearchResult*)poiResult errorCode:(BMKSearchErrorCode)errorCode{//BMKSearchErrorCode错误码,BMK_SEARCH_NO_ERROR:检索结果正常返回if (errorCode == BMK_SEARCH_NO_ERROR) {//在此处理正常结果NSMutableArray *_array = [NSMutableArray array];if (poiResult.poiInfoList) {for (BMKPoiInfo * poi in poiResult.poiInfoList) {// 具体属性可以参考官方文档的BMKPoiInfo类NSDictionary *dict = @{@"name" : poi.name,@"detaill" : poi.address,};[_array addObject: dict];}NSError *error = nil;NSData *jsonData = [NSJSONSerialization dataWithJSONObject:_arrayoptions:NSJSONWritingPrettyPrintederror:&error];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];self.poiSearchBlcok(@[jsonString]);} else {self.poiSearchBlcok(@[@"-1"]);}} else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD) {// NSLog(@"检索词有歧义");self.poiSearchBlcok(@[@"-1"]);} else {// NSLog(@"其他检索结果错误码");self.poiSearchBlcok(@[@"-1"]);}
}@end

react-native 端使用

Example.js

import React, { Component } from 'react';
import { View, NativeModules, PermissionsAndroid
} from 'react-native';
export default class Example extends Component {constructor(props) {super(props);this.state = {addressList: [],searchList: [],}this.isInSearch = false;}componentDidMount() {if (Platform.OS === 'ios') {this.getLocation();} else {this.requestPermission();}}requestPermission = async() => {try {const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);if (granted === PermissionsAndroid.RESULTS.GRANTED) {console.log('你获得GPS定位权限了');this.getLocation();} else { // 拒绝的话二次获取权限const granted1 = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);if (granted1 === PermissionsAndroid.RESULTS.GRANTED) {console.log('你获得网络定位权限了');this.getLocation();} else {this.getLocation();}}} catch (err) {console.warn(err);}}getLocation = () => {const { BaiDuLocation } = NativeModules;BaiDuLocation.startLocation((res) => {if (res === 'null') {console.log('ios定位失败了');return}let data = JSON.parse(res)console.log(data);// android 判断code  ios 判断 res === "null"if (data.code === 161 || Platform.OS === 'ios') {if (data.poiList && data.poiList != "null" && data.poiList.length > 0) {// 检索到了poi// 具体数据操作按自己需求来console.log(data.poiList); } else {// 未检索到poi 但获取到了地理位置// 具体数据操作按自己需求来console.log(data.city);console.log(data.district);console.log(data.addr);}} else {console.log(data.error);}// 百度地图提供的  全球逆地理编码服务 可以获取更多的poithis.moreLocation(data.latitude, data.longitude);})}moreLocation = (lat, lng) => {let mcode = '安全码'; // 开发环境  开发版SHA1 + 包名// let mcode = '安全码'; // 生产环境  发布版SHA1 + 包名let ak = 'androidAK';if (Platform.OS === 'ios') {mcode = '自己的包名'; // ios的包名就是安全码ak = 'iosAK';}// 请求方式按自己的来 请求参数 返回数据 官网写的很详细(具体参考官方文档)fetch(`http://api.map.baidu.com/reverse_geocoding/v3/?ak=${ak}&output=json&coordtype=wgs84ll&location=${lat},${lng}&mcode=${mcode}&extensions_poi=1`, {method: 'GET',cache: 'default',}).then((response) => {if (response.ok) {return response.json();}}).then((json) => {// 具体数据操作按自己需求来console.log(json);})}searchAddr = (text) => {const { BaiDuLocation } = NativeModules;if (this.isInSearch || text === '') {return;}this.isInSearch = true;BaiDuLocation.searchLocation(text, (res) => {this.isInSearch = false;console.log(res);if (res === "-1") {// 检索失败// 具体数据操作按自己需求来} else {// 检索成功let data = JSON.parse(res)// 具体数据操作按自己需求来console.log(data);}})}render() {return (<View></View>)}
}

参考图

设置的搜索半径有点大,所以可以获取到比较远的poi

react-native 接百度地图API(显示周边poi)相关推荐

  1. react项目使用百度地图API

    文章目录 前言 一.接入API 1.登录百度地图 2.创建应用,获取密钥 3.引入API 4.当作模块导入BMap 二.使用 1.引入 2.展示地图 三.效果展示 总结 前言 最近在开发一款react ...

  2. 百度地图API显示多个标注点的代码 以及修改传参

    引用的页面原始数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  3. 百度地图API 显示区域边界及地名定位

    百度地图API 显示区域边界及地名定位 这个定位一共用了两个方法组成 一个是定位绘制区域边界线,另一个是地名定位 原理: 当用户输入省.市.县.区这种大地名时,我们要定位用户输入的这个位置,并显示轮廓 ...

  4. 关于百度地图API显示地区范围控制的问题

    关于百度地图API显示地区范围控制的问题,这个有很多种方法,需要看个人需求下面列举两种方法 1.假如我只想在 加载地图的时候显示郑州市所包含的范围,其他地方屏蔽掉,或者不让拖拽(如有图所示) 2. 控 ...

  5. 百度地图API显示多个标注点带提示的代码 / 单个标注点带提示代码

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><me ...

  6. 利用百度地图api抓取POI点(上海公交站)

    1.功能描述 百度地图api抓取POI点(上海公交站) 2.代码 import pandas as pd import requests import json import numpy as npi ...

  7. 百度地图API显示车辆运行轨迹并动画展示

    百度地图api 版本:3.0 开发文档:http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a0b0 需求描述 项 ...

  8. 【QT】--调用百度地图API显示

    编译运行环境 Qt 5.15.2 MSVC2019 release编译 1.html文件 百度地图提供API示例程序 将代码复制到html文件中,用编辑器打开,这里用vs打开 在图中位置替换为个人申请 ...

  9. python3 通过百度地图API获取城市POI点并存于CSV格式

    原文信息: 作者:WenWu_Both  出处:http://blog.csdn.net/wenwu_both/article/  版权:本文版权归作者和CSDN博客共有  转载:欢迎转载,但未经作者 ...

  10. python读取csv文件坐标地图描点_python3 通过百度地图API获取城市POI点并存于CSV格式...

    原文信息: 作者:WenWu_Both 出处:http://blog.csdn.net/wenwu_both/article/ 版权:本文版权归作者和CSDN博客共有 转载:欢迎转载,但未经作者同意, ...

最新文章

  1. Springboot 中 Mybatis 的使用
  2. nginx反向代理部署与演示(二)
  3. Java CopyOnWriteArrayList
  4. Worktile 技术架构概要
  5. alibaba Fastjson的JOSN解析库 -
  6. MacOS录制GIF/录屏的工具
  7. 【OpenCV 例程200篇】71. 连续函数的取样
  8. pe和linux一起安装到移动硬盘,解决方法:将分区的移动硬盘放入可启动的WIN PE磁盘中,并安装GHO或ISO原始版本...
  9. 2017年云主机性能测评报告
  10. abap判断包含字符当中包含小数点_剑指Offer整理3 -- 栈和队列 + 数学和字符串
  11. ASP.NET 配置概览
  12. Java 数组+循环升级篇
  13. java热血_5个让人热血沸腾的java项目
  14. linux服务器配置与管理_一个十多年的系统管理员,忘了如何管理一台服务器
  15. 数据结构题及c语言版 答案,数据结构(C语言版)1800道题及答案[完整版]
  16. 一个好的热修复技术,将为你的 App助力百倍
  17. 寄存器、缓存、内存、硬盘、存储器
  18. AbstractApplicationContext的refresh方法
  19. 哈工大C语言程序设计精髓第六周
  20. 1.8w 字 | 初中级前端 JavaScript 自测清单 - 2

热门文章

  1. 判断一个整数为奇数还是偶数
  2. 在EDIUS中使用调音台的方法
  3. MySQL 中间件 Mycat
  4. BGA Banner 轮播图 引导图
  5. 拓薪教育任亮java_拓薪教育-中国移动电商实战项目-任亮
  6. 店宝宝:淘宝开店详细教程!来自老卖家的建议
  7. ArcGIS API For JavaScript Font字体简介,下载及本地部署
  8. python克里金生成asc_使用Python生成ASCII字符画
  9. 机械复试面试问题汇总 4
  10. 图片透明代码html5,javascript – 透明图像背景html5画布