1. 程式人生 > >react native 呼叫手機內建地圖

react native 呼叫手機內建地圖

GitHub:https://github.com/starlight36/react-native-map-linking

Android:

  • 高德地圖
  • 百度地圖

iOS:

  • 高德地圖
  • 百度地圖
  • 蘋果地圖

使用:npm install react-native-map-linking --save

ios需要在 info.plist 內配置:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>baidumap</string>
    <string>iosamap</string>
</array>

 

使用:

import MapLinking from 'react-native-map-linking';

// 喚起地圖, 並在地圖上標記一個點
MapLinking.markLocation({lat: 40, lng: 118}, 'aaa', 'bbb');

// 喚起地圖, 並讓地圖規劃從開始到結束的路線
MapLinking.planRoute({lat:40, lng: 118, title: '起點'}, {lat:40, lng: 119, title: '終點'}, 'drive');

// 喚起地圖, 併發起導航
MapLinking.navigate({lat:40, lng: 118, title: '終點'});

-----------------------------------------------------------------------

注意:

1、demo使用的是百度地圖外掛,具體配置可以看:https://blog.csdn.net/qq_39910762/article/details/82882786

2、呼叫手機內建地圖使用的是 react native 的方法 navigator.geolocation.getCurrentPosition()

原因:在demo裡使用 react native 自帶的定位,會有很大的偏差(誤差在1.2km左右,忍不了);

           而在呼叫手機地圖的時候不使用 react native 自帶的方法返回的經緯度,誤差同樣在1.2km左右

           高德地圖一樣(以測,放圖說話)

                    

 

下面是未使用react native方法的結果:

          

 

使用後:

           

 

iOS以測,OK

 

import React, { Component } from 'react';

import {
    StyleSheet,
    Text,
    View,
    ScrollView,
    Platform,
} from 'react-native';

import { MapView,MapTypes,Geolocation} from 'react-native-baidu-map';
import MapLinking from 'react-native-map-linking';
console.log(MapLinking)

import Dimensions from 'Dimensions';
const { width,height } = Dimensions.get('window');

