Etiquetas

React-Leafet(comenzando a trabajar)

 




Para crear un proyecto de React con la integración de react-leaflet para mapas interactivos, puedes seguir estos pasos:

Crear un nuevo proyecto React


Abre tu terminal y ejecuta el siguiente comando para crear un nuevo proyecto React:

npx create-react-app inicio

Este comando creará un nuevo directorio llamado inicio con la estructura básica de un proyecto React, posteriormente ingresar al directorio del proyecto

cd inicio

En seguida ya estando en el directorio del proyecto se instalar las dependencias de Leaflet y react-leaflet junto con las de react.

npm install react react-dom leaflet react-leaflet

Esto instalará las dependencias necesarias para trabajar con Leaflet y react-leaflet en tu proyecto y para finalizar, ejecuta el siguiente comando para iniciar tu aplicación React:

npm start

Esto iniciará la aplicación y abrirá automáticamente tu navegador predeterminado en http://localhost:3000. Deberías ver un mapa interactivo.

¡Ahora tienes un proyecto React básico con la integración de react-leaflet! Puedes continuar personalizando y ampliando este proyecto según tus necesidades.


Ya puedes abrir tu proyecto con editor de codigo de tu preferencia. Para continuar dirigete al archivo app.js que esta en tu proyecto.

Archivo App.js

El archivo App.js en una aplicación React que sirve como punto de entrada principal y contiene la lógica principal para la estructurar y renderizar la interfaz de usuario.

 Codigo de archivo App.js


import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;






El código que se ha proporcionado es el contenido básico del archivo App.js generado por Create React App al iniciar un nuevo proyecto de React. A continuación, se explica cada parte:

Importación de recursos y estilos:

import logo from './logo.svg';: Importa un archivo de imagen llamado logo.svg. Este archivo probablemente se encuentra en el mismo directorio que App.js.
import './App.css';: Importa los estilos definidos en el archivo App.css. Estos estilos se aplicarán al componente App.

Definición del componente funcional App:

function App() { ... }: Define un componente funcional de React llamado App. Los componentes funcionales son funciones de JavaScript que devuelven elementos de React.

Estructura de la interfaz de usuario (JSX):

Dentro de la función App, se devuelve un JSX que representa la estructura de la interfaz de usuario.

<div className="App">: Un contenedor principal con la clase CSS App.
<header className="App-header">: Un encabezado con la clase CSS App-header.
Contenido del encabezado:

<img src={logo} className="App-logo" alt="logo" />: Muestra la imagen del logo importada. La ruta de la imagen está definida por la variable logo.
<p>...</p>: Un párrafo que contiene un mensaje de ejemplo.
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">Learn React</a>: Un enlace que dirige al sitio web de React.
Exportación del componente:

export default App;: Exporta el componente App para que pueda ser utilizado en otros archivos de la aplicación.

Modificamos el archivo App.js


Para comenzar a trabajar con nuestro objetivo de trabajar con react-leaflet se modificara y agregara las siguientes lineas al archivo App.js, se utilizara el mismo ejercicio


import './App.css';
import { MapContainer, TileLayer } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

