Etiquetas

React-Leafet(ruta)

 

Este blog tiene como finalidad de compartir conocimientos y aportar un granito más de información. Comparto mis apuntes e información que he encontrado por Internet, teniendo en cuenta que muchas ideas escritas no son propias, en la parte inferior coloco la url de los sitios donde esta la idea original ... espero que les sea de utilidad. 




Una ruta en React-Leaflet se refiere a un camino o trayectoria trazada en un mapa, generalmente utilizando componentes y herramientas de Leaflet para dibujar y visualizar caminos, trayectorias o rutas entre puntos específicos. En un contexto de mapas, una ruta puede ser un conjunto de puntos conectados, una línea entre dos ubicaciones, o un conjunto de direcciones paso a paso.

Conceptos Clave de Rutas en React-Leaflet
  • Leaflet: Es una biblioteca de mapas de código abierto utilizada para crear aplicaciones de mapas interactivas. React-Leaflet es una integración de Leaflet para React, que permite usar componentes React para trabajar con mapas Leaflet.
  • Rutas: En el contexto de mapas, una ruta puede ser:
    • Una línea que conecta puntos específicos en un mapa.
    • Un camino entre dos o más ubicaciones.
    • Un itinerario que incluye instrucciones paso a paso.


Crear un nuevo proyecto React

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

npx create-react-app inicio_ruta

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_ruta

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.

Desarrollo


En el archivo  App.js se debera ver de la siguiente manera.

Codigo App.js 


import './App.css';
import Ruta from './componentsRuta/ruta'
function App() {
  return (
    <div className="App">
      <Ruta />
    </div>
  );
}

export default App;

Creamos una carpeta denominada "componentsRuta" para almacenar nuestros modulos e instalamos RoutineMachine con  npm i leaflet-routing-machine.

Crea el modulo ruta.

codigo de ruta.js

import React from 'react';
import { MapContainer, TileLayer} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import RoutingMachine from './routineMachine ';
import {MapButton} from './MapButton';

function Ruta() {
  const handleButtonClick = () => {
    const routingContainer = document.querySelector('.leaflet-routing-container');
    if (routingContainer) {
        if(routingContainer.style.display=='none'){
        routingContainer.style.display = 'block'; // Mostrar el panel
    }else{          
      routingContainer.style.display = 'none'; // Ocultar el panel
    }}
};
  return (
    <div className="App">
      <MapContainer center={[19.295110, -99.116862]}
      zoom={12} 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'
        />
       <RoutingMachine />
       <MapButton position="topright" onClick={handleButtonClick} />
      </MapContainer>
    </div>
  );
}

export default Ruta;


Creamos nuestro modulo  routineMachine.

    Codigo routineMachine .js

import L from "leaflet";
import { createControlComponent } from "@react-leaflet/core";
import "leaflet-routing-machine";
import "leaflet-routing-machine/dist/leaflet-routing-machine.css";

const createRoutineMachineLayer = () => {
  /* L.Marker.prototype.options.icon = 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"      
    }); */
  const customIcon = L.icon({
    iconUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-icon.png",
    shadowUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-shadow.png", // URL del nuevo icono
    iconSize: [25, 41], // Tamaño del icono
    iconAnchor: [12, 41], // Anclaje del icono
    popupAnchor: [1, -34], // Anclaje del popup
  });

  var routeArray = new Array();

  const instance = L.Routing.control({
    waypoints: [
      L.latLng(19.286306, -99.143788),
      L.latLng(19.548763, -98.881959)
    ],
    lineOptions: {
      styles: [{ color: 'green', opacity: 1, weight: 5 }]
    },
    show: true,
    addWaypoints: true,
    routeWhileDragging: true,
    draggableWaypoints: true,
    fitSelectedRoutes: true,
    showAlternatives: true,
    altLineOptions: {
      styles: [
        { color: 'black', opacity: 0.15, weight: 9 },
        { color: 'white', opacity: 0.8, weight: 6 },
        { color: 'blue', opacity: 0.5, weight: 2 }
      ]
    },
    createMarker: function (i, waypoint, n) {
      /* if (i === n - 1) return null; */
      const marker = L.marker(waypoint.latLng, { icon: customIcon }); // Aplicar el icono personalizado
      marker.bindPopup(`Punto  ${i + 1} <br>con coordenadas :[${waypoint.latLng.lat}, ${waypoint.latLng.lng}]`); // Vincular un popup
      return marker;
    },

  }).on('routeselected', (e) => {
    const route = e.route;
    console.log('Nueva ruta seleccionada:', route.summary);
  })

    .on('waypointschanged', (e) => {
      console.log('Waypoints cambiados:', e.waypoints);
    })

  routeArray = instance.getWaypoints();
  console.log('---- routeArray', routeArray);
  return instance;
};

const RoutingMachine = createControlComponent(createRoutineMachineLayer);

export default RoutingMachine;


Creamos el modilo "MapButton" para crear un boton en el mapa.

Codigo de MapButton.js

import React from 'react';
import L from 'leaflet';
import { useMap } from 'react-leaflet';

// Componente de botón personalizado
export const MapButton = ({ position = 'topright', onClick }) => {
  const map = useMap(); // Obtén el mapa para agregar el control

  React.useEffect(() => {
    const control = L.control({ position }); // Define la posición del control
    control.onAdd = () => {
      const button = L.DomUtil.create('button', 'map-button');
      button.innerHTML = 'Indicaciones'; // Texto del botón
      button.onclick = onClick; // Manejar clics
      return button; // Devuelve el elemento DOM
    };
   
    control.addTo(map); // Agrega el control al mapa
   
    return () => {
      control.remove(); // Limpia el control cuando el componente se desmonta
    };
  }, [map, position, onClick]);

  return null; // No se necesita renderizar nada en JSX
};

tu aplicacion se vera de esta manera.