export default class BaiduMapDemo extends Component {
    constructor() {
        super();
        this.state = {
            zoomControlsVisible: true,
            trafficEnabled: false,
            baiduHeatMapEnabled: false,
            mapType: MapTypes.NORMAL,
            zoom: 15,
            center: {
                longitude: 113.896198,
                latitude: 22.959144,
            },
            markers: [
                {
                    longitude: 113.896198,
                    latitude: 22.959144,
                    title: 'title',
                }
            ],
            clickMessage: '',
            poiMessage: '',
        };
    }
    lat = '';
    lng = '';
    componentDidMount() {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                console.log(position)
                position = position.coords;
                lat = position.latitude;
                lng = position.longitude;
            },
            (error) => alert(error.message),
        )
    }

  render() {
        return (
            <View style={styles.container}>
                <MapView 
                    zoomControlsVisible={this.state.zoomControlsVisible} //預設true,是否顯示縮放控制元件,僅支援android
                    trafficEnabled={this.state.trafficEnabled} //預設false,是否顯示交通線
                    baiduHeatMapEnabled={this.state.baiduHeatMapEnabled} //預設false,是否顯示熱力圖
                    mapType={this.state.mapType} //地圖模式,NORMAL普通 SATELLITE衛星圖
                    zoom={this.state.zoom} //縮放等級,預設為10
                    center={this.state.center} // 地圖中心位置
                    markers={this.state.markers} //地圖多個標記點

                    onMapLoaded={(e) => { //地圖載入事件
                        Geolocation.getCurrentPosition()
                            .then(data => {
                                // console.log(data)
                                this.setState({
                                    center: {
                                        longitude: data.longitude,
                                        latitude: data.latitude
                                    },
                                    markers: [{
                                        longitude: data.longitude,
                                        latitude: data.latitude,
                                        title: data.district + data.street
                                    }]
                                })
                            })
                            .catch(e =>{
                                console.warn(e, 'error');
                            })
                    }}
                    
                    onMarkerClick={(e) => { //標記點點選事件
                        console.log(e)
                    }}
                    onMapClick={(e) => { //地圖空白區域點選事件,返回經緯度
                        let title = '';
                        Geolocation.reverseGeoCode(e.latitude,e.longitude)
                            .then(res => {
                                console.log(res)
                                Platform.OS == 'ios' ? 
                                    title = res.district + res.streetName
                                :
                                    title = res.district + res.street;
                                this.setState({
                                    center: {
                                        longitude: e.longitude,
                                        latitude: e.latitude,
                                    },
                                    markers: [{
                                        longitude: e.longitude,
                                        latitude: e.latitude,
                                        title: title,
                                    }],
                                    clickMessage: JSON.stringify(res)
                                })
                            })
                            .catch(err => {
                                console.log(err)
                            })
                        
                    }}
                    onMapPoiClick={(e) => { //地圖已有點點選
                        Geolocation.reverseGeoCode(e.latitude,e.longitude)
                            .then(res => {
                                res = JSON.stringify(res)
                                this.setState({
                                    center: {
                                        longitude: e.longitude,
                                        latitude: e.latitude,
                                    },
                                    markers: [{
                                        longitude: e.longitude,
                                        latitude: e.latitude,
                                        title: e.name,
                                    }],
                                    poiMessage: res
                                })
                            })
                            .catch(err => {
                                console.log(err)
                            })
                    }}
                    style={styles.map}
                >
                </MapView>

                <View style={styles.list}>
                    <Text>地圖縮放控制元件狀態: </Text>
                    {this.state.zoomControlsVisible ? 
                        <Text onPress={() => this.setState({zoomControlsVisible:false})}>顯示</Text>
                        :
                        <Text onPress={() => this.setState({zoomControlsVisible:true})}>關閉</Text>
                    }
                </View>
                <View style={styles.list}>
                    <Text>交通線狀態: </Text>
                    {this.state.trafficEnabled ? 
                        <Text onPress={() => this.setState({trafficEnabled:false})}>顯示</Text>
                        :
                        <Text onPress={() => this.setState({trafficEnabled:true})}>關閉</Text>
                    }
                </View>
                <View style={styles.list}>
                    <Text>熱力圖狀態: </Text>
                    {this.state.baiduHeatMapEnabled ? 
                        <Text onPress={() => this.setState({baiduHeatMapEnabled:false})}>顯示</Text>
                        :
                        <Text onPress={() => this.setState({baiduHeatMapEnabled:true})}>關閉</Text>
                    }
                </View>
                <View style={styles.list}>
                    <Text>地圖模式狀態: </Text>
                    {this.state.mapType == MapTypes.NORMAL ? 
                        <Text onPress={() => this.setState({mapType:MapTypes.SATELLITE})}>普通</Text>
                        :
                        <Text onPress={() => this.setState({mapType:MapTypes.NORMAL})}>衛星</Text>
                    }
                </View>
                <View style={styles.list}>
                    <Text>地圖空白區域點選資訊: </Text>
                </View>
                <View style={styles.list}>
                    <Text>{this.state.clickMessage}</Text>
                </View>
                <View style={styles.list}>
                    <Text>地圖已有點點選資訊: </Text>
                </View>
                <View style={styles.list}>
                    <Text>{this.state.poiMessage}</Text>
                </View>
                <View style={styles.list}>
                    <Text onPress={() => {
                        Geolocation.getCurrentPosition()
                            .then(data => {
                                console.log(data)
                                this.setState({
                                    center: {
                                        longitude: data.longitude,
                                        latitude: data.latitude
                                    },
                                    markers: [{
                                        longitude: data.longitude,
                                        latitude: data.latitude,
                                        title: data.district + data.street
                                    }]
                                })
                            })
                            .catch(e =>{
                                console.warn(e, 'error');
                            })
                    }}>當前位置</Text>
                </View>
                <View style={styles.list}>
                    <Text 
                        onPress={() => {
                            let data = this.state.markers;
                            data = data[0];
                            console.log(data)
                            MapLinking.markLocation({
                                lat: lat,
                                lng: lng,
                            },
                            data.title,data.title)}
                        }
                    >
                        調起手機地圖地點
                    </Text>
                </View>
                <View style={styles.list}>
                    <Text 
                        onPress={() => {
                            let data = this.state.markers;
                            data = data[0];
                            console.log(data)
                            MapLinking.planRoute({
                                lat: lat,
                                lng: lng,
                                title: '起點'
                            },{
                                lat: data.latitude,
                                lng: data.longitude,
                                title: '終點'
                            }, 'bus')}  // drive 駕車 bus 公交 walk 步行(預設)
                        }
                    >
                        手機地圖規劃路線
                    </Text>
                </View>
                <View style={styles.list}>
                    <Text 
                        onPress={() => {
                            let data = this.state.markers;
                            data = data[0];
                            console.log(data)
                            MapLinking.navigate({
                                lat: data.latitude,
                                lng: data.longitude,
                                title: data.title,
                            })}
                        }
                    >
                        調起手機地圖導航
                    </Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    map: {
        width: width,
        height: height - 300,
        marginBottom: 5,
    },
    list: {
        flexDirection: 'row',
        paddingLeft: 10,
        marginBottom: 5,
    }
});