function App() {
  return (
    <div className="App">
      <MapContainer center= {[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
      <TileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      />
      </MapContainer>
    </div>
  );
}

export default App;

Una explicacion simple


1.-import './App.css'; y import 'leaflet/dist/leaflet.css';

Estos son comandos de importación que traen hojas de estilo CSS a tu aplicación. ./App.css probablemente es el archivo de estilo específico de la aplicación, y 'leaflet/dist/leaflet.css' es el archivo de estilo de Leaflet. Importar estos archivos asegura que las reglas de estilo necesarias estén disponibles para tu componente y los componentes de react-leaflet.

2.-import { MapContainer, TileLayer} from 'react-leaflet';

Aquí estás importando varios componentes de react-leaflet que te permitirán construir y personalizar tu mapa.

3.- function App() { ... }

Aquí defines la función App, que es un componente funcional de React.
Dentro de esta función, estás utilizando JSX para describir la estructura de tu componente. JSX es una sintaxis que se parece al XML/HTML y es utilizada en React para definir la interfaz de usuario.

4.- <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}> ... </MapContainer>

Este es el componente principal de react-leaflet.
center establece las coordenadas geográficas en las que se centrará inicialmente el mapa.
zoom establece el nivel de zoom inicial del mapa.
style establece el estilo del contenedor del mapa, en este caso, ocupando el 100% del alto y ancho de la ventana.

5.- <TileLayer ... />

El componente TileLayer configura la capa del mapa base utilizando datos de OpenStreetMap. La URL especificada es un patrón de URL que OpenStreetMap proporciona para obtener imágenes de mapas. Además, se agrega una atribución que indica la fuente de los datos del mapa.


6.- export default App;

Exporta el componente App para que pueda ser utilizado en otros archivos de tu aplicación.


En caso de error de puerto



En ocasiones ya hay una aplicacion en ejecucion utilizando el puerto 3000 donde se ejecuta por default las aplicaciones de react.

Para poder ejecutar otra aplicacion debemos de indicar otro puerto. en este caso ocuparemos el archivo env. te dejo una explicacion a continuacion:




El archivo .env en un proyecto React se utiliza para configurar variables de entorno específicas para tu aplicación. Estas variables de entorno pueden contener información sensible o configuraciones que varían según el entorno de desarrollo (local), el entorno de prueba, y el entorno de producción.

Aquí hay algunas cosas clave que necesitas saber sobre el archivo .env en React:

Ubicación del archivo:

El archivo .env debe colocarse en el directorio raíz de tu proyecto React.
Puedes tener varios archivos .env específicos para diferentes entornos (.env.local, .env.development, .env.production, etc.).
Variables de entorno:

En el archivo .env, defines variables de entorno con el formato NOMBRE_VARIABLE=valor.
Por ejemplo, puedes tener una variable de entorno para la API key de un servicio externo: REACT_APP_API_KEY=mi_api_key_secreta.
Prefijo REACT_APP_ para seguridad:

Para que las variables de entorno sean reconocidas por Create React App (la herramienta de inicio para proyectos React), deben tener un prefijo REACT_APP_.
Esto ayuda a evitar que se compartan accidentalmente variables de entorno con el entorno del sistema operativo.
Uso en el código:

En tu código JavaScript o JSX, puedes acceder a las variables de entorno utilizando process.env.NOMBRE_VARIABLE.
Por ejemplo, puedes usar process.env.REACT_APP_API_KEY para obtener la API key definida en el archivo .env.
Entornos específicos:

Puedes tener archivos .env específicos para diferentes entornos. Por ejemplo, .env.development para el entorno de desarrollo y .env.production para el entorno de producción.
Create React App seleccionará automáticamente el archivo .env correspondiente al entorno en el que se está ejecutando la aplicación.

ejemplo:


NODE_ENV: process.env.NODE_ENV || 'development'
 HOST: process.env.HOST || '127.0.0.1'
 PORT: process.env.PORT || 8000


una simple esplicacion:

1.- NODE_ENV: process.env.NODE_ENV || 'development'

  • NODE_ENV es una variable de entorno que se utiliza para especificar el entorno en el que se está ejecutando la aplicación (por ejemplo, "development", "production", "test", etc.).
  • process.env.NODE_ENV intenta obtener el valor de NODE_ENV de las variables de entorno del sistema operativo.
  • Si NODE_ENV no está definida en las variables de entorno, se utiliza el valor por defecto 'development'.
  • Esto es comúnmente utilizado para determinar cómo se deben configurar ciertos aspectos de la aplicación en diferentes entornos. Por ejemplo, puedes tener configuraciones específicas para el desarrollo, producción, y pruebas.


2.- HOST: process.env.HOST || '127.0.0.1'

  • HOST es una variable que indica la dirección IP en la que la aplicación escuchará conexiones.
  • process.env.HOST intenta obtener el valor de HOST de las variables de entorno del sistema operativo.
  • Si HOST no está definida en las variables de entorno, se utiliza el valor por defecto '127.0.0.1', que es la dirección IP local (localhost).
  • Esto te permite configurar la dirección IP en la que la aplicación escucha, por ejemplo, para que esté disponible en la red local o solo en la máquina local.

3.- PORT: process.env.PORT || 8000

  • PORT es una variable que indica el número de puerto en el que la aplicación escuchará conexiones.
  • process.env.PORT intenta obtener el valor de PORT de las variables de entorno del sistema operativo.
  • Si PORT no está definida en las variables de entorno, se utiliza el valor por defecto 8000.
  • Esto te permite configurar el número de puerto en el que la aplicación estará disponible, por ejemplo, si tienes varias aplicaciones ejecutándose en la misma máquina.


Crear archivo .env


Crear un archivo .env en un entorno Windows puede hacerse usando comandos en PowerShell o utilizando un editor de texto. Aquí te doy dos opciones

1.-Abre PowerShell:

Presiona Win + X y selecciona "Windows PowerShell" o "Windows PowerShell (Admin)" si estás ejecutando como administrador.
Navega al directorio de tu proyecto:


cd ruta\de\tu\proyecto

2.-Crea el archivo .env:

New-Item -Type file -Name .env

3.-Edita el archivo .env:

notepad .env

Esto abrirá el archivo .env en el Bloc de notas. Puedes agregar tus variables de entorno y guardar los cambios.


Otra opcion es utilizando el Bloc de notas u otro editor de texto. Aquí te guiaré a través de los pasos utilizando el Bloc de notas:

1.-Abre el Bloc de notas:

        Presiona Windows + R para abrir el cuadro de diálogo Ejecutar.
        Escribe notepad y presiona Enter.

2.-Agrega las variables de entorno a utilizar

3.-Guarda el archivo:

  • Haz clic en "Archivo" y luego en "Guardar como".
  • Guarda el archivo .env en el directorio raíz de tu proyecto React.
  • Cambia el tipo de archivo a "Todos los archivos".
  • Guarda el archivo con el nombre .env.. (asegúrate de que no tenga una            extensión adicional como .txt).
  • Clic en guardar

A finalizar estos pasos y ejecutar nuevamente tu aplicacion , la barra de direcciones de tu navegador se vera asi:





Marcador con ventana emergente


En react-leaflet, puedes agregar marcadores (pines) a tu mapa con ventanas emergentes (popups) asociadas para mostrar información adicional. Aquí tienes una explicación básica de cómo agregar un marcador con una ventana emergente en react-leaflet:


Codigo del archivo App.js


import './App.css';
import { MapContainer, TileLayer, Marker, Popup} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';

const MarkerIcon = L.icon({
  iconSize: [25, 41],
  iconAnchor: [10, 41],
  popupAnchor: [2, -40],
  iconUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-icon.png",
  shadowUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-shadow.png"
});

function App() {
 
  return (
    <div className="App">
      <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />

        <Marker position={[22.470690, -102.153547]} icon={MarkerIcon}>
          <Popup>
            Un mensaje <br/> emergente.
          </Popup>
        </Marker>
      </MapContainer>
    </div>
  );
}

export default App;




explicacion simple :



import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';

Importa varios componentes de react-leaflet que son esenciales para trabajar con mapas interactivos en React.

  • MapContainer: El contenedor principal para tu mapa.
  • TileLayer: La capa que proporciona el mapa base.
  • Marker: El componente para agregar marcadores al mapa.
  • Popup: El componente para agregar ventanas emergentes asociadas a los marcadores.


import L from 'leaflet';

Importa el objeto L desde la librería Leaflet. Leaflet utiliza L como un espacio de nombres que contiene varias funciones y clases relacionadas con la creación y manipulación de mapas interactivos. Puedes utilizar este objeto para acceder a funcionalidades específicas de Leaflet que no están cubiertas directamente por react-leaflet.

La función L.icon() es una función de la biblioteca Leaflet que se utiliza para crear un objeto de icono personalizado que puede ser utilizado para representar marcadores en un mapa interactivo. Esta función se utiliza comúnmente para definir la apariencia visual de los marcadores.

  • iconSize: [25, 41]: Establece el tamaño del ícono del marcador. En este caso, el ícono se dimensiona a 25 píxeles de ancho y 41 píxeles de alto.
  • iconAnchor: [10, 41]: Define el punto del ícono que se anclará al lugar del marcador en el mapa. En este caso, se especifica que el punto de anclaje es a 10 píxeles desde la izquierda y 41 píxeles desde la parte superior del ícono.
  • popupAnchor: [2, -40]: Establece el punto desde el cual se abrirá la ventana emergente asociada al marcador. En este caso, la ventana emergente se abrirá a 2 píxeles desde la izquierda y 40 píxeles desde la parte superior del ícono del marcador.
  • iconUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-icon.png": Especifica la URL de la imagen que se utilizará como ícono del marcador. En este ejemplo, se utiliza el ícono predeterminado de Leaflet para marcadores.
  • shadowUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-shadow.png": Especifica la URL de la sombra que se proyectará desde el marcador. En este caso, se utiliza la sombra predeterminada de Leaflet.

La sección de código <Marker position={[22.470690, -102.153547]} icon={MarkerIcon}> crea un marcador en un mapa Leaflet utilizando react-leaflet. Aquí hay una explicación detallada:

<Marker position={[22.470690, -102.153547]} icon={MarkerIcon}>

<Marker>: Este componente de react-leaflet representa un marcador en el mapa.

  • position: Propiedad que indica las coordenadas geográficas donde se colocará el marcador. En este caso, [22.470690, -102.153547].
  • icon: Propiedad que permite especificar el ícono que se utilizará para el marcador.
 En este caso, se utiliza el ícono personalizado MarkerIcon que definiste previamente con L.icon().

<Popup>

<Popup>: Este componente de react-leaflet representa una ventana emergente que se asocia al marcador.

Contiene el texto que  se mostrará cuando se haga clic en el marcador.
En este caso, contiene el texto "Un mensaje" con un salto de línea (<br/>) para indicar una nueva línea en la ventana y con tinuar el texto "emergente".


<Marker position={[22.470690, -102.153547]} icon={MarkerIcon}>

<Marker>: Este componente de react-leaflet representa un marcador en el mapa.

  • position: Propiedad que indica las coordenadas geográficas donde se colocará el marcador. En este caso, [22.470690, -102.153547].
  • icon: Propiedad que permite especificar el ícono que se utilizará para el marcador.
 En este caso, se utiliza el ícono personalizado MarkerIcon que definiste previamente con L.icon().



Poligono 


Para agregar un polígono con una ventana emergente en react-leaflet, puedes utilizar el componente Popup junto con el componente Polygon.

import './App.css';
import { MapContainer, TileLayer,Polygon, Popup} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const polygonPositions = [
  [18.999958, -96.677550],
  [15.896315, -96.591099],
  [16.094286, -93.333141],
  [18.610258, -93.336471]
  // Agrega más coordenadas según sea necesario
];

function App() {
 
  return (
    <div className="App">
      <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />
          <Polygon positions={polygonPositions} color="blue">
        {/* Agrega una ventana emergente al polígono */}
        <Popup>
          <p>Este es un polígono con una ventana emergente.</p>
        </Popup>
      </Polygon>
      </MapContainer>
    </div>
  );
}

export default App;



Explicacion simple


polygonPositions : Define un array de coordenadas que forman las esquinas del polígono. Cada subarray representa un punto con coordenadas [latitud, longitud].

<Polygon positions={polygonPositions} color="blue">: Crea un polígono en el mapa utilizando las coordenadas definidas en polygonPositions y con color azul.


LInea


Para dibujar un linea en Leaflet, puedes utilizar el componente Polyline. Aquí tienes un ejemplo básico de cómo hacerlo en una aplicación React utilizando react-leaflet:


import './App.css';
import { MapContainer, TileLayer,Polyline, Popup,Tooltip} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const lineCoordinates = [
  [21.806486, -100.965174],
  [21.576196, -101.099327],
  [21.565799, -101.102897],
  [21.550138, -101.114738]
  // Agrega más coordenadas según sea necesario
];

function App() {
 
  return (
    <div className="App">
      <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />
          <Polyline positions={lineCoordinates} color="red">
            <Popup>
              <p>Esta es una línea poligonal con una ventana emergente.</p>
            </Popup>
            <Tooltip sticky>
              <p>Informacion flotante</p>
            </Tooltip>
          </Polyline>
      </MapContainer>
    </div>
  );
}

export default App;




Explicación rapida



LineCoordinates:

 Es un array que contiene las coordenadas de los puntos de la linea. Puedes agregar tantos puntos como desees para definir la linea.

Polyline:

Polyline es un componente que representa una línea poligonal en el mapa, conectando una serie de puntos.
Se utiliza para dibujar líneas que pueden representar rutas, límites, etc.

Tooltip:

Tooltip es un componente que muestra información flotante (similar a un Popup) pero sin necesidad de hacer clic.Se muestra cuando el mouse pasa sobre el elemento asociado en el mapa.Puedes utilizar Tooltip para mostrar información breve y útil.


Circulo


Para colocar un círculo en Leaflet utilizando react-leaflet, puedes utilizar el componente CircleMarker.

import './App.css';
import { MapContainer, TileLayer, Popup, Tooltip, CircleMarker} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';


function App() {

  return (
    <div className="App">
      <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />
        <CircleMarker
          center={[24.288929, -102.847390]}
          pathOptions={{ color: 'red' }}
          radius={20}>
          <Popup>Este es un circulo </Popup>  
          <Tooltip>información flotante</Tooltip>
        </CircleMarker>
      </MapContainer>
    </div>
  );
}

export default App;


Pequeña explicación


CircleMarker:

CircleMarker es un componente que representa un marcador circular en el mapa.
A diferencia de Marker, CircleMarker mantiene su tamaño en píxeles independientemente del nivel de zoom.
Puedes usar CircleMarker para resaltar ubicaciones específicas en el mapa.


Rectangulo

Para insertar un rectángulo en Leaflet utilizando react-leaflet, puedes utilizar el componente Rectangle.

import './App.css';
import { MapContainer, TileLayer, Popup, Tooltip, CircleMarker } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';


function App() {

  return (
    <div className="App">
      <MapContainer center={[22.785971, -101.833501]} zoom={5} style={{ height: '100vh', width: '100vw' }}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />
        <Rectangle bounds={rectangle} pathOptions={{ color: 'black' }}>
        <Popup>Este es un rectangulo </Popup>
          <Tooltip>información flotante</Tooltip>
        </Rectangle>
      </MapContainer>
    </div>
  );
}

export default App;



explicacion simple

Rectangle : se utiliza para agregar un rectángulo al mapa. La propiedad bounds especifica las coordenadas de las esquinas superior izquierda e inferior derecha del rectángulo. También puedes personalizar el color del rectángulo usando la propiedad color y la opacidad de relleno con fillOpacity.


<TileLayer> y <LayersControl>


<TileLayer> y <LayersControl> son dos componentes diferentes proporcionados por react-leaflet que se utilizan para diferentes propósitos en la creación de mapas interactivos. Aquí está la diferencia entre ellos:

<TileLayer> se utiliza para agregar capas de azulejos (tiles) a un mapa. Estas capas de azulejos proporcionan la visualización de mapas base y pueden provenir de diversas fuentes, como OpenStreetMap, Mapbox, Google Maps, etc.

Puedes usar <TileLayer> para mostrar diferentes estilos de mapas base, como mapas de carreteras, imágenes satelitales, mapas topográficos, etc.

<LayersControl> se utiliza para controlar las capas del mapa, tanto las capas base como las capas superpuestas (overlays).
Proporciona una interfaz para que los usuarios seleccionen qué capa base o capa superpuesta desean ver en el mapa.
Puedes usar <LayersControl> para agregar capas base y capas superpuestas al mapa y permitir a los usuarios alternar entre ellas.

S puede decir que <TileLayer> se utiliza para agregar capas de azulejos (tiles) al mapa, mientras que <LayersControl> se utiliza para controlar las capas del mapa y proporcionar una interfaz para que los usuarios seleccionen qué capa base o capa superpuesta desean ver.

<TileLayer> se a utilizado asta este punto en los ejemplos anteriores 

<TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
 />


A continuacion veremos <LayersControl> que anterior mente se menciono que es un componente proporcionado por react-leaflet que te permite controlar las capas del mapa, como capas base y capas superpuestas (overlays). Puedes usar <LayersControl> para permitir a los usuarios cambiar entre diferentes capas base y capas superpuestas en el mapa. veamos el ejemplo.

<LayersControl position="topright">
        {/* Capas base */}
        <LayersControl.BaseLayer checked name="OpenStreetMap">
          <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Mapbox">
          <TileLayer url="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}" id="mapbox/streets-v11" accessToken="your-access-token-here" />
        </LayersControl.BaseLayer>

        {/* Capas superpuestas */}
        <LayersControl.Overlay name="Marcadores">
          {/* Agrega tus marcadores aquí */}
        </LayersControl.Overlay>
</LayersControl>

Explicacion simple


<LayersControl> envuelve las capas base y las capas superpuestas del mapa.

position="topright" especifica que el control se mostrará en la esquina superior derecha del mapa.

Dentro de <LayersControl>, <LayersControl.BaseLayer> define las capas base del mapa. Puedes proporcionar un nombre para cada capa base y un componente TileLayer para mostrar la capa base. La propiedad "checked" indica que la capa base esta seleccionada por defecto.

<LayersControl.Overlay> define las capas superpuestas del mapa. Puedes proporcionar un nombre para cada capa superpuesta y agregar cualquier contenido que desees mostrar como capa superpuesta.



A continuacion se indicaran las Fuentes que se pueden utilizar como mapas base 

  • openstreetmap
    • url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
  • OSM Cycle Map
    • url="http://tile.thunderforest.com/cycle/{z}/{x}/{y}.png"
    




  • Carto Positron
    • url="https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"




  • CARTO dark
    • url="http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"


  • Google Maps
    • url="https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}"


  • Google Satellite
    • url="http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}"


  • Google Hybrid
    • url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}"


  • Google Terrain
    • url="https://mt1.google.com/vt/lyrs=t&x={x}&y={y}&z={z}"


  • Google Traffic
    • url="https://mt1.google.com/vt?lyrs=h@159000000,traffic|seconds_into_week:-1&style=3&x={x}&y={y}&z={z}"


  • Google Roads
    • url="https://mt1.google.com/vt/lyrs=h&x={x}&y={y}&z={z}"


  • ESRI Imagery/Satellite
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"


  • ESRI National Geographic
    • url="http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}"


  • ESRI Physical
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}"


  • ESRI Streets
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"


  • ESRI Terrain
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}"


  • ESRI Topo
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}"


  • ESRI ransportation
    • url="https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}"
    •           />


  • mobile-atlas
    • url: 'https://{s}.tile.thunderforest.com/mobile-atlas/{z}/{x}/{y}{r}.png?apikey=7c352c8ff1244dd8b732e349e0b0fe8d'




  • landscape
    • url: 'https://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}{r}.png?apikey=7c352c8ff1244dd8b732e349e0b0fe8d'


  • World Topo Map
    • url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}'


  • terrain day
    •  url: 'https://1.aerial.maps.ls.hereapi.com/maptile/2.1/maptile/newest/terrain.day/{z}/{x}/{y}/256/png8?app_id=eAdkWGYRoc4RfxVo0Z4B&app_code=TrLJuXVK62IQk0vuXFzaig&lg=eng'


