import React from 'react'; import ReactMapGL, { Marker } from 'react-map-gl'; import { Button } from "react-bootstrap"; import XmlReader from 'xml-reader'; import { withToastManager } from 'react-toast-notifications'; import PropTypes from 'prop-types'; import { haveSelectedGas, extractGasStationFromXml } from '../helpers'; import 'mapbox-gl/dist/mapbox-gl.css'; const mapboxToken = 'pk.eyJ1IjoiZGFya291IiwiYSI6ImNrNzkwdmlsdTBtMmwzZnM0ZmI4Z3h4czIifQ.GU2CdcMiKiApHNhI0ylGtQ'; class Map extends React.Component { constructor(props) { super(props); this.state = { viewport: { width: '100vw', height: '100vh', latitude: 44.837789, longitude: -0.57918, zoom: 11, }, userLocation: { // latitude: 44.837789, // longitude: -0.57918, }, gasStations: [], }; this.mapRef = React.createRef(); this.loadGasStations(); } componentDidMount() { this.setUserLocation(); } /** * Méthode permettant de mettre à jour la position de la map * @param {Object} viewport */ onViewportChange = (viewport) => { this.setState({ viewport }); } /** * Méthode permettant de sauvegarder la position de l'utilisateur */ setUserLocation() { navigator.geolocation.getCurrentPosition((position) => { const setUserLocation = { latitude: position.coords.latitude, longitude: position.coords.longitude, }; const newViewport = { height: '100vh', width: '100vw', latitude: position.coords.latitude, longitude: position.coords.longitude, zoom: 10, }; this.setState({ viewport: newViewport, userLocation: setUserLocation, }); }); } /** * Méthode permettant de filter sur la liste des stations affichables sur la carte * @param {Object} gasStation * @return {Boolean} */ displayThisGasStation = (gasStation) => { const mapGL = this.mapRef.getMap(); const bounds = mapGL.getBounds(); return (bounds._ne.lat > gasStation.latitude && bounds._sw.lat < gasStation.latitude) && (bounds._ne.lng > gasStation.longitude && bounds._sw.lng < gasStation.longitude); } /** * Méthode permettant de charger le fichier xml contenant la liste des stations */ loadGasStations() { const { toastManager, } = this.props; fetch('/gasStations.xml') .then((response) => response.text()) .then((response) => { const reader = XmlReader.create(); reader.on('done', (data) => { const pdv = data.children; const gasStations = []; for (let i = 0; i < pdv.length; i += 1) { const currentPdv = pdv[i]; gasStations.push(extractGasStationFromXml(currentPdv)); } this.setState((prevState) => ({ ...prevState, gasStations, })); }); reader.parse(response); }).catch(() => { toastManager.add('Erreur lors du chargement de la liste des stations', { appearance: 'error', autoDismiss: true }); }); } /** * Méthode gérant le rendu de la vue */ render() { const { viewport, userLocation, gasStations, } = this.state; const { showGasStation, selectedGasType, } = this.props; return ( <> { if (map) this.mapRef = map; }} > { Object.keys(userLocation).length !== 0 ? ( My position ) : (null) } {gasStations.filter(this.displayThisGasStation).filter((station) => haveSelectedGas(station, selectedGasType)).map((gasStation) => ( ))} ); } } Map.propTypes = { selectedGasType: PropTypes.string.isRequired, showGasStation: PropTypes.func.isRequired, toastManager: PropTypes.shape({ add: PropTypes.func, }).isRequired, }; export default withToastManager(Map);