Me gustaría tener un mapa usando OpenStreetMap que muestre la ubicación de las flores. Mi punto es tener LayersControl
con colours
y type
y poder verificar, por ejemplo, Orange
y Tulip
y ver solo tulipanes naranjas en el mapa, pero parece difícil por lo que leí en la documentación de React LeafLet.
Para que sea más fácil de entender, agregaré un código:
Ejemplo de datos de flores:
const flowers = [ { "type": "Tulip", "colour": "Orange", "latlng": [52.081222, 5.235965], }, { "type": "Crocus", "colour": "Red", "latlng": [52.081421, 5.235534], }, ]
LeafletMap.jsx (parcial):
const LeafletMap: React.FC = () => { return ( <MapContainer id="mapId" center={averagePos} zoom={zoom}> {flowerItems.map((flower, index) => ( //Maybe do something here like sorting and creating //multiple layers //or having already a layer for every type of search //but if i want to add more colours ou type it can be very hard to update ))} </LayersControl> </MapContainer> ) }
Puede mantener las capas seleccionadas usando variables de estado: una matriz para rastrear el type
(Azafrán o Tulipán) y otra para rastrear el colour
(rojo o naranja). Inicialmente, los estados están configurados para mostrar todo:
const [type, setType] = useState(['Tulip', 'Crocus']); const [colour, setColour] = useState(['Orange', 'Red']);
Para cada type
y colour
, puede crear un LayersControl
donde se conecta a los controladores de eventos para add
y remove
y actualizar el estado correspondiente ( type
o colour
) cuando el usuario marca o desmarca la capa:
<LayersControl.Overlay name="Crocus" checked="true"> <LayerGroup eventHandlers={{ add: (e) => { updateTypeState('Crocus', true); }, remove: (e) => { updateTypeState('Crocus', false); }, }} ></LayerGroup> </LayersControl.Overlay>
Las funciones para actualizar el estado se ven así (hay una función para actualizar el type
y otra para actualizar colour
):
const updateTypeState = (key: string, value: boolean) => { setType((prevState) => { if (value) { prevState = [...prevState, key]; } else { prevState = prevState.filter((e) => e !== key); } console.log(prevState); return prevState; }); }; const updateColourState = (key: string, value: boolean) => { setColour((prevState) => { if (value) { prevState = [...prevState, key]; } else { prevState = prevState.filter((e) => e !== key); } return prevState; }); };
Luego podría renderizar los marcadores usando la función de map
como sugirió:
{flowers .filter((flower) => { if (type.length == 0 && colour.length == 0) { // No layers selected, so show all return true; } if (type.length > 0 && colour.length > 0) { // Colours and types selected return ( type.indexOf(flower.type) >= 0 && colour.indexOf(flower.colour) >= 0 ); } if (type.length > 0) { // Type selected, no colour selected return type.indexOf(flower.type) >= 0; } // Colour selected, no type selected return colour.indexOf(flower.colour) >= 0; }) .map((flower, index) => ( <Marker position={flower.latlng}> <Popup> {flower.type}, {flower.colour} </Popup> </Marker> ))}
Aquí hay un StackBlitz en funcionamiento, pero tenga en cuenta que las imágenes de los marcadores no se muestran correctamente debido a este problema , pero debería poder ver un ícono de imagen roto y hacer clic en él para ver los detalles de la flor.