Un ejemplo rapido de como usra las fuentes de informacion como  Capas base



import React from "react";
import {
  MapContainer,
  LayersControl,
  TileLayer
} from "react-leaflet";
import "leaflet/dist/leaflet.css";

export default function App() {

  return (

    <MapContainer
      center={[19.286007, -99.142330]}
      zoom={5}
      style={{ height: "100vh" }}

    >

      <LayersControl position="topright">
        <LayersControl.BaseLayer checked name="Calles">
          <TileLayer
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="OpenStreetMap">
          <TileLayer
            url="http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="OpenStreetMap Mapnick">
          <TileLayer
            url="http://tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="OSM Cycle Map">
          <TileLayer
            url="http://tile.thunderforest.com/cycle/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="OSM Black and White">
          <TileLayer
            url="http://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="OSM2World/3D (D,A,CH)">
          <TileLayer
            url="http://tiles.osm2world.org/osm/pngtiles/n/{z}/{x}/{y}.png}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Carto Positron">
          <TileLayer
            url="https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="CARTO dark">
          <TileLayer
            url="http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Bing maps">
          <TileLayer
            url="http://ecn.dynamic.t0.tiles.virtualearth.net/comp/CompositionHandler/{q}?mkt=en-us&it=G,VE,BX,L,LA&shading=hill"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Bing Satélite">
          <TileLayer
            url="http://ecn.t3.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0&dir=dir_n’"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Stamen Terrain">
          <TileLayer
            url="http://a.tile.stamen.com/terrain/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Stamen Toner">
          <TileLayer
            url="http://tile.stamen.com/toner/{z}/{x}/{y}.png"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Stamen Watercolor">
          <TileLayer
            url="http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Maps">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Satellite">
          <TileLayer
            url="http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Hybrid">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Terrain">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=t&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Traffic">
          <TileLayer
            url="https://mt1.google.com/vt?lyrs=h@159000000,traffic|seconds_into_week:-1&style=3&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="Google Roads">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=h&x={x}&y={y}&z={z}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI Imagery/Satellite">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI National Geographic">
          <TileLayer
            url="http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI Physical">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI Streets">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI Terrain">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI Topo">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        <LayersControl.BaseLayer name="ESRI ransportation">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.BaseLayer>
        

        
      </LayersControl>

    </MapContainer>
  );
}



