Etiquetas

React - Leaflet (Manejo de coordenadas)

 Se reutilizara codigo de busqueda y localizacion.


codigo app.js


import './App.css';

import MapView from './components/MapView';
function App() {
  return (
    <div>
      <MapView/>
    </div>
  );
}

export default App;


codigo MapView.js


import React, { useState, useRef } from 'react';
import {
  TileLayer,
  MapContainer,
  LayerGroup,
} from 'react-leaflet'
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import { BusquedaBoton } from "./busquedaBoton";
import EstadosMunicipiosFuerza from './estadosMunicipiosFuerza';
import { ZoomDisplay } from './evento_mapa';
import { CapturaClick } from './capturaCiclk';
import { UbicarCoordenada } from './ubicarCoordenada';
import {UbicarCoordenadadms} from './ubicarCoordenadasdms';
import {Ubicardm} from './ubicarCoordenadasdm';

const MapView = () => {
  const [position, setPosition] = useState([0, 0]);
  const mapRef = useRef(null);
  const layerGroupRef = useRef(null);

 

  const ResetMapButton = ({ layerGroupRef }) => {
    const handleResetClick = () => {
      if (mapRef.current) {

        layerGroupRef.current.clearLayers();
        /*  mapRef.current.setView([20.521602, -99.893896], 5); */

      }
    };

    return (
      <button
        onClick={handleResetClick}
        style={{
          position: 'absolute',
          top: '10px',
          left: '60px',
          zIndex: 1000,
        }}
      >
        Restablecer Mapa
      </button>
    );
  };

  const handleMapClick = (e) => {
    const { lat, lng } = e.latlng;
    setPosition([lat, lng]);
  };

  const handleMapReady = (map) => {
    map.on("click", handleMapClick);
    mapRef.current = map;
  };


  return (
    <>
      <MapContainer
        center={[20.521602, -99.893896]}
        zoom={10}
        scrollWheelZoom={true}
        whenReady={({ target: map }) => handleMapReady(map)}
        style={{ height: "100vh", width: "100%" }}
      >
        <TileLayer url="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}" />

        <ZoomDisplay />
        <LayerGroup ref={layerGroupRef}>
          <CapturaClick layerGroupRef={layerGroupRef} />
        </LayerGroup>
      </MapContainer>

      <ResetMapButton layerGroupRef={layerGroupRef} />
      <EstadosMunicipiosFuerza punto={position} layerGroupRef={layerGroupRef} />
      <BusquedaBoton layerGroupRef={layerGroupRef} mapRef={mapRef} />
      <UbicarCoordenada layerGroupRef={layerGroupRef} mapRef={mapRef} />
      <UbicarCoordenadadms layerGroupRef={layerGroupRef} mapRef={mapRef} />
      <Ubicardm layerGroupRef={layerGroupRef} mapRef={mapRef}/>
    </>
  )
}
export default MapView  


codigo busquedaBoton.js

import React, { useState, useEffect } from 'react';
import { Buscar } from "./buscar";
import L from 'leaflet';
import { polygon, centroid } from '@turf/turf';
import 'leaflet/dist/leaflet.css';

