动态渲染 React Native 的 MapView 标记

3
这是我的地图视图的样子:
<MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,


            }}
            >
            <Marker
                coordinate={{
                    latitude:51.524464,
                    longitude:-0.036285,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 1"}
                description={customData.text1} 
            />
            <Marker
                coordinate={{
                    latitude:51.524310,
                    longitude:-0.037798,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 2"}
                description={customData.text2}
            />
            <Marker
                coordinate={{
                    latitude:51.523174,
                    longitude:-0.039332,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 3"}
                description={customData.text3}
            />

            </MapView>

您可以看到,我已经硬编码了3个标记来确保 MapViews 正常工作。现在,我使用外部 API 根据用户的输入告知停车位。例如,如果用户输入某个邮政编码/邮区编码,API 将返回一个数组,其中包含有关停车位的各种信息,如经度和纬度。我想在地图上用标记表示这些停车位。我使用 FlatList 来实现:

<FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude)
                    }}

                    title = {"parking markers"}

                    />  

                }}
                keyExtractor={item => item.unique_identifier}

            />

我没有收到任何错误信息,但是我无法在地图上看到标记。以下是我的完整代码:

import React ,{Component,useState,useEffect} from 'react'
import {View,Text,StyleSheet,Dimensions,Button,Alert,FlatList} from 'react-native'
import MapView , {Marker}from 'react-native-maps'
import axios from 'axios'
import { TextInput } from 'react-native-gesture-handler'
import camdenParking from '../api/camdenParking'
import SearchBar from '../components/SearchBar'



/// Key Secret : 5ulg30lagu2o493uwsmn24rxklsg0ivb05k2zl6xqhiz8js9e7
/// App Secret Token : NTEX14nQLbrS8MIz4RmC6riUV6K2aQ_j687H


const HomeScreen = ()=>

{

    const [parkingSpaces,setparkingSpaces] = useState([])
    const[term,setTerm] = useState('')
    let userLatitude = 0
    let userLongitude = 0 

    const customData = require("./MarkersText.json")


      const searchApi = async() => {

        const response = await camdenParking.get("",{

            params:{
                //longitude:-0.115444,
                //latitude:51.517597
                postcode: term


            }

        }) // you can change this later on
        console.log(response.data)
        setparkingSpaces(response.data)
        console.log(term)      
      }


      const findCoordinates = () => {
        navigator.geolocation.getCurrentPosition(
          position => {
            const locationString = JSON.stringify(position); // Here we get the JSON object but it needs to be parsed
            var longLat = JSON.parse(locationString); // Here we parse the JSON object

             userLatitude=longLat.coords.latitude
             userLongitude=longLat.coords.longitude

             console.log(userLatitude) // This prints the current latitude from the user
             console.log(userLongitude) // This prints the longitude



          },
          error => Alert.alert(error.message),
          { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
        );
      };


     //useEffect(()=>{
       // searchApi()
     //},[])



    return(


        <View style={styles.container}>
            <SearchBar 
                term={term}
                onTermChange={newTerm=>setTerm(newTerm)}
                onTermSubmit={()=> searchApi(term)}
                />
            <MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,


            }}
            >
            <Marker
                coordinate={{
                    latitude:51.524464,
                    longitude:-0.036285,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 1"}
                description={customData.text1} 
            />
            <Marker
                coordinate={{
                    latitude:51.524310,
                    longitude:-0.037798,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 2"}
                description={customData.text2}
            />
            <Marker
                coordinate={{
                    latitude:51.523174,
                    longitude:-0.039332,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 3"}
                description={customData.text3}
            />

            </MapView>
            <Text>We have found {parkingSpaces.length} results</Text>
            <Button onPress={searchApi} title=" Click Here To Get Parking Spaces" />
            <Button onPress={findCoordinates} title=" Click Here To Get User's Location" />
            <Text>Parking Spaces found around {term}</Text>

            <FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude)
                    }}

                    title = {"parking markers"}

                    />  

                }}
                keyExtractor={item => item.unique_identifier}

            />

            <FlatList 
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <Text> {item.road_name} | Possible Available Spaces:{item.parking_spaces} </Text>

                }}
            keyExtractor={item => item.unique_identifier}

            />


        </View>
    );
};

const styles = StyleSheet.create(
    {
     container:{
         flex:1,
         backgroundColor: '#fff',
         //alignItems: 'center',
         //justifyContent: 'center',
         //...StyleSheet.absoluteFillObject,
         //marginLeft:0,
         //height:400,
         //width:400,
         //justifyContent:"flex-end",
         //alignItems:"center",   
     },

     mapStyle: {
        width: 400,
        height:400, 
        //width: Dimensions.get('window').width,
        //height: Dimensions.get('window').height,
      },
    }

)

export default HomeScreen

更新

现在我的代码如下所示:

