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.
Busqueda en archivo json para presentarlo en capa
Codigo de App.js
import './App.css';
import MapView from './components/MapView';
function App() {
return (
<div>
<p>mapa</p>
<MapView/>
</div>
);
}
export default App;
Codigo de 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'
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} />
</>
)
}
export default MapView
Codigo de 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 de 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 buscar.js
import mun from "./municipios_js/municipios_sep"
const operacionBusqueda = ({ texBuscar }) => {
return new Promise((resolve) => {
const parts = texBuscar.split(',').map(part => part.trim());
if(parts.length>1){
mun?.forEach((estado) => {
if (estado.NOM.toUpperCase() === parts[0].toUpperCase()) {
estado.MUNICIPYES?.forEach(element => {
if (element.properties.NOM_MUN.toUpperCase() === parts[1].toUpperCase()) {
resolve({ estado: estado.COORDINATES,nomestado:estado.NOM,municipio: element.coordinates, nommunicipio: element.properties.NOM_MUN});
}
})
}
});
}else{
mun?.forEach((estado) => {
if (estado.NOM.toUpperCase() === parts[0].toUpperCase()) {
resolve({ estado: estado.COORDINATES,nomestado:estado.NOM});
}
});
}
});
};
export const Buscar = async ({ texBuscar }) => {
try {
const data = await operacionBusqueda({ texBuscar });
return data;
} catch (err) {
console.log("error", texBuscar, " ### ", err);
} finally {
console.log("finaliza", texBuscar);
}
};
Codigo capturar click.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 icon.js
import L from "leaflet"
const icon = L.icon({
iconSize: [25, 41],
iconAnchor: [15, 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"
});
export default icon;
Codigo ubicarCoordenada
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</button>
</div>
</>
);
}
Codigo de ubicarCoordenadasdms
mport 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>
</>
);
}
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 municipios_sep.js
import aguascalientes from "./aguascalientes_mun";
import bajaCalifornia from "./bajaCalifornia_mun";
import bajaCaliforniaSur from "./bajaCaliforniaSur_mun";
import campeche from "./campeche_mun";
import chiapas from "./chiapas_mun";
import chihuahua from "./chihuahua_mun";
import cdmx from "./cdmx_mun";
import coahuila from "./coahuila_mun";
import colima from "./colima_mun";
import durango from "./durango_mun";
import mexico from "./mexico_mun";
import guanajuato from "./guanajuato_mun";
import guerrero from "./guerrero_mun";
import hidalgo from "./hidalgo_mun";
import jalisco from "./jalisco_mun";
import michoacan from "./michoacan_mun";
import morelos from "./morelos_mun";
import nayarit from "./nayarit_mun";
import nuevoLeon from "./nuevoLeon_mun";
import oaxaca from "./oaxaca_prue";
import puebla from "./puebla_prue";
import queretaro from "./queretaro_mun";
import quintanaroo from "./quintanaroo_mun";
import sanLuisPotosi from "./sanLuisPotosi_mun";
import sinaloa from "./sinaloa_mun";
import sonora from "./sonora_mun";
import tabasco from "./tabasco_mun";
import tamaulipas from "./tamaulipas_mun";
import tlaxcala from "./tlaxcala_mun";
import veracruz from "./veracruz_prue";
import yucatan from "./yucatan_mun";
import zacatecas from "./zacatecas_mun";
const mun = [
aguascalientes,
bajaCalifornia,
bajaCaliforniaSur,
campeche,
chiapas,
chihuahua,
cdmx,
coahuila,
colima,
durango,
mexico,
guanajuato,
guerrero,
hidalgo,
jalisco,
michoacan,
morelos,
nayarit,
nuevoLeon,
oaxaca,
puebla,
queretaro,
quintanaroo,
sanLuisPotosi,
sinaloa,
sonora,
tabasco,
tamaulipas,
tlaxcala,
veracruz,
yucatan,
zacatecas,
]
export default mun;
Por el espacio del blog no se puede cargar los datos del los archivos de los estados ... la estructura del archivo de los estados seria esta :
export const aguascalientes = {
"CVE_ENT": "01",
"NOM": "Aguascalientes",
"CLAVES": "01000",
"DATA_ENT": [],
"COORDINATES": [[
[ 21.79620484 , -102.0645076 ],
[ 21.79620484 , -102.0645076 ],
]],
"MUNICIPYES": [
{"properties": { "CVE_ENT": "01", "CVE_MUN": "005", "NOM_MUN": "Jesus Maria", "Claves": "01005" },
"data":"1",
"coordinates": [[
[ 22.05066522 , -102.3356776 ],
[ 22.05171803 , -102.3357788 ],
[ 22.05066522 , -102.3356776 ]
]]
}
]
}
export default aguascalientes;
Vista del mapa