{"_id":"@datosgeo-atdt/geo-herramientas","_rev":"10-4d7ffa3fab7cde0d5eaebd10699774b6","name":"@datosgeo-atdt/geo-herramientas","dist-tags":{"latest":"1.2.0"},"versions":{"0.1.0":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.1.0","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.1.0","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"58e72e343bb4d5b41f4c8e1df6be8d6654ba8192","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.1.0.tgz","fileCount":7,"integrity":"sha512-tOwjtdZ5j0KV0IQKU1WdEaVIKyrqZ9VuReHiTkNZ2koDJegQiV7Km6dh0Yeorcz3UHwdL/lq9SjXa+xAELm5uQ==","signatures":[{"sig":"MEUCICM6lggVBhezayaQsl0IJgOu+WsEwHFcC9QdJC7s3qodAiEA1QrCH1A31CGfJGBaa/kbt+5o2J2X4qnEA+JKzFflepU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173850},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"f22d2ca7785497a4b76da12c04de481d3499a8f5","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.1.0_1772146537847_0.579835153796534","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.1.1","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.1.1","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"854353a8329035d261eee3154bc8c0b3e807cd58","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.1.1.tgz","fileCount":8,"integrity":"sha512-YspudDQpoEFyFl3zjwiDMXjrGE0IwHWiCfNTePGiWSDOc3tCw7+9J10I246cP1ZUectLX1iKKXJw7whb8EcruQ==","signatures":[{"sig":"MEUCIFBsaesYyS4kLLTohLNrvSKGVogeOugcKPi7CUE6WavNAiEAxPQt9SO9gLNnxp+jwbvtObkO653zW7aeMVVQhVWBq/8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":188056},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"10757a1b4345abe15871f320b94714fc0be69306","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.1.1_1772146921472_0.1967232074013836","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.1.2","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.1.2","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"fb692903a1ad3c77b5fb46547e2c58bd1ca9d690","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.1.2.tgz","fileCount":8,"integrity":"sha512-ykxfT/gczWe/RBgwajvl7Oh9HFnOMRzLSBDbF7hpS+u1bwgS40nzkwP6brtUBr+quyZI3HqRIoNSFrahTHabCg==","signatures":[{"sig":"MEUCIQCYhJtZl+SfInBCPbcFehFEtUxxR2OCLEAr7hu0jJsiYgIgImw4Aaekvwtqyze0UcHRkiBx6h/GGFGWVpvDKsJJ+/0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":221868},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"15c8a1a8636abb48cf44f3a3307bd1c4d84b3ea1","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.1.2_1772212779725_0.7935280669529303","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.2.1","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.2.1","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"0af976ebde9792a037a7d2fd90882e8c5d4258c6","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.2.1.tgz","fileCount":8,"integrity":"sha512-ayaWhKQ//CBlMxxnftVUWSGsC9YD0/plyTPdGLDwLtNXw33RIjmC1D3B//IpEqq3RUhf8J+v4JYEnQhY0mTQyw==","signatures":[{"sig":"MEUCIGY6sluqoggu3brqbi1e+zw0RJuAoXw/A6E0ODjASz1bAiEAj7Dp6EkIIJ/lveS3qBby35M3I7nPrY6My3LYaysogM4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225066},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"6ee33a313c27b9a35596627f42202cc11b1cc125","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.2.1_1772213066341_0.8819007565745176","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.2.3","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.2.3","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"c023a9c915d4df4fd52cf3065e7ec17c0c339563","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.2.3.tgz","fileCount":8,"integrity":"sha512-G2tylg7jcRfDIf4hI7Fwxt+00A/nHDyTfe1t4psna2594AGscuLNxEzCOh7zlhawTWF7uh1FXzuCOOWpUsiBWw==","signatures":[{"sig":"MEUCIQDgaljy6yCQB7PUe48EIvBjKkqulhwo4XXgQyTrdhtf8gIgQsbhxTuqzQxrgkOtB/FQeLwkD73xJVyDJEhXVsxvp+I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":228876},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"7e62a76e129cedff45898fd000a5311af094784f","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.2.3_1772214002684_0.4193560770974194","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.2.4","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.2.4","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"cb463d8dcfe45ed932493bc7849ab2aea3dd271e","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.2.4.tgz","fileCount":10,"integrity":"sha512-ynG9ZM/5wjdQfB66gvfFl1n6saqHR35WIMpb65wS2RusuDhZY2nLlWoxDlV6mdT+RwKgAHDAaD5/nylE9mBkCA==","signatures":[{"sig":"MEUCICYSO0lxkDRqfw4wFD8D4tPuosQEqzPOAJSf8HQj5eZfAiEAsLPM5RG+QO7uBN2p2i7rwGB2l9Cawtb1MvOH9vZv73E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":214669},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dist/index.css":"./dist/index.css"},"gitHead":"b3889383001163ee6f2761f98b916aff18bb405b","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.2.4_1772214837102_0.12459686925995461","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@datosgeo-atdt/geo-herramientas","version":"0.2.5","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@0.2.5","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"46e0ab5c0493f4a926dd682fa4ea0f4c6e920dc3","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-0.2.5.tgz","fileCount":10,"integrity":"sha512-CA4zE28iQ0+u8GcIS9esavvY+Gz0BQx450tYugtuTdVUx2fYHKusuwoWLpIpciM1uBd+lRrINvuhgey56fKxqA==","signatures":[{"sig":"MEYCIQCX4L39U+rWqZaGNtsyD7v7vT55p0BprVxoG56Lk8HmJwIhAO1gx4Db3BKTylyln3/KLMnvqBiBlsg+pzulSZMz7ugE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":214824},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dist/index.css":"./dist/index.css"},"gitHead":"159cd8eebfaec2a5e013a572001dbd18848e98b4","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_0.2.5_1772215649364_0.5111651162502846","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@datosgeo-atdt/geo-herramientas","version":"1.0.0","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","_id":"@datosgeo-atdt/geo-herramientas@1.0.0","maintainers":[{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"dist":{"shasum":"ec193fbbfc6147e82cad0cfe9b71f7c93866c4f0","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-1.0.0.tgz","fileCount":10,"integrity":"sha512-0VBi85Z7qzJ0jLp4vygw6WmhQ5TvIIv+hT1eBZqhF3U1yDUuHWsD45J99hpNhcx8/QOZ4edPS4ov8Xu5e+mHeQ==","signatures":[{"sig":"MEQCIF+lKcFHUvbRRfHh6du8MHSZkKgsbWAgwy4lBVDAGjHxAiBPO8MblotY0tmJYxxhdzquP+10YYczGmGV08PTOkU1BA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":217014},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dist/index.css":"./dist/index.css"},"gitHead":"776c0db21f5642ee45c6631764a0eed13fc75485","scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},"_npmVersion":"11.6.2","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","maplibre-gl":"^5.19.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","maplibre-gl":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/geo-herramientas_1.0.0_1772230887301_0.9995877151573558","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@datosgeo-atdt/geo-herramientas","version":"1.2.0","description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","main":"dist/index.cjs","module":"dist/index.js","types":"dist/index.d.ts","type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dist/index.css":"./dist/index.css"},"scripts":{"build":"tsup","build:watch":"tsup --watch","prepublishOnly":"npm run build"},"keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"author":{"name":"DatosGeo ATDT"},"license":"MIT","publishConfig":{"access":"public"},"peerDependencies":{"maplibre-gl":">=3.0.0","react":">=18.0.0","react-dom":">=18.0.0"},"devDependencies":{"@types/react":"^19.2.14","@types/react-dom":"^19.2.3","maplibre-gl":"^5.20.0","tsup":"^8.5.1","typescript":"^5.9.3"},"dependencies":{"@turf/turf":"^7.3.4","react-icons":"^5.5.0","react-loading-indicators":"^1.0.1"},"gitHead":"85cc1ca499d869714b5d0f109f3c349f16d42854","_id":"@datosgeo-atdt/geo-herramientas@1.2.0","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-tUa9m8hTvlVQFIgPU0bWV/jlH1i7yBk3U2aQefwlDFM7A47ainsfMDEL6XM7BGXlS5RPg4VN8dkOsmxCrn+CWA==","shasum":"8beaab96cc95c3eca8c6f708e66904e2c7856e5e","tarball":"https://registry.npmjs.org/@datosgeo-atdt/geo-herramientas/-/geo-herramientas-1.2.0.tgz","fileCount":10,"unpackedSize":336947,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBiBtJmDmI220NTRZeem8KGxOG4pHVJ7odJbKhRcPLKxAiEAqn5AogNosso36sdP4b4R9LuN9wfRqNjuuL2sbZ0mgf8="}]},"_npmUser":{"name":"edson_velazquez","email":"edson.velazquez@transformaciondigital.gob.mx"},"directories":{},"maintainers":[{"name":"edson_velazquez","email":"edson.velazquez@transformaciondigital.gob.mx"},{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/geo-herramientas_1.2.0_1773270853803_0.2454082332275871"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-26T22:55:37.786Z","modified":"2026-03-11T23:14:14.184Z","0.1.0":"2026-02-26T22:55:38.040Z","0.1.1":"2026-02-26T23:02:01.622Z","0.1.2":"2026-02-27T17:19:39.875Z","0.2.1":"2026-02-27T17:24:26.520Z","0.2.3":"2026-02-27T17:40:02.840Z","0.2.4":"2026-02-27T17:53:57.250Z","0.2.5":"2026-02-27T18:07:29.521Z","1.0.0":"2026-02-27T22:21:27.461Z","1.2.0":"2026-03-11T23:14:13.955Z"},"author":{"name":"DatosGeo ATDT"},"license":"MIT","keywords":["maplibre","geoespacial","gis","isocronas","rutas","mexico"],"description":"Herramientas de análisis geoespacial para mapas MapLibre GL JS","maintainers":[{"name":"edson_velazquez","email":"edson.velazquez@transformaciondigital.gob.mx"},{"name":"geoespacial_atdt","email":"edwin.flores@transformaciondigital.gob.mx"},{"name":"mario_snz","email":"mario.sanchez@transformaciondigital.gob.mx"},{"name":"yoshi_orta_atdt","email":"juan.hernandez@transformaciondigital.gob.mx"}],"readme":"# @datosgeo-atdt/geo-herramientas\r\n\r\nHerramientas de análisis geoespacial para React + MapLibre GL JS. Incluye hooks y componentes listos para usar: rutas óptimas, isócronas de tiempo, edificios 3D, terreno 3D y selector de estilos de mapa.\r\n\r\n## Instalación\r\n\r\n```bash\r\nnpm install @datosgeo-atdt/geo-herramientas\r\n```\r\n\r\n### Dependencias requeridas (peer dependencies)\r\n\r\nEste paquete requiere que tu proyecto ya tenga instalado:\r\n\r\n```bash\r\nnpm install maplibre-gl react react-dom\r\n```\r\n\r\n### Importar estilos CSS\r\n\r\n**Importante:** debes importar el CSS del paquete una sola vez en tu proyecto (por ejemplo en tu archivo `main.tsx` o `App.tsx`):\r\n\r\n```tsx\r\nimport '@datosgeo-atdt/geo-herramientas/dist/index.css';\r\n```\r\n\r\nSin esta importación los botones aparecerán sin estilo (negros y sin posicionamiento).\r\n\r\n---\r\n\r\n## Uso rápido\r\n\r\nTodos los hooks y componentes reciben un `mapRef` — la referencia al objeto `Map` de MapLibre que obtienes de tu instancia del mapa.\r\n\r\n```tsx\r\nimport { useRef } from 'react';\r\nimport maplibregl from 'maplibre-gl';\r\nimport 'maplibre-gl/dist/maplibre-gl.css';\r\nimport '@datosgeo-atdt/geo-herramientas/dist/index.css';\r\n\r\nconst mapRef = useRef<maplibregl.Map>(null);\r\n```\r\n\r\n---\r\n\r\n## Componentes\r\n\r\n### `<MapToolbar />`\r\n\r\nBarra de herramientas completa que integra todos los controles en un solo componente.\r\n\r\n```tsx\r\nimport { MapToolbar, useOptimalRoute, useIsochrone, useBuildings3D } from '@datosgeo-atdt/geo-herramientas';\r\n\r\nfunction MiMapa() {\r\n  const mapRef = useRef<maplibregl.Map>(null);\r\n  const [currentStyle, setCurrentStyle] = useState('https://www.mapabase.atdt.gob.mx/style.json');\r\n\r\n  const { routeMode, setRouteMode, clearRoute } = useOptimalRoute({ mapRef });\r\n  const { isochroneMode, setIsochroneMode, isLoading, isComplete, clearIsochrone } = useIsochrone({\r\n    mapRef,\r\n    orsApiKey: 'TU_API_KEY_ORS',\r\n  });\r\n  const { buildings3DEnabled, toggleBuildings3D } = useBuildings3D({ mapRef });\r\n\r\n  return (\r\n    <div style={{ position: 'relative', width: '100%', height: '100vh' }}>\r\n      {/* Tu mapa */}\r\n      <div ref={/* tu container ref */} style={{ width: '100%', height: '100%' }} />\r\n\r\n      <MapToolbar\r\n        mapRef={mapRef}\r\n        routeMode={routeMode}\r\n        onToggleRouteMode={() => setRouteMode(!routeMode)}\r\n        isochroneMode={isochroneMode}\r\n        onToggleIsochroneMode={() => setIsochroneMode(!isochroneMode)}\r\n        isochroneLoading={isLoading}\r\n        isochroneComplete={isComplete}\r\n        buildings3DEnabled={buildings3DEnabled}\r\n        onToggleBuildings3D={toggleBuildings3D}\r\n        currentStyle={currentStyle}\r\n        onStyleChange={setCurrentStyle}\r\n        onClear={() => { clearRoute(); clearIsochrone(); }}\r\n        activeColor=\"#611232\"\r\n      />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n#### Props de `MapToolbar`\r\n\r\n| Prop | Tipo | Requerido | Descripción |\r\n|------|------|-----------|-------------|\r\n| `mapRef` | `RefObject<maplibregl.Map>` | ✅ | Referencia al mapa |\r\n| `routeMode` | `boolean` | ✅ | Estado del modo ruta |\r\n| `onToggleRouteMode` | `() => void` | ✅ | Activa/desactiva modo ruta |\r\n| `isochroneMode` | `boolean` | ✅ | Estado del modo isocrona |\r\n| `onToggleIsochroneMode` | `() => void` | ✅ | Activa/desactiva modo isocrona |\r\n| `isochroneLoading` | `boolean` | — | Muestra spinner de carga |\r\n| `isochroneComplete` | `boolean` | — | Muestra indicador de éxito |\r\n| `buildings3DEnabled` | `boolean` | ✅ | Estado de edificios 3D |\r\n| `onToggleBuildings3D` | `() => void` | ✅ | Activa/desactiva edificios 3D |\r\n| `terrainEnabled` | `boolean` | — | Estado del terreno 3D (controlado externo) |\r\n| `setTerrainEnabled` | `Dispatch<SetStateAction<boolean>>` | — | Setter para terreno controlado externo |\r\n| `currentStyle` | `string` | ✅ | URL del estilo de mapa activo |\r\n| `onStyleChange` | `(url: string) => void` | ✅ | Callback al cambiar estilo |\r\n| `mapStyles` | `MapStyle[]` | — | Lista personalizada de estilos |\r\n| `onClear` | `() => void` | ✅ | Limpia todas las capas |\r\n| `activeColor` | `string` | — | Color de acento (default `#611232`) |\r\n| `className` | `string` | — | Clase CSS extra para la barra |\r\n\r\n---\r\n\r\n### `<MapStyleSelector />`\r\n\r\nSelector flotante de estilos de mapa base (blanco, color, oscuro, satélite).\r\n\r\n```tsx\r\nimport { MapStyleSelector } from '@datosgeo-atdt/geo-herramientas';\r\n\r\nconst [currentStyle, setCurrentStyle] = useState('https://www.mapabase.atdt.gob.mx/style.json');\r\n\r\n<MapStyleSelector\r\n  currentStyle={currentStyle}\r\n  onStyleChange={setCurrentStyle}\r\n/>\r\n```\r\n\r\nPara usar estilos personalizados:\r\n\r\n```tsx\r\nconst misEstilos = [\r\n  { id: 'claro', label: 'Claro', url: 'https://mi-servidor/style-light.json', icon: 'map' },\r\n  { id: 'oscuro', label: 'Oscuro', url: 'https://mi-servidor/style-dark.json', icon: 'map-dark' },\r\n  { id: 'satelite', label: 'Satélite', url: 'https://mi-servidor/style-sat.json', icon: 'satellite' },\r\n];\r\n\r\n<MapStyleSelector\r\n  currentStyle={currentStyle}\r\n  onStyleChange={setCurrentStyle}\r\n  styles={misEstilos}\r\n  activeColor=\"#1a73e8\"\r\n/>\r\n```\r\n\r\n#### Props de `MapStyleSelector`\r\n\r\n| Prop | Tipo | Requerido | Descripción |\r\n|------|------|-----------|-------------|\r\n| `currentStyle` | `string` | ✅ | URL del estilo activo |\r\n| `onStyleChange` | `(url: string) => void` | ✅ | Callback al seleccionar un estilo |\r\n| `styles` | `MapStyle[]` | — | Estilos personalizados (usa los de ATDT por defecto) |\r\n| `activeColor` | `string` | — | Color del botón activo |\r\n\r\n---\r\n\r\n### `<TerrainToggle />`\r\n\r\nBotón para activar/desactivar el terreno 3D con hillshading.\r\n\r\n```tsx\r\nimport { TerrainToggle } from '@datosgeo-atdt/geo-herramientas';\r\n\r\n// Modo no controlado (maneja su propio estado)\r\n<TerrainToggle mapRef={mapRef} />\r\n\r\n// Modo controlado (el estado lo manejas tú)\r\nconst [terrainEnabled, setTerrainEnabled] = useState(false);\r\n\r\n<TerrainToggle\r\n  mapRef={mapRef}\r\n  terrainEnabled={terrainEnabled}\r\n  setTerrainEnabled={setTerrainEnabled}\r\n  exaggeration={2}\r\n  activePitch={60}\r\n  activeBearing={-45}\r\n/>\r\n```\r\n\r\n#### Props de `TerrainToggle`\r\n\r\n| Prop | Tipo | Requerido | Descripción |\r\n|------|------|-----------|-------------|\r\n| `mapRef` | `RefObject<maplibregl.Map>` | ✅ | Referencia al mapa |\r\n| `terrainEnabled` | `boolean` | — | Estado controlado externamente |\r\n| `setTerrainEnabled` | `Dispatch<SetStateAction<boolean>>` | — | Setter controlado externamente |\r\n| `exaggeration` | `number` | — | Exageración del terreno (default `2`) |\r\n| `activePitch` | `number` | — | Inclinación al activar (default `60`) |\r\n| `activeBearing` | `number` | — | Rotación al activar (default `-45`) |\r\n\r\n---\r\n\r\n## Hooks\r\n\r\n### `useOptimalRoute`\r\n\r\nCalcula la ruta óptima entre múltiples puntos usando OSRM. El usuario hace clic en el mapa para agregar nodos.\r\n\r\n```tsx\r\nimport { useOptimalRoute } from '@datosgeo-atdt/geo-herramientas';\r\n\r\nconst {\r\n  routeMode,\r\n  setRouteMode,\r\n  selectedNodes,\r\n  setSelectedNodes,\r\n  routeData,\r\n  distanceText,\r\n  clearRoute,\r\n  isCalculating,\r\n} = useOptimalRoute({\r\n  mapRef,\r\n  lineColor: '#007cbf',   // color de la línea de ruta\r\n  lineWidth: 4,            // grosor en px\r\n  osrmUrl: 'https://router.project-osrm.org',  // servidor OSRM\r\n  profile: 'driving',      // 'driving' | 'walking' | 'cycling'\r\n});\r\n\r\n// Activar modo: el usuario hace clic en el mapa para agregar puntos\r\n<button onClick={() => setRouteMode(!routeMode)}>\r\n  {routeMode ? 'Cancelar ruta' : 'Trazar ruta'}\r\n</button>\r\n\r\n{distanceText && <p>Distancia total: {distanceText}</p>}\r\n\r\n<button onClick={clearRoute}>Limpiar</button>\r\n```\r\n\r\n#### Opciones de `useOptimalRoute`\r\n\r\n| Parámetro | Tipo | Default | Descripción |\r\n|-----------|------|---------|-------------|\r\n| `mapRef` | `RefObject<maplibregl.Map>` | — | Referencia al mapa |\r\n| `lineColor` | `string` | `'#007cbf'` | Color de la línea de ruta |\r\n| `lineWidth` | `number` | `4` | Grosor de la línea en px |\r\n| `osrmUrl` | `string` | `'https://router.project-osrm.org'` | URL del servidor OSRM |\r\n| `profile` | `string` | `'driving'` | Perfil de transporte |\r\n\r\n#### Valores retornados\r\n\r\n| Valor | Tipo | Descripción |\r\n|-------|------|-------------|\r\n| `routeMode` | `boolean` | Si el modo ruta está activo |\r\n| `setRouteMode` | `(active: boolean) => void` | Activa/desactiva el modo |\r\n| `selectedNodes` | `SelectedNode[]` | Nodos seleccionados por el usuario |\r\n| `setSelectedNodes` | `Dispatch` | Setter de nodos (para eliminar puntos manualmente) |\r\n| `routeData` | `number[][]` | Coordenadas de la ruta calculada |\r\n| `distanceText` | `string \\| null` | Distancia formateada (ej. `\"2.34 km\"`) |\r\n| `clearRoute` | `() => void` | Elimina ruta y puntos del mapa |\r\n| `isCalculating` | `boolean` | Indica si hay un cálculo en curso |\r\n\r\n---\r\n\r\n### `useIsochrone`\r\n\r\nGenera isócronas de tiempo (áreas alcanzables) usando OpenRouteService. El usuario hace clic en el mapa para generar el análisis.\r\n\r\n```tsx\r\nimport { useIsochrone } from '@datosgeo-atdt/geo-herramientas';\r\n\r\nconst {\r\n  isochroneMode,\r\n  setIsochroneMode,\r\n  isLoading,\r\n  isComplete,\r\n  clearIsochrone,\r\n  timeRange,\r\n  setTimeRange,\r\n} = useIsochrone({\r\n  mapRef,\r\n  orsApiKey: 'TU_API_KEY',           // API key de openrouteservice.org\r\n  ranges: [900, 1800, 3600],          // rangos en segundos: 15 min, 30 min, 1 hora\r\n  profile: 'driving-car',             // perfil de movilidad\r\n  colors: ['#D79BB3', '#A24D7B', '#4A0D4D'],  // un color por rango\r\n});\r\n\r\n// Activa el modo: el siguiente clic en el mapa genera las isócronas\r\n<button onClick={() => setIsochroneMode(!isochroneMode)}>\r\n  {isochroneMode ? 'Cancelar' : 'Generar isócronas'}\r\n</button>\r\n\r\n// Control de visibilidad por tiempo (en minutos)\r\n<input\r\n  type=\"range\"\r\n  min={15}\r\n  max={60}\r\n  value={timeRange}\r\n  onChange={e => setTimeRange(Number(e.target.value))}\r\n/>\r\n<span>Mostrar hasta {timeRange} min</span>\r\n```\r\n\r\n> Obtén tu API key gratuita en [openrouteservice.org](https://openrouteservice.org/dev/#/signup)\r\n\r\n#### Opciones de `useIsochrone`\r\n\r\n| Parámetro | Tipo | Default | Descripción |\r\n|-----------|------|---------|-------------|\r\n| `mapRef` | `RefObject<maplibregl.Map>` | — | Referencia al mapa |\r\n| `orsApiKey` | `string` | — | API key de OpenRouteService |\r\n| `ranges` | `number[]` | `[900, 1800, 3600]` | Rangos en segundos |\r\n| `profile` | `string` | `'driving-car'` | Perfil ORS (`'driving-car'`, `'foot-walking'`, `'cycling-regular'`) |\r\n| `colors` | `string[]` | colores morados | Un color por rango, del más pequeño al más grande |\r\n\r\n#### Valores retornados\r\n\r\n| Valor | Tipo | Descripción |\r\n|-------|------|-------------|\r\n| `isochroneMode` | `boolean` | Si el modo está activo |\r\n| `setIsochroneMode` | `(active: boolean) => void` | Activa/desactiva el modo |\r\n| `isLoading` | `boolean` | Calculando isócronas |\r\n| `isComplete` | `boolean` | Cálculo completado (se resetea en 2.5 s) |\r\n| `clearIsochrone` | `() => void` | Elimina las capas del mapa |\r\n| `timeRange` | `number` | Minutos visibles actualmente |\r\n| `setTimeRange` | `Dispatch` | Controla qué rangos se muestran |\r\n\r\n---\r\n\r\n### `useBuildings3D`\r\n\r\nRenderiza edificios en 3D con extrusión. Soporta tres modos de fuente: GeoJSON, vector tiles propios, o reutilizar una fuente que ya viene en el estilo del mapa.\r\n\r\n#### Modo 1 — GeoJSON (más simple)\r\n\r\n```tsx\r\nimport { useBuildings3D } from '@datosgeo-atdt/geo-herramientas';\r\n\r\nconst { buildings3DEnabled, toggleBuildings3D, isLoading } = useBuildings3D({\r\n  mapRef,\r\n  footprintsUrl: 'https://mi-servidor/edificios.geojson',\r\n  heightProperty: 'altura',\r\n  defaultHeight: 10,\r\n  buildingColor: '#c0b8b0',\r\n  baseColor: '#a09890',\r\n});\r\n\r\n<button onClick={toggleBuildings3D} disabled={isLoading}>\r\n  {buildings3DEnabled ? 'Ocultar edificios 3D' : 'Ver edificios 3D'}\r\n</button>\r\n```\r\n\r\n#### Modo 2 — Vector tiles propios\r\n\r\nCuando tienes un servidor de vector tiles propio que sí tiene CORS configurado para tu dominio:\r\n\r\n```tsx\r\nconst { buildings3DEnabled, toggleBuildings3D, isLoading } = useBuildings3D({\r\n  mapRef,\r\n  sourceType: 'vector',\r\n  footprintsUrl: 'https://mi-servidor/api/edificios',  // endpoint TileJSON\r\n  // sourceLayer no es necesario si el layer se llama 'footprints' (default automático)\r\n  sourceLayer: 'edificios',   // especificar solo si el layer tiene otro nombre\r\n  heightProperty: 'height_mean',\r\n  defaultHeight: 10,\r\n});\r\n```\r\n\r\n#### Modo 3 — Reutilizar fuente del estilo (recomendado para CORS)\r\n\r\nSi tu estilo de mapa ya incluye la fuente de edificios, úsala directamente en vez de cargarla de nuevo. Esto evita peticiones adicionales que pueden fallar por CORS cuando el servidor de tiles no permite tu dominio de desarrollo:\r\n\r\n```tsx\r\n// El estilo base ya tiene definida la fuente \"lotes\" con los tiles de edificios.\r\n// Pasamos existingSourceId para reutilizarla sin hacer ninguna petición extra.\r\n// sourceLayer se omite: cuando hay existingSourceId se usa 'footprints' automáticamente.\r\nconst { buildings3DEnabled, toggleBuildings3D, isLoading } = useBuildings3D({\r\n  mapRef,\r\n  existingSourceId: 'lotes',    // nombre exacto de la fuente en el estilo\r\n  heightProperty: 'height_mean',\r\n  buildingColor: '#DDDDDD',     // opcional: color personalizado\r\n  buildingOpacity: 0.7,         // opcional: opacidad entre 0 y 1\r\n});\r\n```\r\n\r\n> **¿Cómo sé el nombre de la fuente?** Está definido en el JSON de tu estilo de mapa, dentro de la clave `\"sources\"`. Por ejemplo: `\"sources\": { \"lotes\": { \"type\": \"vector\", ... } }`.\r\n> **¿Y el `sourceLayer`?** Por defecto es `'footprints'` cuando usas `existingSourceId` o `sourceType: 'vector'`. Solo pásalo explícitamente si tu tileset usa un nombre diferente.\r\n\r\n#### Opciones de `useBuildings3D`\r\n\r\n| Parámetro | Tipo | Default | Descripción |\r\n|-----------|------|---------|-------------|\r\n| `mapRef` | `RefObject<maplibregl.Map>` | — | Referencia al mapa |\r\n| `existingSourceId` | `string` | — | ID de una fuente ya cargada por el estilo. Si se pasa, `footprintsUrl` se ignora y no se hace ninguna petición extra |\r\n| `footprintsUrl` | `string` | URL ATDT | URL del GeoJSON o TileJSON. Se usa solo si `existingSourceId` no se especifica |\r\n| `sourceType` | `'geojson' \\| 'vector'` | `'geojson'` | Tipo de fuente cuando se crea una nueva (ignorado con `existingSourceId`) |\r\n| `sourceLayer` | `string` | `'footprints'`* | Nombre del layer dentro del tileset. *Se auto-asigna `'footprints'` cuando se usa `existingSourceId` o `sourceType: 'vector'`; solo pásalo si tu tileset usa otro nombre |\r\n| `heightProperty` | `string` | `'altura'` | Propiedad del feature que contiene la altura en metros |\r\n| `defaultHeight` | `number` | `10` | Altura en metros cuando el feature no tiene la propiedad |\r\n| `buildingColor` | `string` | `'#c0b8b0'` | Color de la extrusión |\r\n| `buildingOpacity` | `number` | `0.85` | Opacidad de la extrusión (0–1) |\r\n| `baseColor` | `string` | `'#a09890'` | Color del piso del edificio |\r\n\r\n---\r\n\r\n## Ejemplo completo\r\n\r\nEl patrón recomendado separa la lógica de los hooks en un componente hijo que solo se monta **después** de que el mapa está listo (`mapLoaded`). Esto evita que los hooks intenten acceder al mapa antes de que exista.\r\n\r\n```tsx\r\nimport { useRef, useState, useEffect } from 'react';\r\nimport maplibregl from 'maplibre-gl';\r\nimport 'maplibre-gl/dist/maplibre-gl.css';\r\nimport {\r\n  MapToolbar,\r\n  useOptimalRoute,\r\n  useIsochrone,\r\n  useBuildings3D,\r\n} from '@datosgeo-atdt/geo-herramientas';\r\n\r\nconst STYLE_INICIAL = 'https://www.mapabase.atdt.gob.mx/style.json';\r\nconst ORS_API_KEY = 'TU_API_KEY_ORS';\r\n\r\n// ── Componente hijo: solo se monta cuando el mapa ya está listo ──────────────\r\nfunction MapControls({\r\n  mapRef,\r\n  currentStyle,\r\n  setCurrentStyle,\r\n}: {\r\n  mapRef: React.RefObject<maplibregl.Map>;\r\n  currentStyle: string;\r\n  setCurrentStyle: (s: string) => void;\r\n}) {\r\n  const route = useOptimalRoute({ mapRef });\r\n  const isochrone = useIsochrone({ mapRef, orsApiKey: ORS_API_KEY });\r\n\r\n  // Si el estilo del mapa ya incluye la fuente \"lotes\", usa existingSourceId\r\n  // para evitar una segunda petición que puede fallar por CORS en desarrollo.\r\n  // sourceLayer se omite: con existingSourceId se usa 'footprints' automáticamente.\r\n  const buildings = useBuildings3D({\r\n    mapRef,\r\n    existingSourceId: 'lotes',   // fuente ya cargada por el estilo base\r\n    heightProperty: 'height_mean',\r\n  });\r\n\r\n  return (\r\n    <MapToolbar\r\n      mapRef={mapRef}\r\n      routeMode={route.routeMode}\r\n      onToggleRouteMode={() => route.setRouteMode(!route.routeMode)}\r\n      isochroneMode={isochrone.isochroneMode}\r\n      onToggleIsochroneMode={() => isochrone.setIsochroneMode(!isochrone.isochroneMode)}\r\n      isochroneLoading={isochrone.isLoading}\r\n      isochroneComplete={isochrone.isComplete}\r\n      buildings3DEnabled={buildings.buildings3DEnabled}\r\n      onToggleBuildings3D={buildings.toggleBuildings3D}\r\n      currentStyle={currentStyle}\r\n      onStyleChange={setCurrentStyle}\r\n      onClear={() => { route.clearRoute(); isochrone.clearIsochrone(); }}\r\n    />\r\n  );\r\n}\r\n\r\n// ── Componente principal del mapa ────────────────────────────────────────────\r\nexport default function MapView() {\r\n  const containerRef = useRef<HTMLDivElement>(null);\r\n  const mapRef = useRef<maplibregl.Map>(null);\r\n  const [mapLoaded, setMapLoaded] = useState(false);\r\n  const [currentStyle, setCurrentStyle] = useState(STYLE_INICIAL);\r\n  const isFirstStyle = useRef(true);\r\n\r\n  // Inicializar el mapa\r\n  useEffect(() => {\r\n    if (!containerRef.current) return;\r\n    const map = new maplibregl.Map({\r\n      container: containerRef.current,\r\n      style: STYLE_INICIAL,\r\n      center: [-99.133, 19.432],\r\n      zoom: 11,\r\n    });\r\n    (mapRef as React.MutableRefObject<maplibregl.Map>).current = map;\r\n    map.addControl(new maplibregl.NavigationControl());\r\n    map.on('style.load', () => setMapLoaded(true));\r\n    return () => { map.remove(); setMapLoaded(false); };\r\n  }, []);\r\n\r\n  // Cambiar estilo de mapa base\r\n  useEffect(() => {\r\n    if (isFirstStyle.current) { isFirstStyle.current = false; return; }\r\n    setMapLoaded(false);\r\n    mapRef.current?.setStyle(currentStyle);\r\n  }, [currentStyle]);\r\n\r\n  return (\r\n    // ⚠️ position: relative es obligatorio para que los botones\r\n    // se posicionen correctamente sobre el mapa\r\n    <div style={{ position: 'relative', width: '100%', height: '100vh' }}>\r\n      <div ref={containerRef} style={{ width: '100%', height: '100%' }} />\r\n      {mapLoaded && (\r\n        <MapControls\r\n          mapRef={mapRef as React.RefObject<maplibregl.Map>}\r\n          currentStyle={currentStyle}\r\n          setCurrentStyle={setCurrentStyle}\r\n        />\r\n      )}\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n---\r\n\r\n## Tipos exportados\r\n\r\n```ts\r\nimport type {\r\n  MapRef,\r\n  SelectedNode,\r\n  MapStyle,\r\n  UseOptimalRouteOptions,\r\n  UseOptimalRouteReturn,\r\n  UseIsochroneOptions,\r\n  UseIsochroneReturn,\r\n  UseBuildings3DOptions,\r\n  UseBuildings3DReturn,\r\n  TerrainToggleProps,\r\n  MapStyleSelectorProps,\r\n  MapToolbarProps,\r\n} from '@datosgeo-atdt/geo-herramientas';\r\n```\r\n\r\n---\r\n\r\n## Licencia\r\n\r\nMIT © [DatosGeo ATDT](https://www.atdt.gob.mx)\r\n","readmeFilename":"README.md"}