utilizando las mismas fuentes de informacion pero ahora como capas flotantes,<LayersControl.Overlay> se utiliza para definir capas superpuestas en un mapa interactivo. Estas capas superpuestas pueden ser activadas o desactivadas por el usuario a través del control de capas (LayersControl). Aquí hay una explicación detallada de cómo funciona:

Definición de una capa superpuesta: Al utilizar <LayersControl.Overlay>, puedes definir una capa que se superpondrá al mapa principal. Esta capa puede contener diferentes tipos de contenido, como marcadores, polígonos, capas de teselas, etc. Puedes definir varias capas superpuestas dentro de <LayersControl> para ofrecer opciones de visualización a los usuarios.

Propiedades:

name: Esta propiedad especifica el nombre de la capa superpuesta que se mostrará en el control de capas. Es la etiqueta que aparecerá junto al checkbox correspondiente en el control de capas.
checked: Esta propiedad indica si la capa superpuesta debe estar marcada como seleccionada por defecto. Si se establece en true, la capa estará seleccionada cuando se cargue inicialmente el mapa.
Uso:

Dentro de <LayersControl>, puedes usar <LayersControl.Overlay> para definir diferentes capas superpuestas.
Puedes colocar cualquier contenido válido dentro de <LayersControl.Overlay>, como un <Marker> para marcadores, <TileLayer> para capas de teselas, <Polygon> para polígonos, etc.
Interacción del usuario:

Cuando un usuario interactúa con el control de capas en el mapa, puede activar o desactivar las capas superpuestas según sea necesario. Esto proporciona una forma conveniente para que los usuarios controlen qué capas desean ver en el mapa en un momento dado.



import React from "react";
import {
  MapContainer,
  LayersControl,
  TileLayer
} from "react-leaflet";
import "leaflet/dist/leaflet.css";

export default function App() {

  return (

    <MapContainer
      center={[19.286007, -99.142330]}
      zoom={5}
      style={{ height: "100vh" }}

    >

      <LayersControl position="topright">
        <LayersControl.Overlay checked name="Calles">
          <TileLayer
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="OpenStreetMap">
          <TileLayer
            url="http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="OpenStreetMap Mapnick">
          <TileLayer
            url="http://tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="OSM Cycle Map">
          <TileLayer
            url="http://tile.thunderforest.com/cycle/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="OSM Black and White">
          <TileLayer
            url="http://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="OSM2World/3D (D,A,CH)">
          <TileLayer
            url="http://tiles.osm2world.org/osm/pngtiles/n/{z}/{x}/{y}.png}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Carto Positron">
          <TileLayer
            url="https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="CARTO dark">
          <TileLayer
            url="http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Bing maps">
          <TileLayer
            url="http://ecn.dynamic.t0.tiles.virtualearth.net/comp/CompositionHandler/{q}?mkt=en-us&it=G,VE,BX,L,LA&shading=hill"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Bing Satélite">
          <TileLayer
            url="http://ecn.t3.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0&dir=dir_n’"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Stamen Terrain">
          <TileLayer
            url="http://a.tile.stamen.com/terrain/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Stamen Toner">
          <TileLayer
            url="http://tile.stamen.com/toner/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Stamen Watercolor">
          <TileLayer
            url="http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Maps">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Satellite">
          <TileLayer
            url="http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Hybrid">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Terrain">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=t&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Traffic">
          <TileLayer
            url="https://mt1.google.com/vt?lyrs=h@159000000,traffic|seconds_into_week:-1&style=3&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="Google Roads">
          <TileLayer
            url="https://mt1.google.com/vt/lyrs=h&x={x}&y={y}&z={z}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI Imagery/Satellite">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI National Geographic">
          <TileLayer
            url="http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI Physical">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI Streets">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI Terrain">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI Topo">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        <LayersControl.Overlay name="ESRI ransportation">
          <TileLayer
            url="https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}"
          />
        </LayersControl.Overlay>
        

        
      </LayersControl>

    </MapContainer>
  );
}




Boton de pantalla completa


npm i react-leaflet-fullscreen

El comando npm i react-leaflet-fullscreen es utilizado para instalar el paquete react-leaflet-fullscreen en un proyecto de React que utiliza React-Leaflet para integrar mapas interactivos. Este paquete proporciona una funcionalidad adicional para habilitar la funcionalidad de pantalla completa en los mapas implementados con React-Leaflet.

Aquí hay una explicación de cada parte del comando:

npm: Es el administrador de paquetes de Node.js que se utiliza para instalar paquetes y gestionar las dependencias de un proyecto.
i (abreviatura de install): Es un comando de npm que se utiliza para instalar paquetes.
react-leaflet-fullscreen: Es el nombre del paquete que se va a instalar. Este paquete específico extiende las capacidades de React-Leaflet al proporcionar componentes y utilidades para integrar la funcionalidad de pantalla completa en los mapas creados con React-Leaflet.

Ejemplo 


import React from "react";
import {
  MapContainer,
  LayersControl,
  TileLayer
} from "react-leaflet";
import "leaflet/dist/leaflet.css";
import { FullscreenControl } from "react-leaflet-fullscreen";
import "react-leaflet-fullscreen/styles.css";


