简体   繁体   中英

Is there a way to hide react-native-maps markers?

I am working on a tourism application, containing a map with markers made using my data. I want to add the option to "filter" its markers. The user can press buttons "Restaurants", "Hotels," Commerces" to display only the selected markers.

(The user presses on "Restaurants" -> Show only restaurant markers, here is a picture of the idea:

地图和标记

Here is the code of my Axios request, nothing big:

import axios from 'axios';

// URL API BASE
const APIURL = 'http://10.22.101.55:5000/api';


// RECUPERATION DES RESTAURANTS
export const getAllRestaurant = (nom, adresse, ville, cp, telephone, email, latitude, longitude ) => axios.get(`${APIURL}/restaurant`, {
    nom: nom,
    adresse: adresse,
    ville: ville,
    cp: cp,
    telephone: telephone,
    email: email,
    latitude: latitude,
    longitude: longitude
});

// RECUPERATION DES HôTELS
export const getAllHotel = (nom, adresse, ville, cp, telephone, email, latitude, longitude ) => axios.get(`${APIURL}/hotel`, {
    nom: nom,
    adresse: adresse,
    ville: ville,
    cp: cp,
    telephone: telephone,
    email: email,
    latitude: latitude,
    longitude: longitude
});

// RECUPERATION DES COMMERCES
export const getAllCommerce = (nom, adresse, ville, cp, telephone, email, latitude, longitude ) => axios.get(`${APIURL}/commerce`, {
    nom: nom,
    adresse: adresse,
    ville: ville,
    cp: cp,
    telephone: telephone,
    email: email,
    latitude: latitude,
    longitude: longitude
});

And the code of my page, I made sure to separate the different categories hoping that it would be easier:

import React, { useEffect } from 'react';
import { View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import { ScrollView, TextInput } from 'react-native-gesture-handler';
import MapView, { Marker } from 'react-native-maps';
import Ionicons from 'react-native-vector-icons/Ionicons';


// Récupération des données
import {getAllRestaurant, getAllHotel, getAllCommerce} from '../service/Emplacements'

export default function AccueilScreen() {

  // RECUPERATION DES RESTAURANTS
  const [restaurants, setRestaurants] = React.useState([])
  const LesRestaurants = () => [
    getAllRestaurant().then(response => {
      setRestaurants(response.data);
    }).catch(err => console.log(err))
  ]

  // RECUPERATION DES HÔTELS
  const [hotels, setHotels] = React.useState([])
  const LesHotels = () => [
    getAllHotel().then(response => {
      setHotels(response.data);
    }).catch(err => console.log(err))
  ]

  // RECUPERATION DES COMMERCES
  const [commerces, setCommerces] = React.useState([])
  const lesCommerces = () => [
    getAllCommerce().then(response => {
      setCommerces(response.data);
    }).catch(err => console.log(err))
  ]

  // AFFICHAGE DES MARKERS RESTAURANTS
  const afficheRestaurant = restaurants.map((restaurant) => (
    <Marker
      pinColor='#fdca40'
      key={restaurant.id}
      coordinate={{latitude: restaurant.latitude, longitude: restaurant.longitude}}
      title={restaurant.nom}
    />
  )) 

  // AFFICHAGE DES MARKERS HÔTELS
  const afficheHotel = hotels.map((hotel) => (
    <Marker
      pinColor='#2978b5'
      key={hotel.id}
      coordinate={{latitude: hotel.latitude, longitude: hotel.longitude}}
      title={hotel.nom}
    />
  ))

  // AFFICHAGE DES MARKERS COMMERCES
  const afficheCommerce = commerces.map((commerce) => (
    <Marker
      pinColor='#8fd9a8'
      key={commerce.id}
      coordinate={{latitude: commerce.latitude, longitude: commerce.longitude}}
      title={commerce.nom}
    />
  ))

  // FILTRE RESTAURANT
  const onlyRestaurant = () => {
    afficheCommerce = commerces.map((null))
    afficheHotel = hotels.map((null))
  }

  // CHARGEMENT DES EMPLACEMENTS
  useEffect(() => {
    LesRestaurants()
    LesHotels()
    lesCommerces()
  },[])


  return (
    <View style={styles.container}>

      {/* -- MAP ET MARKERS -- */}
      <MapView
        customMapStyle={MapStyle}
        scrollEnabled={false}
        rotateEnabled={false}
        zoomEnabled={false}
        minZoomLevel={0}
        maxZoomLevel={13}
        style={styles.container}
        region={{
          latitude: 49.4826616,
          longitude: 1.7245633,
          latitudeDelta: 0.015,
          longitudeDelta: 0.0121,
        }}
      >
        {afficheRestaurant}

        {afficheHotel}

        {afficheCommerce}

      </MapView>

      {/* -- BARRE RECHERCHE -- */}
      <View style={styles.searchBox}>
        <TextInput
          placeholder='Rechercher un lieu ...'
          placeholderTextColor='#fb3640'
          style={{flex: 1, padding: 0}}
        />
        <Ionicons name='search-outline' size={20}/>
      </View>

      {/* -- FILTRE -- */}
      <ScrollView
        horizontal
        scrollEventThrottle={1}
        showsHorizontalScrollIndicator={false}
        height={50}
        style={styles.scroll}
        contentContainerStyle={{paddingRight: 20}}
      >

        <TouchableOpacity style={styles.itemAll}>
          <Ionicons size={15} name='options-outline'>  Tout</Ionicons>
        </TouchableOpacity>

        <TouchableOpacity style={styles.itemRestaurant} onPress={onlyRestaurant}>
          <Ionicons size={15} name='restaurant-outline'>  Restaurant</Ionicons>
        </TouchableOpacity>

        <TouchableOpacity style={styles.itemHotel}>
          <Ionicons size={15} name='bed-outline'>  Hôtel</Ionicons>
        </TouchableOpacity>

        <TouchableOpacity style={styles.itemCommerce}>
          <Ionicons size={15} name='cart-outline'>  Commerce</Ionicons>
        </TouchableOpacity>

      </ScrollView>

   </View>
  );
}

// STYLE DE LA PAGE
{...}

 // STYLE DE LA CARTE
 {...}

I did some testing (const onylRestaurant) but nothing good (.map can be null, or read-only errors).

I wanted to know if you have any ideas that I can use

Thanks for any help!

Do not hesitate to ask me for additional information, I'm still new to react-native but I will do my best to answer you

You are on the right path.

Have another state variable in your Component.

const [currentCategory, setCurrentCategory] = React.useState('All');

When the user clicks on any button, update this variable with corresponding category.

Then use this new state variable to decide which markers you want to show. Something like this.

const getMarkers = () => {
    switch (currentCategory) {
        case 'hotel': return afficheHotel;
        case 'restaurant': return afficheRestaurant;
        case 'commerce': return afficheCommerce;
        default: return [...afficheHotel, ...afficheRestaurant, ...afficheCommerce];
    }
}

Now write a function to update this state variable by handling onClick

const onCategoryClick = category => {
    setCurrentCategory(category);
}

Now use the above function in your code like this

<TouchableOpacity style={styles.itemAll} onPress={() => onCategoryClick('All')}>
      <Ionicons size={15} name='options-outline'>  Tout</Ionicons>
</TouchableOpacity>

<TouchableOpacity style={styles.itemRestaurant} onPress={() => onCategoryClick('restaurant')}>
      <Ionicons size={15} name='restaurant-outline'>  Restaurant</Ionicons>
</TouchableOpacity>

<TouchableOpacity style={styles.itemHotel} onPress={() => onCategoryClick('hotel')}>
      <Ionicons size={15} name='bed-outline'>  Hôtel</Ionicons>
</TouchableOpacity>

<TouchableOpacity style={styles.itemCommerce} onPress={() => onCategoryClick('commerce')}>
      <Ionicons size={15} name='cart-outline'>  Commerce</Ionicons>
</TouchableOpacity>

Finally, you would have to update your code to remove this part inside your MapView

{afficheRestaurant}

{afficheHotel}

{afficheCommerce}

and in its place add this

{getMarkers()}

so your Mapview will be this,

<MapView
    customMapStyle={MapStyle}
    scrollEnabled={false}
    rotateEnabled={false}
    zoomEnabled={false}
    minZoomLevel={0}
    maxZoomLevel={13}
    style={styles.container}
    region={{
      latitude: 49.4826616,
      longitude: 1.7245633,
      latitudeDelta: 0.015,
      longitudeDelta: 0.0121,
    }}
  >
    {getMarkers()}
</MapView>

Does this work?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM