react-native-baidu-map-jm
v1.4.4
Published
Baidu Map SDK modules and view for React Native(Android & IOS), support react native 0.57+. 百度地图 React Native 模块,支持 react native 0.57+,已更新到最新的百度地图SDK版本。
Downloads
168
Readme
react-native-baidu-map-jm
- 此版本为lovebing的分支仓库,特此感谢作者的开源。因项目需求,iOS版百度最新的SDK作者未实现Overlay,个人在其基础上参考Android进行修改和完善。
Baidu Map SDK modules and view for React Native(Android & IOS), support react native 0.57+
百度地图 React Native 模块,支持 react native 0.57+,已更新到最新的百度地图SDK版本。
Environments 环境要求
1.JS
- node: 8.0+
2.Android
- Android SDK: api 28+
- gradle: 4.5
- Android Studio: 3.1.3+
3.IOS
- XCode: 9.0+
Install 安装
使用 npm 源
npm install react-native-baidu-map-jm --save
原生模块导入
Android Studio
react-native link react-native-baidu-map-jm
PS: 工程build.gradle需要修改代码,否则无法运行:
dependencies {
compileOnly 'com.facebook.react:react-native:+'
compileOnly files('src/main/assets')
implementation project(':map_baidu_lib') //自定义导入百度SDK模块(第三方开发者使用时屏蔽此代码,打开下一行依赖)
// implementation files('libs/BaiduLBS_Android.jar')
}
修改为
dependencies {
compileOnly 'com.facebook.react:react-native:+'
compileOnly files('src/main/assets')
implementation files('libs/BaiduLBS_Android.jar')
}
在MapListener.java文件打开下面的代码(仓库代码中被屏蔽了)
////第三方使用者需要打开以下代码
// @Override
// public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
// sendEvent(mapView, "onMapStatusChangeStart", getEventParams(mapStatus));
// }
IOS/Xcode
1、方式一:react-native link react-native-baidu-map-jm
2、方式二:
Podfile 增加
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge',
'DevSupport',
'RCTText',
'RCTNetwork',
'RCTWebSocket',
'RCTAnimation'
]
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
pod 'react-native-baidu-map-jm', :podspec => '../node_modules/react-native-baidu-map-jm/ios/react-native-baidu-map-jm.podspec'
Usage 使用方法
import { MapView, MapTypes, Geolocation, Overlay, MapSearch} from 'react-native-baidu-map-jm'
MapView Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | zoomControlsVisible | bool | true | 是否显示缩放控件,Android only | trafficEnabled | bool | false | 是否打开路况图层 | baiduHeatMapEnabled | bool | false | 是否打开热力图 | mapType | number| 1 | 地图类型:标准地图=1、卫星地图=2 | zoom | number| 10 | 地图缩放级别,iOS:[4,21],Android:[3,20] | center | object| null | 地图中心位置,{latitude: 0, longitude: 0} | buildingsEnabled | bool | true | 是否显示3D楼块效果 | overlookEnabled | bool | true | 是否打开俯仰角效果 | visualRange | array | [] | 地图可是范围 | correctPerspective | object| undefined| 是否支持透视效果,Android only | onMapStatusChangeStart | func | undefined| 回调:地图状态开始更改 | onMapStatusChange | func | undefined| 回调:地图状态改变 | onMapStatusChangeFinish | func | undefined| 回调:地图状态改变完成 | onMapLoaded | func | undefined| 回调:地图已加载完成 | onMapClick | func | undefined| 回调:地图点击 | onMapDoubleClick | func | undefined| 回调:双击地图 | onMarkerClick | func | undefined| 回调:点击Marker | onMapPoiClick | func | undefined| 回调:点中底图标注 | onBubbleOfMarkerClick | func | undefined| 回调:点击气泡,Android only | reloadView() | Func | undefined| 刷新地图上的所有图层(当地图被切换进来时再次进入需要调用),Android only,用法:<MapView ref={(e)=>{this.MapViewFunc=e}}/> this.MapViewFunc.reloadView();
Overlay 覆盖物
const { Marker, Arc, Circle, Polyline, Polygon, InfoWindow } = Overlay;
Marker Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | tag | int | -1 | 用于多个Marker时绑定InfoWindow,仅当tag相同时才会显示 | title | string| null | | location | object| {latitude: 0, longitude: 0} | | alpha | float | 1 | 透明度 | rotate | float | 0 | 图片旋转角度 | flat | bool | null | | icon | any | null | icon图片,同 的 source 属性 | visible | bool | true | 是否显示
Arc Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | color | string| FFFF0088 | 颜色 | width | int | 1 | 宽度 | poins | array | [{latitude: 0, longitude: 0}, {latitude: 0, longitude: 0}, {latitude: 0, longitude: 0}] | 数值长度必须为 3 | visible | bool | true | 是否显示
Circle Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | radius | int | | 角度 | fillColor | string| | 内部填充颜色 | stroke | object| {width: 2, color: 'AA0000FF'} | | center | object| {latitude: 0, longitude: 0} | | visible | bool | true | 是否显示
Polyline Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | points | array | [{latitude: 0, longitude: 0},{latitude: 0, longitude: 0}] | | width | int | 8 | 线条宽度 | color | string|'FF00FF44'| 线条颜色 | visible | bool | true | 是否显示
Polygon Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | points | array | [{latitude: 0, longitude: 0}] | | fillColor | string| | 内部填充颜色 | stroke | object| {width: 2, color: 'AA00FF00'} | | visible | bool | true | 是否显示
Text Props 属性(iOS无此属性)
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | text | string| | | fontSize | int | | | fontColor | string| | | bgColor | string| | | rotate | float | | | location | object|{latitude: 0, longitude: 0}
InfoWindow Props 属性
| Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | tag | int | -1 | 用于多个Marker时绑定InfoWindow,仅当tag相同时才会显示 | location | object| {latitude: 0, longitude: 0},不要使用(无效) | visible | bool | true | 是否显示 | title | string| "" | | update() | Func |undefined | <Overlay.InfoWindow ref={(e)=>{this.InfoWindowFunc=e}}/> this.InfoWindowFunc.update(); | PS(注意) | Bomb |undefined | 1、Android平台中若需要放入图片,InfoWindow需要和MapView同级放置View中,同时把位置移至手机屏幕外;2、无图片无需按第1条操作;3、iOS端无需前2条操作;
Geolocation Methods
| Method | Result
| ------------------------- | -------
| Promise reverseGeoCode(double lat, double lng) | {"address": "", "province": "", "cityCode": "", "city": "", "district": "", "streetName": "", "streetNumber": ""}
| Promise reverseGeoCodeGPS(double lat, double lng) | {"address": "", "province": "", "cityCode": "", "city": "", "district": "", "streetName": "", "streetNumber": ""}
| Promise geocode(String city, String addr) | {"latitude": 0.0, "longitude": 0.0}
| Promise getCurrentPosition() | IOS: {"latitude": 0.0, "longitude": 0.0, "address": "", "province": "", "cityCode": "", "city": "", "district": "", "streetName": "", "streetNumber": ""}
Android: {"latitude": 0.0, "longitude": 0.0, "direction": -1, "altitude": 0.0, "radius": 0.0, "address": "", "countryCode": "", "country": "", "province": "", "cityCode": "", "city": "", "district": "", "street": "", "streetNumber": "", "buildingId": "", "buildingName": ""}
BaiduLocationModule Methods
| Method | Listener | Result | Description
| ------------------------- | ------- | ------ | -------
| Promise config(String key) | kLocationModuleCheckPermission |{"errcode": "0", "errmsg": "Success"}
| locationTimeout(int timeout) | null | null | 定位的超时时间(注意:不是定位频率)
| allowsBackground(bool allows) | null |null | 仅iOS有效
| startUpdatingLocation() | kLocationModuleUpdateLocation、kLocationModuleFail、kLocationModuleChangeAuthorization、kLocationModuleUpdateNetworkState | {"method": "onLocationModuleUpdateLocation", "latitude": 0.0, "longitude": "0.0"}
or {"method": "onLocationModuleFail", "errcode": 0, "errmsg": "定位发生错误"}
or {"method": "onLocationModuleChangeAuthorization", "state": 0}
or {"method": "onLocationModuleUpdateNetworkState", "state": 0}
| kLocationModuleChangeAuthorization、kLocationModuleUpdateNetworkState仅iOS有效
| stopUpdatingLocation() | null | null
| startUpdatingHeading() | kLocationModuleUpdateHeading | {"magneticHeading": 0.0, "trueHeading": 0.0, "headingAccuracy": 0.0, "timestamp": 0.0}
| 仅iOS有效
| stopUpdatingHeading() | null | null | 仅iOS有效
MapSearch Methods(POI检索)
| Method | Result
| ------------------------- | -------
| Promise requestSuggestion(String city, String keyWord) | {"sugList":[{"city": "", "district": "", "key": "", "latitude": "", "longitude": ""},{...}]}
注意:key、district可能不存在
| Promise poiSearchNearby(double lat, double lng, int radius, String keyword) | {"sugList":[{"city": "", "district": "", "key": "", "latitude": "", "longitude": ""},{...}]}
注意:key、district可能不存在
Demo示例
import React, {Component} from 'react';
import {Platform, StyleSheet, Image, Text, View, Dimensions, Button,TouchableOpacity,NativeModules,NativeEventEmitter} from 'react-native';
import { MapView, MapTypes, Geolocation, Overlay} from 'react-native-baidu-map-jm';
const {height, width} = Dimensions.get('window');
const {
BaiduLocationModule
} = NativeModules;
const locationListener = new NativeEventEmitter(BaiduLocationModule);
export default class App extends Component<Props> {
state = {
center:{
latitude : 22.5801910000,
longitude : 113.9276540000
},
trafficEnabled:true,
isOpenPanoramic:false,
mapType:1,
markers:[
{
title:'汽车位置',
location:{
latitude : 22.55373,
longitude : 113.925063
}
},
{
title:'haha,我在这里',
location:{
latitude : 22.580054,
longitude : 113.927745
}
}],
isCarLocation:false
};
componentWillMount() {
}
componentDidMount(){
this.location(this.state.isCarLocation);
}
componentWillUnmount() {
}
//路况
setTraffic(enabled){
console.log('Home',"路况:" + enabled);
this.setState({trafficEnabled:enabled});
}
//全景
panoramic(isOpen){
console.log('Home',"全景状态:" + isOpen);
}
//地图类型
setMapType(type){
console.log('Home',"地图类型:" + type);
this.setState({mapType:type});
}
location(isCar){
if(isCar) {
console.log('定位车辆位置');
} else {
console.log('定位当前位置');
}
this.setState({isCarLocation:isCar});
if(isCar){
this.getCarLocation();
}else{
this.getMyLocation();
}
this.InfoWindowFunc.update();
}
//自定定位
autoLocation() {
locationListener.addListener(BaiduLocationModule.kLocationModuleCheckPermission, (reminder) => {
console.log('kLocationModuleCheckPermission---->', reminder);
BaiduLocationModule.startUpdatingLocation();
});
locationListener.addListener(BaiduLocationModule.kLocationModuleUpdateLocation, (reminder) => {
console.log('kLocationModuleUpdateLocation---->', reminder);
});
BaiduLocationModule.config(null);
}
//查询车的位置
getCarLocation(){
//此处无Car的位置信息,用人的位置代替
Geolocation.getCurrentPosition().then(data=>{
console.log('getCarPosition',"latitude:" + data.latitude + " ,longitude:" + data.longitude + " ,address:" + data.address);
let carPosition = this.state.markers[0];
let personPosition = this.state.markers[1];
this.setState({
markers:[
{
title:carPosition.title,
location:{
latitude : data.latitude-0.001000,
longitude : data.longitude-0.001000,
}
},
{
title:personPosition.title,
location:{
latitude : personPosition.location.latitude,
longitude : personPosition.location.longitude,
}
}
],
center:{
latitude : data.latitude-0.001000,
longitude : data.longitude-0.001000
}
});
}).catch(e=>{
console.log('getCurrentPosition', '获取位置失败:' + e);
});
}
//获取当前人位置
getMyLocation(){
Geolocation.getCurrentPosition().then(data=>{
console.log('getCurrentPosition',"latitude:" + data.latitude + " ,longitude:" + data.longitude + " ,address:" + data.address);
let carPosition = this.state.markers[0];
let personPosition = this.state.markers[1];
this.setState({
markers:[
{
title:carPosition.title,
location:{
latitude : carPosition.location.latitude,
longitude : carPosition.location.longitude,
}
},
{
title:personPosition.title,
location:{
latitude : data.latitude,
longitude : data.longitude,
}
}
],
center:{
latitude : data.latitude,
longitude : data.longitude
}
});
}).catch(e=>{
console.log('getCurrentPosition', '获取位置失败:' + e);
});
}
render() {
return (
<View style={styles.container}>
<MapView
ref={(e)=>{this.MapViewFunc=e}}
mapType={this.state.mapType}
trafficEnabled={this.state.trafficEnabled}
width={width}
height={height}
zoom={18}
center={this.state.center}
onMapStatusChange={(params)=>{
// console.log("onMapStatusChange->params:" + params.target.longitude)
}}
onMapLoaded={(params)=>{
console.log("onMapLoaded->params:")
}}
onMapClick={(params)=>{
console.log("onMapClick->位置:" + params.longitude + "," + params.latitude)
}}
onMapDoubleClick={(params)=>{
console.log("onMapPoiClick->params:" + " ,位置:" + params.longitude + "," + params.latitude)
}}
onMapPoiClick={(params)=>{
console.log("onMapPoiClick->Name:" + params.name + " ,uid:" + params.uid + " ,位置:" + params.longitude + "," + params.latitude)
}}
onMarkerClick={(params) => {
console.log("onMarkerClick->标题:", params.title + " ,位置:" + params.position.longitude + "," + params.position.latitude)
}}
onBubbleOfMarkerClick={(params) => {
console.log("onBubbleOfMarkerClick->标题:", params.title + " ,位置:" + params.position.longitude + "," + params.position.latitude)
}}
>
<Overlay.Marker
tag={0}
title={this.state.markers[0].title}
location={this.state.markers[0].location}
icon={require('./res/image/icon_car.png')}
/>
<Overlay.Marker
tag={1}
title={this.state.markers[1].title}
location={this.state.markers[1].location}
icon={require('./res/image/home_icon_locat.png')}
/>
<Overlay.InfoWindow
ref={(e)=>{this.InfoWindowFunc=e}}
style={{flexDirection:'column', justifyContent:'space-between', width:100, height:100, backgroundColor:'#F5FCFF', borderRadius:6}}
tag={this.state.isCarLocation? 0 : 1}
visible={true}
>
<Text style={styles.baseText}>
{"This is a Infowindow"}{'\n'}
</Text>
<Image
source={require('./res/image/home_icon_car.png')}>
</Image>
</Overlay.InfoWindow>
<Overlay.Circle
center={this.state.markers[1].location}
radius={30}
fillColor='AA0000FF'
/>
<Overlay.Polygon
points={[{
latitude: this.state.markers[0].location.latitude-0.0005,
longitude: this.state.markers[0].location.longitude-0.0005
},
{
latitude: this.state.markers[0].location.latitude-0.0005,
longitude: this.state.markers[0].location.longitude+0.0005
},
{
latitude: this.state.markers[0].location.latitude+0.0005,
longitude: this.state.markers[0].location.longitude+0.0005
},
{
latitude: this.state.markers[0].location.latitude+0.0005,
longitude: this.state.markers[0].location.longitude-0.0005
}]}
/>
<Overlay.Polyline
points={[{
latitude: this.state.markers[0].location.latitude-0.0005,
longitude: this.state.markers[0].location.longitude-0.0005
},
{
latitude: this.state.markers[0].location.latitude+0.0005,
longitude: this.state.markers[0].location.longitude+0.0005
}]}
/>
<Overlay.Arc
points={[{
latitude: this.state.markers[0].location.latitude,
longitude: this.state.markers[0].location.longitude
},
{
latitude: this.state.markers[0].location.latitude,
longitude: this.state.markers[1].location.longitude
},
{
latitude: this.state.markers[1].location.latitude,
longitude: this.state.markers[1].location.longitude
}
]}
/>
</MapView>
<TouchableOpacity style={{position:'absolute',bottom:20,start:20}} onPress={()=>{this.location(!this.state.isCarLocation)}}>
<Image
source={this.state.isCarLocation ? require('./res/image/home_icon_car.png'):require('./res/image/home_icon_location.png')}>
</Image>
</TouchableOpacity>
<View style={{flexDirection:'column' , justifyContent:'space-between' ,width:30 ,height:90 ,position:'absolute',top:40,end:20}}>
<TouchableOpacity onPress={()=>{this.setTraffic(!this.state.trafficEnabled)}}>
<Image
source={this.state.trafficEnabled ? require('./res/image/icon_traffic_selected.png'):require('./res/image/icon_traffic_unselected.png')}>
</Image>
</TouchableOpacity>
<TouchableOpacity onPress={()=>{
let type = this.state.mapType == 1 ? 2 : 1;
this.setMapType(type);
}}>
<Image
source={this.state.mapType == 1 ? require('./res/image/icon_layer_unselected.png'):require('./res/image/icon_layer_selected.png')}>
</Image>
</TouchableOpacity>
</View>
<TouchableOpacity style={{position:'absolute',bottom:20,start:20}} onPress={()=>{this.location(!this.state.isCarLocation)}}>
<Image
source={this.state.isCarLocation ? require('./res/image/home_icon_location.png'):require('./res/image/home_icon_car.png')}>
</Image>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});