export default function App() {


  return (

    <MapContainer
      center={[19.286007, -99.142330]}
      zoom={5}
      style={{ height: "100vh" }}
      
    >
      
      <LayersControl position="topright">
      <FullscreenControl />
          <LayersControl.Overlay checked name="Calles-----">
            <TileLayer
              url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
          </LayersControl.Overlay>
               
        <LayersControl.Overlay name="OpenStreetMap">
          <TileLayer
            url="http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
        </LayersControl.Overlay>
      </LayersControl>

    </MapContainer>
  );
}


Explicacion simple


import { FullscreenControl } from "react-leaflet-fullscreen";: Importa el componente FullscreenControl del paquete react-leaflet-fullscreen, que proporciona funcionalidad para habilitar la pantalla completa en el mapa.

import "react-leaflet-fullscreen/styles.css";: Importa los estilos CSS del paquete react-leaflet-fullscreen.

<FullscreenControl />: Se incluye como un componente independiente dentro del <LayersControl>. Este componente agrega un botón para habilitar la vista de pantalla completa en el mapa.


Minimapa

Un minimapa en Leaflet es una vista de mapa reducida que se muestra junto al mapa principal y proporciona una visión general del área cubierta por el mapa principal. Esta vista general puede ser útil para que los usuarios naveguen rápidamente a diferentes áreas del mapa o para tener una perspectiva general de todo el conjunto de datos geográficos.

La utilidad de un minimapa en Leaflet incluye:

Perspectiva general: Un minimapa proporciona una visión general de todo el mapa, permitiendo a los usuarios entender rápidamente la distribución geográfica de los datos representados en el mapa principal. Esto puede ser especialmente útil cuando se trabaja con conjuntos de datos grandes o complejos.

Navegación rápida: Los usuarios pueden utilizar el minimapa para navegar rápidamente a diferentes partes del mapa principal. Al hacer clic o arrastrar en el minimapa, la vista en el mapa principal se ajusta automáticamente para mostrar la ubicación correspondiente en el minimapa.

Contexto espacial: Proporciona un contexto espacial adicional al mapa principal, lo que ayuda a los usuarios a comprender la ubicación relativa de diferentes características geográficas o puntos de interés. Esto es especialmente útil en aplicaciones de mapeo donde la orientación espacial es importante.

Referencia visual: Sirve como una referencia visual constante para los usuarios, lo que les permite mantenerse orientados mientras exploran el mapa principal. Esto puede ser útil en situaciones donde los usuarios necesitan comparar rápidamente diferentes áreas del mapa.

Para este ejemplo cambiaremos la forma que hemos venido ocupando, seguiremos utilizando el archivo App.js como punto de partida ;Vamos a crear otro archivo para visualizar nuestros mapas que denominaremos MapView.js , posteriormente crearemos una carpeta que nombraremos components donde guardaremos todos los archivos de desarrollo de los mapas, en este caso crearemos el archivo denominado MyMaps donde estara el desarrollo de nuestro minimapa .

Revisemos el archivo App.js

import './App.css';
import MapView from './components/MapView';

function App() {
  return (
    <div>
      <MapView/>
    </div>
  );
}

export default App;


Explicacion simple


El código es un componente de función de React que representa la aplicación principal. Aquí tienes una explicación de cada parte:

import './App.css';: Esta línea importa el archivo CSS llamado App.css. Este archivo generalmente se utiliza para definir estilos específicos de la aplicación, como colores, fuentes, márgenes, etc. La convención de nombre App.css sugiere que estos estilos están destinados a aplicarse a toda la aplicación.

import MapView from './components/MapView';: Esta línea importa un componente llamado MapView desde el archivo ./components/MapView. MapView es un archivo  que está ubicado en la carpeta components de la aplicación. Esto indica que la lógica y la presentación relacionadas con la visualización del mapa se han encapsulado en un componente separado para mantener el código organizado y modular.

function App() { ... }: Este es el componente de función principal llamado App. Este componente devuelve el JSX que define la estructura de la aplicación.

return ( ... );: El componente App devuelve el JSX que describe la estructura de la aplicación. En este caso, hay un div que envuelve el componente MapView. Esto se hace para proporcionar un contenedor para los componentes hijos y para aplicar estilos o funcionalidades adicionales si es necesario.

<MapView/>: Aquí se renderiza el componente MapView. Este componente es responsable de mostrar el mapa en la aplicación. Al renderizar <MapView/> dentro del componente App, se integra en la estructura de la aplicación principal.

export default App;: Finalmente, el componente App se exporta como el componente predeterminado de este archivo. Esto significa que otros archivos de la aplicación pueden importar y utilizar este componente principal como import App from './App';.


Codigo del archivo MapView.js

import React from 'react';
import 'leaflet/dist/leaflet.css';
import MyMap from "./MyMap";

const MapView = () => {
  return (    
    <div>      
        <MyMap />        
    </div>
  );
}
export default MapView




Explicacion simple


Este código representa un componente de función en React llamado MapView. Aquí está la explicación de cada parte:

import React from 'react';: Esta línea importa el módulo React, que es necesario para definir componentes de React. En este caso, el componente MapView se define como un componente de función, y React es necesario para que este componente funcione.

import 'leaflet/dist/leaflet.css';: Esta línea importa los estilos CSS de Leaflet. Leaflet es una biblioteca de mapeo que se utiliza en conjunto con React-Leaflet para crear mapas interactivos en aplicaciones web. Al importar los estilos CSS de Leaflet, aseguramos que los componentes de Leaflet se muestren correctamente en nuestra aplicación.

import MyMap from "./MyMap";: Esta línea importa el componente MyMap desde el archivo "./MyMap". MyMap es un componente personalizado que representa el mapa que se mostrará en MapView.

const MapView = () => { ... }: Aquí se define el componente de función MapView. Este componente no acepta ninguna propiedad (props) y se define como una función de flecha que devuelve JSX.

return ( ... );: El componente MapView devuelve JSX que define la estructura del componente. En este caso, MapView devuelve un div que contiene el componente MyMap.

<MyMap />: Aquí se renderiza el componente MyMap. Este componente es responsable de mostrar el mapa en la aplicación. Al renderizar <MyMap /> dentro del componente MapView, se integra en la estructura de la vista de mapa principal.

export default MapView;: Finalmente, el componente MapView se exporta como el componente predeterminado de este archivo. Esto significa que otros archivos de la aplicación pueden importar y utilizar este componente como import MapView from './MapView';.


codigo del archivo MyMap.js