export const BusquedaBoton = ({ layerGroupRef, mapRef}) => {
  const [texBuscar, setTexBuscar] = useState('');
  const [resuelto, setResuelto] = useState('');
  const [centroide, setCentroide] = useState([0,0]);
  const [zoomapa, setZoomapa]=useState(0);
 
  const handleBuscar = async () => {
    const coordenadas = await Buscar({ texBuscar });
    setResuelto(coordenadas);
    setTexBuscar('');
  }

  useEffect(() => {
    if (layerGroupRef.current) {
      layerGroupRef.current.clearLayers();
    }

    if (resuelto.estado && resuelto.estado.length > 0) {
      const newPolygonEstado = new L.Polygon(resuelto.estado, {
        color: "#1b4f72",
        weight: 1,
        opacity: 0.9,
        fillColor: "#85c1e9",
        fillOpacity: 0.7
      });
      layerGroupRef.current.addLayer(newPolygonEstado);
      const estadoPolygon = polygon(resuelto.estado);
      const estadoCentroide = centroid(estadoPolygon).geometry.coordinates;
      setCentroide(estadoCentroide);
      setZoomapa(7);
    }

    if (resuelto.municipio && resuelto.municipio.length > 0) {
      const newPolygonMunicipio = new L.Polygon(resuelto.municipio, {
        color: "#4a235a",
        weight: 2,
        opacity: 0.5,
        fillColor: "#bb8fce",
        fillOpacity: 0.5
      });
      layerGroupRef.current.addLayer(newPolygonMunicipio);
      const municipioPolygon = polygon(resuelto.municipio);
      const municipioCentroide = centroid(municipioPolygon).geometry.coordinates;
      setCentroide(municipioCentroide);
      setZoomapa(11);
    }

  }, [resuelto, layerGroupRef]);

  useEffect(() => {
    if (centroide[0]>1) {
      mapRef.current.setView(centroide,zoomapa);

    }
  },[centroide,mapRef,zoomapa]);

  return (
    <>
      <div style={{
        position: 'absolute',
        top: '30px',
        left: '60px',
        zIndex: 1000,

      }}>
        <input
          type="text"
          value={texBuscar}
          onChange={(x) => setTexBuscar(x.target.value)}
          placeholder="Estado, Municipio"

        />
        <button onClick={handleBuscar}>Buscar capa</button>
      </div>
    </>
  );
};


codigo estadosMunicipiosFuerza.js


import React from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import mun from "./municipios_js/municipios_sep"

import {
    point,
    polygon,
    booleanPointInPolygon,
} from '@turf/turf';

const createPolygons = (coordinatesArray) => {
    return coordinatesArray.map(coords => polygon([coords]));
};

const EstadosMunicipiosFuerza = ({ punto, layerGroupRef }) => {

    let estadolocalizado = "";
    let coordenadasEstado = [];
    let municipiolocalizado = "";
    let coordenadasMunicipio = [];
    const pointObj = point([punto[0], punto[1]]);

    if (punto[0] === 0) { return null; }
    mun?.forEach((estado) => {
        let polygonObj = polygon(estado.COORDINATES);
        const isPointInsidePolygon = booleanPointInPolygon(pointObj, polygonObj);
        if (isPointInsidePolygon) {
            estadolocalizado = estado.NOM
            coordenadasEstado = estado.COORDINATES
            estado.MUNICIPYES?.forEach(element => {
                let polygonObjmun = createPolygons(element.coordinates);
                polygonObjmun.forEach((polygon, index) => {
                    const isPointInsidePolygonmun = booleanPointInPolygon(pointObj, polygon);
                    if (isPointInsidePolygonmun) {
                        municipiolocalizado = element.properties.NOM_MUN
                        coordenadasMunicipio = element.coordinates
                    }
                });
            })
        }
    })
    if(municipiolocalizado !==''){
    layerGroupRef.current.clearLayers();

    const newPolygonEstado = new L.Polygon(coordenadasEstado,{
        color: "#ff0000",
        weight: 1,
        opacity: 0.3,
        fillColor: "#ff7800",
        fillOpacity: 0.3
      });
    layerGroupRef.current.addLayer(newPolygonEstado);
   
    const newPolygonMunicipio = new L.Polygon(coordenadasMunicipio,{
        color: "#641e16",
        weight: 2,
        opacity: 0.5,
        fillColor: "#e6b0aa",
        fillOpacity: 0.5
      })/* .bindPopup("<b> Estado </b> : <br>" + estadolocalizado + " <br> <b>Municipio</b> : <br>" + municipiolocalizado) */;
    layerGroupRef.current.addLayer(newPolygonMunicipio);
    }else{
       
        alert("coordenadas fuera del territorio nacional  ****  click ***");
        layerGroupRef.current.clearLayers();
    }
    return (null);

};
export default EstadosMunicipiosFuerza

