React-native-maps和Geolocation无法正确获取位置

如何解决React-native-maps和Geolocation无法正确获取位置

我对学习React Native还是一个新手,很感谢我的代码可以提供的任何帮助。我目前正在研究教程,已经被困了几个小时。希望这是足够的信息,以获得一些帮助。预先感谢!

我的目标

我正在尝试按此顺序做三件事:

  1. 获取用户的当前位置
  2. 从API中获取商品数据(以下概述的示例)。应该注意的是,最终获取的内容将取决于用户的当前位置。
  3. 解析项目数据以创建标记和唯一的类别列表,然后将其放置在地图上,并以用户当前的位置为中心。

我希望能够观察用户的位置并相应地移动和更新地图。在所有标记都到位之前,我也不想显示地图。

这是我的react版本:react-native-cli:2.0.1 react-native:0.63.2

我的错误

我同时使用Android Studio模拟器和Xcode模拟器,并且目前遇到以下问题:

  1. Xcode上的iOS模拟器第一次呈现良好效果,但是在随后的刷新中,我发现5个标记中的一两个缺失。
  2. 在Android上,地图会完美加载,然后立即重新绘制地图并以加利福尼亚州的Googleplex为中心,而不是用户当前的位置。 Emulator location is set to London,UK

我怀疑在地图渲染之前我可能会在获取物品和当前位置时遇到某些比赛情况,但是我不确定。

我的代码

//我的API响应结构

{
"id": "96845","title": "Item_title_goes_here","image": "https://someURL/image.JPG","stories": 46,"lat": some_lat_number,"lon": some_lon_number,"category": "category_name","description": "long_description"
},
//ajax.js 

export default {
    async fetchInitialItems() {
        try {
            const response = await fetch(apiHost + '/api/v1/items/');
            const responseJson = await response.json();
            return responseJson;
        } catch (error) {
            console.error(error);
        }
    },async fetchItemDetail(itemId) {
        try {
            const response = await fetch(apiHost + '/api/items/' + itemId);
            const responseJson = await response.json();
            return responseJson;
        } catch (error) {
            console.error(error);
        }
    },};
//ExploreScreen.js (my map component)

import React,{ Component } from 'react';
import {
    View,Text,StyleSheet,Image,Animated,Dimensions,TouchableOpacity,PermissionsAndroid,ScrollView,Platform,StatusBar,} from 'react-native';
import MapView,{
    PROVIDER_GOOGLE,Marker,Callout,Polygon,} from 'react-native-maps';
import PropTypes from 'prop-types';
import Geolocation from '@react-native-community/geolocation';
import { mapDarkStyle,mapStandardStyle } from '../model/mapData';
import ajax from '../utils/ajax';
import MapCarousel from './MapCarousel';

import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Fontisto from 'react-native-vector-icons/Fontisto';

import StarRating from '../components/StarRating';

/**
|--------------------------------------------------
| Variables
|--------------------------------------------------
*/
const { width,height } = Dimensions.get('window');

const SCREEN_HEIGHT = height;
const SCREEN_WIDTH = width;
const ASPECT_RATIO = width / height;
const LATITUDE_DELTA = 0.0422;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
const darkTheme = false;


/**
|--------------------------------------------------
| Component
|--------------------------------------------------
*/
class ExploreScreen extends React.Component {
    /****** Props & States ******/

    state = {
        region: {
            latitude: 0,longitude: 0,latitudeDelta: LATITUDE_DELTA,longitudeDelta: LONGITUDE_DELTA,},items: [],markers: [],categories: [],currentMapRegion: null,};

    /****** Functions ******/

    ///when carousel item selected
    onCarouselItemSelected() {
        alert('carousel item selected');
    }

    //when the carousel in scrolled
    onCarouselIndexChange(itemID) {
        const item = this.state.items.find(item => item.id == itemID);
        const marker = this.state.markers.find(marker => marker.id == itemID);
        const coordinates = { lat: item.lat,lon: item.lon };

        this.goToLocation(coordinates);
    }

    //get current position
    getLocation(that) {
        Geolocation.getCurrentPosition(
            //get the current location
            position => {
                const region = {
                    latitude: parseFloat(position.coords.latitude),longitude: parseFloat(position.coords.longitude),};
                that.setState({ region });
            },error => alert(error.message),{ enableHighAccuracy: true,timeout: 20000 },);
        //get location on location change
        that.watchID = Geolocation.watchPosition(position => {
            const currentRegion = {
                latitude: position.coords.latitude,longitude: position.coords.longitude,};
            this.setState({ region: currentRegion });
        });
    }
    //move map to a lat/lon
    goToLocation(coordinates) {
        if (this.map) {
            this.map.animateToRegion({
                latitude: coordinates.lat,longitude: coordinates.lon,});
        }
    }