import { useCallback, useMemo, useState } from 'react'
import { useEventHandlers } from '@react-leaflet/core'
import {
  MapContainer,
  Rectangle,
  TileLayer,
  useMap,
  useMapEvent,
} from 'react-leaflet'


const POSITION_CLASSES = {
  bottomleft: "leaflet-bottom leaflet-left",
  bottomright: "leaflet-bottom leaflet-right",
  topleft: "leaflet-top leaflet-left",
  topright: "leaflet-top leaflet-right",
}



function MinimapBounds({ parentMap, zoom }) {
  const minimap = useMap()

  // Al hacer clic en un punto en el minimapa se establece el centro del mapa principal
  const onClick = useCallback(
    (e) => {
      parentMap.setView(e.latlng, parentMap.getZoom())
    },
    [parentMap],
  )
  useMapEvent('click', onClick)

  // Realizar un seguimiento de los límites en el estado para activar renderizados
  const [bounds, setBounds] = useState(parentMap.getBounds())
  const onChange = useCallback(() => {
    setBounds(parentMap.getBounds())
    // Actualiza la vista del minimapa para que coincida con el centro y el zoom del mapa principal
    minimap.setView(parentMap.getCenter(), zoom)
  }, [minimap, parentMap, zoom])

  // Escuchar eventos en el mapa principal
  const handlers = useMemo(() => ({ move: onChange, zoom: onChange }), [])
  useEventHandlers({ instance: parentMap }, handlers)

  return <Rectangle bounds={bounds} pathOptions={{weight:4}} />
}



function MinimapControl({ position, zoom }) {
  const parentMap = useMap()
  const mapZoom = zoom || 5

 // Memoriza el minimapa para que no se vea afectado por los cambios de posición
  const minimap = useMemo(
    () => (
      <MapContainer
        style={{ height: 250, width: 250 }}
        center={parentMap.getCenter()}
        zoom={mapZoom}
        dragging={true}
        doubleClickZoom={false}
        scrollWheelZoom={true}
        attributionControl={false}
        zoomControl={false}>
        <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
        <MinimapBounds parentMap={parentMap} />
      </MapContainer>
    ),
    [],
  )

  const positionClass =POSITION_CLASSES.bottomleft
  return (
    <div className={positionClass}>
      <div className="leaflet-control leaflet-bar">{minimap}</div>
    </div>
  )
}

function ReactControlExample() {
  return (
    <MapContainer
        center={[23.622879, -102.199827]} 
        zoom={6} 
        scrollWheelZoom={true}
        style={{ height: '100vh', width: '70wh' }}
     >
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <MinimapControl position="topleft" />
    </MapContainer>
  )
}


export default ReactControlExample;





Explicacion simple 


import { useCallback, useMemo, useState } from 'react': Esta línea importa los hooks useCallback, useMemo y useState de React. Estos hooks se utilizan para gestionar el estado y optimizar el rendimiento de los componentes React.


  • useCallback:
    • useCallback es un hook que se utiliza para memoizar (cachear) funciones callback. Esto significa que si los valores de las dependencias no han cambiado desde la última renderización, useCallback devolverá la misma función callback que se usó anteriormente, lo que puede mejorar el rendimiento evitando la creación innecesaria de nuevas funciones en cada renderización.
    • Se utiliza para optimizar el rendimiento en situaciones en las que las funciones callback se pasan como dependencias a otros hooks o componentes hijos, y queremos evitar que se vuelvan a crear en cada renderizado.
  • useMemo:
    • useMemo es un hook que se utiliza para memoizar (cachear) valores calculados. Similar a useCallback, useMemo evita recalcular un valor si las dependencias no han cambiado desde la última renderización.
    • Se utiliza para mejorar el rendimiento al calcular valores costosos en renderizaciones de componentes funcionales. useMemo es útil cuando tienes un cálculo que es intensivo en CPU y no quieres que se recalcule en cada renderizado si las entradas no han cambiado.
  • useState:
    • useState es un hook que permite añadir estado a los componentes de función en React.
    • Al llamar a useState, se retorna un par de valores: el estado actual y una función para actualizar ese estado. Esto permite que los componentes de función en React manejen el estado interno y se vuelvan reactivos, es decir, que se vuelvan a renderizar automáticamente cuando el estado cambia.

import { useEventHandlers } from '@react-leaflet/core': Esta línea importa el hook useEventHandlers de @react-leaflet/core, que se utiliza para manejar eventos en los componentes Leaflet.

import { MapContainer, Rectangle, TileLayer, useMap, useMapEvent } from 'react-leaflet': Estas líneas importan varios componentes y hooks de React-Leaflet necesarios para construir el mapa interactivo y el minimapa.

POSITION_CLASSES: Este objeto define las clases de posición para el minimapa. Estas clases se utilizan para posicionar el minimapa en una esquina específica del mapa principal.

  • bottomleft: Esta clave representa la esquina inferior izquierda del mapa. La cadena de clases CSS asociada es "leaflet-bottom leaflet-left", lo que significa que el minimapa se posicionará en la esquina inferior izquierda del mapa principal.
  • bottomright: Esta clave representa la esquina inferior derecha del mapa. La cadena de clases CSS asociada es "leaflet-bottom leaflet-right", lo que significa que el minimapa se posicionará en la esquina inferior derecha del mapa principal.
  • topleft: Esta clave representa la esquina superior izquierda del mapa. La cadena de clases CSS asociada es "leaflet-top leaflet-left", lo que significa que el minimapa se posicionará en la esquina superior izquierda del mapa principal.
  • topright: Esta clave representa la esquina superior derecha del mapa. La cadena de clases CSS asociada es "leaflet-top leaflet-right", lo que significa que el minimapa se posicionará en la esquina superior derecha del mapa principal.