codigo evento_mapa.js


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

export const ZoomDisplay = () => {
    const [zoom, setZoom] = useState(null);
   
    useMapEvent('zoomend', (event) => {
        setZoom(event.target.getZoom());
    });

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


codigo capturaClick.js


import React, { useState, useEffect } from 'react';
import { useMapEvent } from 'react-leaflet';
import L from 'leaflet';
import icon from "./icon";

export const CapturaClick = ({ layerGroupRef }) => {
    const [coordenadas, setCoordenadas] = useState([]);
    const [click, setClick] = useState([]);

    useMapEvent('mousemove', (event) => {
        if (event.latlng) {
            setCoordenadas([event.latlng.lat, event.latlng.lng]);
        }
    });

    useMapEvent('click', () => {
        if (coordenadas.length > 0) {
            setClick(coordenadas);
        }
    });

    useEffect(() => {
        if (click.length > 0 && layerGroupRef.current) {
            const newMarker = new L.Marker(click,{icon:icon}).bindPopup("Coordenadas : <br>"+click);
            layerGroupRef.current.addLayer(newMarker);
        }
    }, [click, layerGroupRef]);

    return (null);
};


codigo ubicarCoordenadas.js


import React, { useState, useEffect } from 'react';
import icon from "./icon";
import L from 'leaflet';
import mun from "./municipios_js/municipios_sep"
import { point, polygon, booleanPointInPolygon } from '@turf/turf';

const createPolygons = (coordinatesArray) => {
    return coordinatesArray.map(coords => polygon([coords]));
};

const BuscarPoligono = ({ coordenadas }) => {
    const pointObj = point([coordenadas[0], coordenadas[1]]);
    let polygonObj;
    let isPointInsidePolygon
    let polygonObjmun
    let isPointInsidePolygonmun
    let objcoordenadas = null;

    mun?.forEach((estado) => {
        polygonObj = polygon(estado.COORDINATES);
        isPointInsidePolygon = booleanPointInPolygon(pointObj, polygonObj);
        if (isPointInsidePolygon) {
            estado.MUNICIPYES?.forEach(element => {
                polygonObjmun = createPolygons(element.coordinates);
                polygonObjmun.forEach((polygon) => {
                    isPointInsidePolygonmun = booleanPointInPolygon(pointObj, polygon);
                    if (isPointInsidePolygonmun) {
                        objcoordenadas = { estado: estado.NOM, cooestado: estado.COORDINATES, municipio: element.properties.NOM_MUN, coomunicipio: element.coordinates };
                    }
                });
            })
        }
    });
    console.log("salida de la busqueda",objcoordenadas)
    return objcoordenadas;
}

export const UbicarCoordenada = ({ layerGroupRef, mapRef }) => {
    const [coordenadasBuscar, setCoordenadasBuscar] = useState('');
    const [coordenadas, setCoordenadas] = useState([]);
    const [bandera, setbandera]=useState(null);


    const handleUbicar = () => {
        if(coordenadasBuscar!==''){
        const partes = coordenadasBuscar.split(',').map(part => part.trim());
        setCoordenadas(partes);
        setCoordenadasBuscar('');
        }
    }

   

    useEffect(() => {
        if (coordenadas.length > 0 && layerGroupRef.current) {
            const coordenadasPoligono = BuscarPoligono({ coordenadas });
            setbandera(coordenadasPoligono);
            if(coordenadasPoligono!==null){
                layerGroupRef.current.clearLayers();
                const newPolygonEstado = new L.Polygon(coordenadasPoligono.cooestado, {
                    color: "#424949",
                    weight: 1,
                    opacity: 1,
                    fillColor: "#eaeded",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonEstado);

                const newPolygonMunicipio = new L.Polygon(coordenadasPoligono.coomunicipio, {
                    color: "#7b7d7d",
                    weight: 2,
                    opacity: 1,
                    fillColor: "#858de9  ",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonMunicipio);
                const newMarker = new L.Marker(coordenadas, { icon: icon }).bindPopup("Ubicacion : <br>" + coordenadas + "<br><b> Estado :</b><br>" + coordenadasPoligono.estado + "<br> <b>Municipio :</b><br>" + coordenadasPoligono.municipio);
                layerGroupRef.current.addLayer(newMarker);
            }
        }
    }, [layerGroupRef, coordenadas]);

    useEffect(() => {
        if (coordenadas.length>1 && bandera!= null ) {
            mapRef.current.setView(coordenadas, 13);
            setbandera(null);      
        }
    }, [mapRef,coordenadas,bandera]);

    return (
        <>
            <div style={{
                position: 'absolute',
                top: '55px',
                left: '60px',
                zIndex: 1000,

            }}>
                <input
                    type="text"
                    value={coordenadasBuscar}
                    onChange={(x) => setCoordenadasBuscar(x.target.value)}
                    placeholder="00.00000000 , 00.00000000"

                />
                <button onClick={handleUbicar}>Ubicar DD</button>
            </div>

           
       
        </>
    );
}


codigo de ubicarCoordenadasdm


import React, { useState, useEffect } from 'react';
import icon from "./icon";
import L from 'leaflet';
import mun from "./municipios_js/municipios_sep"
import { point, polygon, booleanPointInPolygon } from '@turf/turf';

const createPolygons = (coordinatesArray) => {
    return coordinatesArray.map(coords => polygon([coords]));
};

const BuscarPoligono = ({ coordenadas }) => {
    const pointObj = point([coordenadas[0], coordenadas[1]]);
    let polygonObj;
    let isPointInsidePolygon
    let polygonObjmun
    let isPointInsidePolygonmun
    let objcoordenadas = null;

    mun?.forEach((estado) => {
        polygonObj = polygon(estado.COORDINATES);
        isPointInsidePolygon = booleanPointInPolygon(pointObj, polygonObj);
        if (isPointInsidePolygon) {
            estado.MUNICIPYES?.forEach(element => {
                polygonObjmun = createPolygons(element.coordinates);
                polygonObjmun.forEach((polygon) => {
                    isPointInsidePolygonmun = booleanPointInPolygon(pointObj, polygon);
                    if (isPointInsidePolygonmun) {
                        objcoordenadas = { estado: estado.NOM, cooestado: estado.COORDINATES, municipio: element.properties.NOM_MUN, coomunicipio: element.coordinates };
                    }
                });
            })
        }
    });
    console.log("salida de la busqueda",objcoordenadas)
    return objcoordenadas;
}

export const Ubicardm = ({ layerGroupRef, mapRef }) => {
    const [coordenadas, setCoordenadas] = useState([]);
    const [bandera, setbandera]=useState(null);
    const [dms, setDms] = useState({ degrees: ''});
    const [dmsw, setDmsw] = useState({ degreesw: ''});
    const [decimal, setDecimal] = useState(0);
    const [decimalw, setDecimalw] = useState(0);



    const handleDmsChange = (e) => {
        setDms({
            ...dms,
            [e.target.name]: parseFloat(e.target.value)
        });
    };

    const handleDmsChangew = (x) => {
        setDmsw({
            ...dmsw,
            [x.target.name]: parseFloat(x.target.value)
        });
    };

    const dmToDecimal = (degrees) => {
        let grados,minutos,coordenada;
        if(degrees>1190){
            grados=Math.floor(degrees/100);
            minutos=degrees-(grados*100);
            coordenada=grados+(minutos/60);
        }else{
            grados=Math.floor(degrees/10);
            minutos=degrees-(grados*10);
            coordenada=grados+(minutos/60);
        }
        return coordenada;
    }

    const convertDmsToDecimal = () => {
        const { degrees} = dms;
        const { degreesw} = dmsw;
        if(degrees===0 || degrees===null) return [0,0];
        setDecimal(dmToDecimal(degrees));
        setDecimalw(dmToDecimal(degreesw)*-1);
        setCoordenadas([decimal,decimalw]);
        console.log("----coordenada----",dmToDecimal(degrees),"    ",(dmToDecimal(degreesw)*-1));
    };

   

     useEffect(() => {
        if (coordenadas.length > 0 && layerGroupRef.current) {
            const coordenadasPoligono = BuscarPoligono({ coordenadas });
            setbandera(coordenadasPoligono);
            if(coordenadasPoligono!==null){
                layerGroupRef.current.clearLayers();
                const newPolygonEstado = new L.Polygon(coordenadasPoligono.cooestado, {
                    color: "#424949",
                    weight: 1,
                    opacity: 1,
                    fillColor: "#eaeded",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonEstado);

                const newPolygonMunicipio = new L.Polygon(coordenadasPoligono.coomunicipio, {
                    color: "#7b7d7d",
                    weight: 2,
                    opacity: 1,
                    fillColor: "#858de9  ",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonMunicipio);
                const newMarker = new L.Marker(coordenadas, { icon: icon }).bindPopup("Ubicacion : <br>" + coordenadas + "<br><b> Estado :</b><br>" + coordenadasPoligono.estado + "<br> <b>Municipio :</b><br>" + coordenadasPoligono.municipio);
                layerGroupRef.current.addLayer(newMarker);
            }
        }
    }, [layerGroupRef, coordenadas]);

    useEffect(() => {
        if (coordenadas.length>1 && bandera!= null ) {
            mapRef.current.setView(coordenadas, 13);
            setbandera(null);      
        }
    }, [mapRef,coordenadas,bandera]);

    return (
        <>
 
            <div style={{
                position: 'absolute',
                top: '160px',
                left: '60px',
                zIndex: 1000,

            }}>
           
            <input
                type="number"
                name="degrees"
                value={dms.degrees}
                onChange={handleDmsChange}
                placeholder="Grados"
            />

            <label> N </label>

        </div>

        <div style={{
                position: 'absolute',
                top: '190px',
                left: '60px',
                zIndex: 1000,

            }}>
           
            <input
                type="number"
                name="degreesw"
                value={dmsw.degreesw}
                onChange={handleDmsChangew}
                placeholder="Grados"
            />
       
            <label> W </label>
            <button onClick={convertDmsToDecimal}>Ubicar DM</button>
        </div>

       
        </>
    );
}


codigo de ubicarCoordenadasdms,js


import React, { useState, useEffect } from 'react';
import icon from "./icon";
import L from 'leaflet';
import mun from "./municipios_js/municipios_sep"
import { point, polygon, booleanPointInPolygon } from '@turf/turf';

const createPolygons = (coordinatesArray) => {
    return coordinatesArray.map(coords => polygon([coords]));
};

const BuscarPoligono = ({ coordenadas }) => {
    const pointObj = point([coordenadas[0], coordenadas[1]]);
    let polygonObj;
    let isPointInsidePolygon
    let polygonObjmun
    let isPointInsidePolygonmun
    let objcoordenadas = null;

    mun?.forEach((estado) => {
        polygonObj = polygon(estado.COORDINATES);
        isPointInsidePolygon = booleanPointInPolygon(pointObj, polygonObj);
        if (isPointInsidePolygon) {
            estado.MUNICIPYES?.forEach(element => {
                polygonObjmun = createPolygons(element.coordinates);
                polygonObjmun.forEach((polygon) => {
                    isPointInsidePolygonmun = booleanPointInPolygon(pointObj, polygon);
                    if (isPointInsidePolygonmun) {
                        objcoordenadas = { estado: estado.NOM, cooestado: estado.COORDINATES, municipio: element.properties.NOM_MUN, coomunicipio: element.coordinates };
                    }
                });
            })
        }
    });
    console.log("salida de la busqueda",objcoordenadas)
    return objcoordenadas;
}

export const UbicarCoordenadadms = ({ layerGroupRef, mapRef }) => {
    const [coordenadas, setCoordenadas] = useState([]);
    const [bandera, setbandera]=useState(null);
    const [dms, setDms] = useState({ degrees: '', minutes: '', seconds: '' });
    const [dmsw, setDmsw] = useState({ degreesw: '', minutesw: '', secondsw: '' });
    const [decimal, setDecimal] = useState(0);
    const [decimalw, setDecimalw] = useState(0);



    const handleDmsChange = (e) => {
        setDms({
            ...dms,
            [e.target.name]: parseFloat(e.target.value)
        });
    };

    const handleDmsChangew = (x) => {
        setDmsw({
            ...dmsw,
            [x.target.name]: parseFloat(x.target.value)
        });
    };

    const dmsToDecimal = (degrees, minutes, seconds) => {
        const decimal = Math.abs(degrees) + (minutes / 60) + (seconds / 3600);
        return decimal;
    }

    const convertDmsToDecimal = () => {
        const { degrees, minutes, seconds } = dms;
        const { degreesw, minutesw, secondsw } = dmsw;
        setDecimal(dmsToDecimal(degrees, minutes, seconds));
        setDecimalw(dmsToDecimal(degreesw, minutesw, secondsw)*-1);
        setCoordenadas([decimal,decimalw]);
    };

   

    useEffect(() => {
        if (coordenadas.length > 0 && layerGroupRef.current) {
            const coordenadasPoligono = BuscarPoligono({ coordenadas });
            setbandera(coordenadasPoligono);
            if(coordenadasPoligono!==null){
                layerGroupRef.current.clearLayers();
                const newPolygonEstado = new L.Polygon(coordenadasPoligono.cooestado, {
                    color: "#424949",
                    weight: 1,
                    opacity: 1,
                    fillColor: "#eaeded",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonEstado);

                const newPolygonMunicipio = new L.Polygon(coordenadasPoligono.coomunicipio, {
                    color: "#7b7d7d",
                    weight: 2,
                    opacity: 1,
                    fillColor: "#858de9  ",
                    fillOpacity: 0.3
                });
                layerGroupRef.current.addLayer(newPolygonMunicipio);
                const newMarker = new L.Marker(coordenadas, { icon: icon }).bindPopup("Ubicacion : <br>" + coordenadas + "<br><b> Estado :</b><br>" + coordenadasPoligono.estado + "<br> <b>Municipio :</b><br>" + coordenadasPoligono.municipio);
                layerGroupRef.current.addLayer(newMarker);
            }
        }
    }, [layerGroupRef, coordenadas]);

    useEffect(() => {
        if (coordenadas.length>1 && bandera!= null ) {
            mapRef.current.setView(coordenadas, 13);
            setbandera(null);      
        }
    }, [mapRef,coordenadas,bandera]);

    return (
        <>
 
            <div style={{
                position: 'absolute',
                top: '80px',
                left: '60px',
                zIndex: 1000,

            }}>
           
            <input
                type="number"
                name="degrees"
                value={dms.degrees}
                onChange={handleDmsChange}
                placeholder="Grados"
            />
            <input
                type="number"
                name="minutes"
                value={dms.minutes}
                onChange={handleDmsChange}
                placeholder="Minutos"
            />
            <input
                type="number"
                name="seconds"
                value={dms.seconds}
                onChange={handleDmsChange}
                placeholder="Segundos"
            />
            <label> N </label>

        </div>

        <div style={{
                position: 'absolute',
                top: '105px',
                left: '60px',
                zIndex: 1000,

            }}>
           
            <input
                type="number"
                name="degreesw"
                value={dmsw.degreesw}
                onChange={handleDmsChangew}
                placeholder="Grados"
            />
            <input
                type="number"
                name="minutesw"
                value={dmsw.minutesw}
                onChange={handleDmsChangew}
                placeholder="Minutos"
            />
            <input
                type="number"
                name="secondsw"
                value={dmsw.secondsw}
                onChange={handleDmsChangew}
                placeholder="Segundos"
            />
            <label> W </label>
            <button onClick={convertDmsToDecimal}>Ubicar DMS</button>
        </div>

       
        </>
    );
}