import React ,{Component,useState,useEffect} from 'react'
import {View,Text,StyleSheet,Dimensions,Button,Alert,FlatList} from 'react-native'
import MapView , {Marker}from 'react-native-maps'
import axios from 'axios'
import { TextInput } from 'react-native-gesture-handler'
import camdenParking from '../api/camdenParking'
import SearchBar from '../components/SearchBar'



/// Key Secret : 5ulg30lagu2o493uwsmn24rxklsg0ivb05k2zl6xqhiz8js9e7
/// App Secret Token : NTEX14nQLbrS8MIz4RmC6riUV6K2aQ_j687H


const HomeScreen = ()=>

{

    const [parkingSpaces,setparkingSpaces] = useState([])
    const[term,setTerm] = useState('')
    let userLatitude = 0
    let userLongitude = 0 

    const customData = require("./MarkersText.json")


      const searchApi = async() => {

        const response = await camdenParking.get("",{

            params:{
                //longitude:-0.115444,
                //latitude:51.517597
                postcode: term


            }

        }) // you can change this later on
        console.log(response.data)
        setparkingSpaces(response.data)
        console.log(term)      
      }


      const findCoordinates = () => {
        navigator.geolocation.getCurrentPosition(
          position => {
            const locationString = JSON.stringify(position); // Here we get the JSON object but it needs to be parsed
            var longLat = JSON.parse(locationString); // Here we parse the JSON object

             userLatitude=longLat.coords.latitude
             userLongitude=longLat.coords.longitude

             console.log(userLatitude) // This prints the current latitude from the user
             console.log(userLongitude) // This prints the longitude



          },
          error => Alert.alert(error.message),
          { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
        );
      };


     //useEffect(()=>{
       // searchApi()
     //},[])



    return(


        <View style={styles.container}>
            <SearchBar 
                term={term}
                onTermChange={newTerm=>setTerm(newTerm)}
                onTermSubmit={()=> searchApi(term)}
                />
            <MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,
                }}
                >
                {parkingSpaces.map((val, index) => {
                return (<MapView.Marker
                        coordinate={{
                        latitude: parseInt(val.latitude),
                        longitude:parseInt(val.longitude)
                        }}
                        key={index}
                        title = {"parking markers"}
                        />); 

                })}

            </MapView>

            <Text>We have found {parkingSpaces.length} results</Text>
            <Button onPress={searchApi} title=" Click Here To Get Parking Spaces" />
            <Button onPress={findCoordinates} title=" Click Here To Get User's Location" />
            <Text> WC2A 3PD</Text>
            <Text>Parking Spaces found around {term}</Text>

            <FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude),
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                    }}

                    title = {"parking markers"}
                    description = {"parking"}


                    />  

                }}
                keyExtractor={item => item.unique_identifier}


            />

            <FlatList 
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <Text> {item.road_name} | Possible Available Spaces:{item.parking_spaces} </Text>

                }}
            keyExtractor={item => item.unique_identifier}

            />


        </View>
    );
};

const styles = StyleSheet.create(
    {
     container:{
         flex:1,
         backgroundColor: '#fff',
         //alignItems: 'center',
         //justifyContent: 'center',
         //...StyleSheet.absoluteFillObject,
         //marginLeft:0,
         //height:400,
         //width:400,
         //justifyContent:"flex-end",
         //alignItems:"center",   
     },

     mapStyle: {
        width: 400,
        height:400, 
        //width: Dimensions.get('window').width,
        //height: Dimensions.get('window').height,
      },
    }

)

export default HomeScreen
1个回答

3
第一个问题是使用FlatList作为标记的容器。解决方法是在MapView之间映射parkingSpaces数组。第二个问题是对坐标调用parseInt,这会导致地图根本不呈现您的标记。此外,您会失去精度。
代码:
<MapView
 style={styles.mapStyle}
 initialRegion={{
 latitude: 51.524300,
 longitude: -0.037790,
 latitudeDelta: 0.0122,
 longitudeDelta: 0.0421,
}}
 >
 {parkingSpaces.map((val, index) => {
  return (<MapView.Marker
          coordinate={{
          latitude: val.latitude,
          longitude: val.longitude
          }}
          key={index}
          title = {"parking markers"}
         />); 
 })}

</MapView>

演示:

https://snack.expo.io/@tim1717/mature-croissant


我尝试使用了你的解决方案。它看起来是正确的,我很感激你的帮助。但现在我遇到了这个错误: 警告:列表中的每个子元素都应该有一个唯一的“key”属性。%s%s 请参见... - cristian9804
1
@cristian9804 这很容易解决。您需要向标记添加一个键属性。请查看我的编辑答案。 - Tim
我已经按照你在演示中展示的方式添加了一个键。然而,地图视图上没有任何标记呈现出来。我不知道如何向你展示我现在拥有的代码。 - cristian9804
@cristian9804,您可以编辑您的问题并添加一个包含您当前代码的额外代码片段,但请确保不要覆盖/删除您之前的代码。 - Tim
@cristian9804,你应该从代码中删除具有标记的FlatList,因为你不需要它。如果问题得到解决,请告诉我。 - Tim
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接