    //when the region changes for the map
    onRegionChangeComplete(region) {
        //I dont know what to do here 
    }

    //move map to center of current location
    gotToCenter() {
        if (this.map) {
            this.map.animateToRegion({
                latitude: this.state.region.latitude,longitude: this.state.region.longitude,});
        }
    }
    //map the categories store in the state
    mapCategories = () => {
        const uniqueCategories = [];
        this.state.items.map(item => {
            if (uniqueCategories.indexOf(item.category) === -1) {
                uniqueCategories.push(item.category);
            }
        });
        this.setState({ categories: uniqueCategories });
    };

    //map the items to markers and store in the state
    mapMarkers = () => {
        const markers = this.state.items.map(item => (
            <Marker
                key={item.id}
                coordinate={{ latitude: item.lat,longitude: item.lon }}
                image={require('../assets/map_marker.png')}
                tracksViewChanges={false}
                title={item.title}
                description={item.description}
            />
        ));
        this.setState({ markers: markers });
    };

    /****** Lifecycle Functions ******/
    async componentDidMount() {
        var that = this;
        //Checking for the permission just after component loaded
        if (Platform.OS === 'ios') {
            //for ios
            this.getLocation(that);
        } else {
            //for android
            async function requestLocationPermission() {
                try {
                    const granted = await PermissionsAndroid.request(
                        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,{
                            title: 'Location Access Required',message: 'This App needs to Access your location',);
                    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                        //To Check,If Permission is granted
                        that.getLocation(that);
                    } else {
                        alert('Permission Denied');
                    }
                } catch (err) {
                    alert('err',err);
                    console.warn(err);
                }
            }
            requestLocationPermission();
        }

        //get location on location change
        that.watchID = Geolocation.watchPosition(position => {
            const currentRegion = {
                latitude: parseFloat(position.coords.latitude),};

            this.setState({ region: currentRegion });
        });

        console.log(this.state.region);

        const items = await ajax.fetchInitialItems();
        this.setState({ items });
        this.mapMarkers();
        this.mapCategories();
    }

    componentWillUnmount = () => {
        Geolocation.clearWatch(this.watchID);
    };

    render() {
        const lat = this.state.region.latitude;
        const lon = this.state.region.longitude;

        if (this.state.items && lat && lon) {
            return (
                <View>
                    <MapView
                        ref={map => {
                            this.map = map;
                        }}
                        onRegionChangeComplete={this.onRegionChangeComplete.bind(this)}
                        toolbarEnabled={false}
                        showsMyLocationButton={false}
                        provider={PROVIDER_GOOGLE}
                        style={styles.map}
                        customMapStyle={darkTheme ? mapDarkStyle : mapStandardStyle}
                        showsUserLocation={true}
                        followsUserLocation={true}
                        region={this.state.region}>
                        {this.state.markers}
                    </MapView>
                    {/* center button */}
                    <TouchableOpacity
                        onPress={this.gotToCenter.bind(this)}
                        style={styles.centerButtonContainer}>
                        <Ionicons name="md-locate" size={20} />
                    </TouchableOpacity>
                    <View style={styles.carousel}>
                        <MapCarousel
                            data={this.state.items}
                            onPressItem={() => {
                                this.onCarouselItemSelected.bind(this);
                            }}
                            onUpdateLocation={this.onCarouselIndexChange.bind(this)}
                        />
                    </View>
                </View>
            );
        } else {
            return (
                <View style={styles.container}>
                    <Text style={styles.header}>Loading...</Text>
                </View>
            );
        }
    }
}

/**
|--------------------------------------------------
| Styles
|--------------------------------------------------
*/
const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,height: '100%',width: '100%',justifyContent: 'center',alignItems: 'center',map: {
        height: '100%',carousel: {
        position: 'absolute',bottom: 25,header: {
        fontSize: 50,//character name
    name: {
        fontSize: 15,marginBottom: 5,//character image
    image: {
        width: 170,height: 80,//center button
    centerButtonContainer: {
        width: 40,height: 40,position: 'absolute',bottom: 260,right: 10,borderColor: '#191919',borderWidth: 0,borderRadius: 30,backgroundColor: '#d2d2d2',shadowColor: '#000',shadowOffset: {
            width: 0,height: 9,shadowOpacity: 0.48,shadowRadius: 11.95,elevation: 18,opacity: 0.9,});

export default ExploreScreen;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-