MinimapBounds: Esta función define un componente funcional de React que representa los límites del minimapa. Este componente se encarga de mantener actualizados los límites del minimapa y de manejar los eventos de clic en el minimapa.

  • La línea const minimap = useMap() es una declaración en React que utiliza el hook useMap() proporcionado por React-Leaflet. Este hook se utiliza para obtener una referencia al objeto de mapa de Leaflet asociado al componente actual.En React-Leaflet, el hook useMap() se puede utilizar dentro de un componente funcional que se encuentra dentro de un <MapContainer> para obtener acceso al objeto de mapa de Leaflet. Este objeto de mapa contiene métodos y propiedades que permiten interactuar con el mapa, como establecer la vista del mapa, agregar capas, escuchar eventos del mapa, entre otros.Cuando se llama a useMap(), React-Leaflet se encarga de manejar la integración entre React y Leaflet, y devuelve una referencia al objeto de mapa de Leaflet asociado al componente actual. Esto permite que el componente funcional tenga acceso al mapa y pueda interactuar con él según sea necesario.
  • const onClick = useCallback(...): Esta línea define una función de devolución de llamada onClick utilizando el hook useCallback. useCallback se utiliza para memoizar (cachear) la función de devolución de llamada, lo que significa que la función se mantendrá igual entre las renderizaciones, a menos que las dependencias especificadas cambien. En este caso, la función de devolución de llamada recibe un evento e (el evento de clic) como argumento y utiliza parentMap para establecer la vista del mapa principal (parentMap.setView(e.latlng, parentMap.getZoom())). La función de devolución de llamada se memoiza con parentMap como dependencia, lo que garantiza que la función se cree nuevamente solo si parentMap cambia.
  • useMapEvent('click', onClick): Esta línea utiliza el hook useMapEvent proporcionado por React-Leaflet para agregar un evento de clic al minimapa. useMapEvent toma dos argumentos: el tipo de evento ('click') y la función de devolución de llamada (onClick) que se ejecutará cuando se produzca el evento especificado. En este caso, cuando el usuario hace clic en el minimapa, se ejecutará la función de devolución de llamada onClick definida anteriormente, lo que cambiará la vista del mapa principal para centrarlo en la ubicación donde se hizo clic en el minimapa.
  • const [bounds, setBounds] = useState(parentMap.getBounds()): Esta línea utiliza el hook useState para inicializar y gestionar el estado de los límites (bounds) del minimapa. parentMap.getBounds() devuelve los límites actuales del mapa principal, y estos límites se utilizan como estado inicial del minimapa. La función setBounds se utiliza para actualizar el estado de los límites del minimapa cuando sea necesario.
  • const onChange = useCallback(() => { ... }, [minimap, parentMap, zoom]): Esta línea define una función de devolución de llamada onChange utilizando el hook useCallback. La función onChange se ejecutará cada vez que cambien las dependencias especificadas en el segundo argumento de useCallback. En este caso, las dependencias son minimap, parentMap y zoom.
  • Dentro de la función de devolución de llamada onChange, se actualizan los límites del minimapa utilizando setBounds(parentMap.getBounds()). Esto asegura que los límites del minimapa reflejen siempre los límites actuales del mapa principal.
  • Además, se ajusta la vista del minimapa para que coincida con el centro y el zoom del mapa principal utilizando minimap.setView(parentMap.getCenter(), zoom). Esto garantiza que la vista del minimapa siempre esté sincronizada con el centro y el zoom del mapa principal.
  • Al utilizar minimap.setView se asegura que la vista del minimapa se actualice correctamente sin desencadenar un bucle infinito, ya que la función onChange solo se ejecutará cuando cambien las dependencias especificadas en useCallback.
  • const handlers = useMemo(() => ({ move: onChange, zoom: onChange }), []): Esta línea utiliza el hook useMemo para memoizar (cachear) un objeto handlers. Este objeto contiene los controladores de eventos para los eventos de movimiento (move) y zoom (zoom) del mapa principal. Ambos eventos están asociados a la función de devolución de llamada onChange.
  • Al utilizar useMemo, se asegura que el objeto handlers se vuelva a calcular solo cuando las dependencias cambien. En este caso, como se proporciona un array vacío de dependencias, el objeto handlers se calcula solo una vez, durante la inicialización del componente.
  • useEventHandlers({ instance: parentMap }, handlers): Esta línea utiliza el hook useEventHandlers proporcionado por @react-leaflet/core para asociar los controladores de eventos definidos en el objeto handlers al mapa principal (parentMap).
  • { instance: parentMap } especifica el objeto de mapa de Leaflet al que se asocian los controladores de eventos.
  • handlers es el objeto que contiene los controladores de eventos definidos previamente.
  • Al utilizar useEventHandlers, los controladores de eventos se registran en el mapa principal para que se ejecuten cuando ocurran los eventos de movimiento y zoom.
  • return <Rectangle bounds={bounds} pathOptions={{weight:4}} />: Esta línea devuelve un componente <Rectangle> de Leaflet. Este componente se utiliza para representar los límites del minimapa en el mapa principal.
  • El prop bounds especifica los límites del rectángulo del minimapa que se mostrará en el mapa principal.
  • El prop pathOptions permite especificar opciones de estilo para el rectángulo, como el grosor de la línea del borde.

MinimapControl: Esta función define un componente funcional de React que representa el control del minimapa. Este componente se encarga de crear el minimapa y de posicionarlo en una esquina específica del mapa principal.

ReactControlExample: Esta función define un componente funcional de React que representa un ejemplo de uso del control de minimapa en un mapa interactivo.

Zoom en pantalla

Para agregar funcionalidad de zoom en un mapa usando React-Leaflet, es una biblioteca que proporciona componentes React para Leaflet, una biblioteca popular de mapas interactivos.

Codigo del modulo map.js

import React from 'react';
import { MapContainer, TileLayer } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import ZoomDisplay from './ZoomDisplay'; // Asegúrate de ajustar la ruta de importación según tu estructura de proyecto

const Map = () => {
    const position = [51.505, -0.09]; // Coordenadas iniciales (por ejemplo, Londres)

    return (
        <MapContainer center={position} zoom={13} style={{ height: "100vh", width: "100%" }}>
            <TileLayer
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            />
            <ZoomDisplay />
        </MapContainer>
    );
};

export default Map;



Codigo del modulo zoom.js

import React, { useState } from 'react'
import { useMapEvent } from 'react-leaflet'

const ZoomDisplay = () => {
    const [zoom, setZoom] = useState(null);

    useMapEvent('zoomend', (event) => {
        setZoom(event.target.getZoom()); // optiene el zoom nuevo
    });

    return (
        <div className="custom-label">
            <div className="leaflet-top leaflet-right">
                {zoom !== null && `* Nivel de zoom: ${zoom}`}
            </div>
        </div>
            );
  };

            export default ZoomDisplay;