Quiero preguntar si uso un mapa de React Leaflet ( https://react-leaflet.js.org/ ), pero ¿cómo agrego un botón de ubicación al mapa? así un ejemplo de la ubicación me botón en la imagen que le di la flecha roja
Y fotos en el enlace:
Ejemplo de una flecha Ubicarme
Un ejemplo en mi mapa donde quiero agregar la ubicación Yo
¿Y cómo mostrar el botón de ubicación, dónde lo guardas de mi codificación?
import { React, useState } from 'react' import { LayersControl, MapContainer, Marker, Popup, TileLayer, useMapEvents, } from 'react-leaflet' const { BaseLayer } = LayersControl function LocationMarker() { const [position, setPosition] = useState(null) const map = useMapEvents({ click() { map.locate() }, locationfound(e) { setPosition(e.latlng) map.flyTo(e.latlng, map.getZoom()) }, }) return position === null ? null : ( <Marker position={position}> <Popup>You are here</Popup> </Marker> ) } function MapsMe() { return ( <div className="flex ml-auto"> <div className="w-4/5"> <MapContainer center={51.505, -0.09} zoom=20> <LayersControl> <BaseLayer checked name="OpenStreetMap"> <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png " /> </BaseLayer> <LocationMarker /> </LayersControl> </MapContainer> </div> </div> ) } export default MapsMeSi necesita obtener exactamente el mismo resultado que en su imagen, debe usar la biblioteca leaflet-easybutton con font-awesome . De lo contrario, puede crear fácilmente su propio icono ampliando el control del folleto.
instalarlos:
npm i leaflet-easybutton npm i font-awesomeimportarlos:
import "leaflet-easybutton/src/easy-button.js"; import "leaflet-easybutton/src/easy-button.css"; import "font-awesome/css/font-awesome.min.css"; Cree una instancia L.easy-button usando el ícono fa-map-marker y dentro de la devolución de llamada, guarde la posición y mueva el mapa a la ubicación del usuario.
export default function Map() { const [map, setMap] = useState(null); const [position, setPosition] = useState(null); useEffect(() => { if (!map) return; L.easyButton("fa-map-marker", () => { map.locate().on("locationfound", function (e) { setPosition(e.latlng); map.flyTo(e.latlng, map.getZoom()); }); }).addTo(map); }, [map]); return ( <MapContainer center={[51.505, -0.09]} zoom={20} style={{ height: "100vh" }} whenCreated={setMap} > ... }Aquí hay una demostración . Cuando lo abra, el ícono no aparecerá porque hay un problema conocido con los íconos svg y codesandbox, pero localmente no debería tener ningún problema.
Así es como resuelvo el mismo problema. Creó un componente reutilizable para los controles de folletos. Solo una forma elegante de manejar fácilmente las clases de folletos.
import L from "leaflet"; import React, { useEffect, useRef } from "react"; const ControlClasses = { bottomleft: "leaflet-bottom leaflet-left", bottomright: "leaflet-bottom leaflet-right", topleft: "leaflet-top leaflet-left", topright: "leaflet-top leaflet-right", }; type ControlPosition = keyof typeof ControlClasses; interface LeafLetControlProps { position?: ControlPosition; } const LeafletControl: React.FC<LeafLetControlProps> = ({ position, children, }) => { const divRef = useRef(null); useEffect(() => { if (divRef.current) { L.DomEvent.disableClickPropagation(divRef.current); L.DomEvent.disableScrollPropagation(divRef.current); } }); return ( <div ref={divRef} className={position && ControlClasses[position]}> <div className={"leaflet-control"}>{children}</div> </div> ); }; export default LeafletControl;Utilice el componente de control de folletos con la funcionalidad que desee.
import { ActionIcon } from "@mantine/core"; import React, { useState } from "react"; import { useMapEvents } from "react-leaflet"; import { CurrentLocation } from "tabler-icons-react"; import LeafletControl from "./LeafletControl"; interface LeadletMyPositionProps {} const LeadletMyPosition: React.FC<LeadletMyPositionProps> = ({}) => { const [loading, setLoading] = useState<boolean>(false); const map = useMapEvents({ locationfound(e) { map.flyTo(e.latlng); setLoading(false); }, }); return ( <LeafletControl position={"topright"}> <ActionIcon onClick={() => { setLoading(true); map.locate(); }} loading={loading} variant={"transparent"} > <CurrentLocation /> </ActionIcon> </LeafletControl> ); }; export default LeadletMyPosition;