{"id":277,"date":"2026-03-05T16:31:04","date_gmt":"2026-03-05T16:31:04","guid":{"rendered":"https:\/\/wisp360.mx\/?page_id=277"},"modified":"2026-03-05T16:52:20","modified_gmt":"2026-03-05T16:52:20","slug":"cobertura","status":"publish","type":"page","link":"https:\/\/wisp360.mx\/index.php\/cobertura\/","title":{"rendered":"Cobertura"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"277\" class=\"elementor elementor-277\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f1877c7 e-flex e-con-boxed e-con e-parent\" data-id=\"f1877c7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-319e358 elementor-widget elementor-widget-html\" data-id=\"319e358\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n\n  <!-- Leaflet -->\n  <link\n    rel=\"stylesheet\"\n    href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\"\n    integrity=\"sha256-p4NxAoJBhIIN+hmNHrzRCf9tD\/miZyoHS5obTRR9BMY=\"\n    crossorigin=\"\"\n  \/>\n  <script\n    src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"\n    integrity=\"sha256-20nQCchB9co0qIjJZRGuk2\/Z9VM+kNiyxNV1lvTlZBo=\"\n    crossorigin=\"\"\n  ><\/script>\n\n  <style>\n    :root{\n      --panel-w: 280px;\n      --gap: 10px;\n      --radius: 10px;\n      --tap: 44px;\n      --shadow: 0 6px 18px rgba(0,0,0,.15);\n      --font: system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;\n      --brand: #781a13;\n    }\n    html,body{margin:0;padding:0;font-family:var(--font);background:#fafafa;}\n\n    \/* Map height responsive *\/\n    #map{width:100%;height:70vh;min-height:350px;}\n    @media (max-width:768px){ #map{height:55vh;} }\n    @media (min-width:1024px){ #map{height:80vh;} }\n\n    \/* Search panel styles *\/\n    .control-panel{\n      background:#fff;\n      width:var(--panel-w);\n      max-width:min(92vw,var(--panel-w));\n      padding:12px;\n      border-radius:var(--radius);\n      box-shadow:var(--shadow);\n      line-height:1.3;\n    }\n    .control-panel form{display:grid;gap:8px;}\n    .control-panel label{font-size:.95rem;font-weight:600;}\n    .control-panel input[type=\"text\"]{\n      font-size:1rem;padding:10px 12px;border:1px solid #ddd;border-radius:8px;min-height:var(--tap);\n    }\n    .control-panel button{\n      font-size:1rem;padding:10px 14px;border:none;border-radius:999px;cursor:pointer;min-height:var(--tap);\n      background:var(--brand);color:#fff;\n    }\n    .control-panel button.secondary{background:#555;}\n    #search-results{\n      margin-top:8px;max-height:180px;overflow-y:auto;border-top:1px solid #eee;padding-top:8px;\n    }\n    .result-item{margin-bottom:8px;display:flex;gap:8px;align-items:flex-start;}\n    .result-item label{font-weight:500;line-height:1.2;}\n\n    \/* Search panel outside (for mobile, now below map) *\/\n    #search-panel-outside{padding:12px;display:flex;justify-content:center;}\n    @media (min-width:769px){ #search-panel-outside{display:none;} }\n  <\/style>\n<\/head>\n<body>\n\n  <!-- Map first -->\n  <div id=\"map\"><\/div>\n\n  <!-- Search panel (mobile: shown below map) -->\n  <div id=\"search-panel-outside\"><\/div>\n\n  <script>\n    \/\/ Initialize map\n    const map = L.map('map', { zoomControl: true }).setView([19.28786, -99.65324], 5);\n\n    L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n      attribution: '\u00a9 OpenStreetMap | <a href=\"https:\/\/www.altanredes.com\" target=\"_blank\" rel=\"noopener\">ALT\u00c1N<\/a> Altan-Maps',\n      maxZoom: 19\n    }).addTo(map);\n\n    L.control.scale().addTo(map);\n\n    \/\/ WMS layer\n    L.tileLayer.wms(\n      'https:\/\/geomap.altanredes.com\/geoserver\/web_altanredes_geoaltan\/ows?SERVICE=WMS&authkey=6bf1b0fv',\n      { layers:'Cobertura_Garantizada', format:'image\/png', transparent:true, tiled:true }\n    ).addTo(map);\n\n    \/\/ Shared panel HTML\n    function panelHTML(){\n      return `\n        <div class=\"control-panel\">\n          <form id=\"search-form\">\n            <label for=\"search-input\">B\u00fasqueda por estado, municipio o colonia<\/label>\n            <input type=\"text\" id=\"search-input\" placeholder=\"Ej: Naucalpan, Centro...\">\n            <button type=\"submit\">Buscar<\/button>\n            <div style=\"height:1px;background:#eee;margin:6px 0;\"><\/div>\n            <label for=\"coord-input\">Latitud, Longitud<\/label>\n            <input type=\"text\" id=\"coord-input\" placeholder=\"Ej: 19.28786, -99.65324\">\n            <button type=\"button\" id=\"coordinate-search\" class=\"secondary\">Buscar por coordenadas<\/button>\n          <\/form>\n          <div id=\"search-results\"><\/div>\n        <\/div>\n      `;\n    }\n\n    \/\/ Search handlers\n    function wireSearchHandlers(root){\n      const form   = root.querySelector('#search-form');\n      const input  = root.querySelector('#search-input');\n      const coord  = root.querySelector('#coord-input');\n      const btnCrd = root.querySelector('#coordinate-search');\n      const box    = root.querySelector('#search-results');\n\n      form.addEventListener('submit', (e)=>{\n        e.preventDefault();\n        const q = input.value.trim();\n        if(!q) return;\n        const url = `https:\/\/nominatim.openstreetmap.org\/search?format=json&q=${encodeURIComponent(q)}&bounded=1&viewbox=-118.601,32.718,-86.711,14.532&limit=8`;\n        fetch(url,{headers:{'Accept-Language':'es'}})\n          .then(r=>r.json())\n          .then(data=>{\n            box.innerHTML='';\n            if(Array.isArray(data)&&data.length){\n              data.forEach((res,i)=>{\n                const id=`loc_${i}`;\n                const item=document.createElement('div');\n                item.className='result-item';\n                item.innerHTML=`<input type=\"radio\" name=\"location\" value=\"${i}\" id=\"${id}\">\n                                <label for=\"${id}\">${res.display_name}<\/label>`;\n                box.appendChild(item);\n              });\n              [...box.querySelectorAll('input[name=\"location\"]')].forEach(r=>{\n                r.addEventListener('change',function(){\n                  const sel=data[Number(this.value)];\n                  const lat=parseFloat(sel.lat), lon=parseFloat(sel.lon);\n                  if(isFinite(lat)&&isFinite(lon)){\n                    map.setView([lat,lon],13);\n                    L.marker([lat,lon]).addTo(map).bindPopup(sel.display_name).openPopup();\n                  }\n                });\n              });\n            }else{\n              box.textContent='Ubicaci\u00f3n no encontrada.';\n            }\n          })\n          .catch(()=>{ box.textContent='Error consultando la ubicaci\u00f3n.'; });\n      });\n\n      btnCrd.addEventListener('click', ()=>{\n        const parts = coord.value.split(',');\n        if(parts.length!==2) return alert('Formato inv\u00e1lido. Use: latitud, longitud');\n        const lat=parseFloat(parts[0]), lon=parseFloat(parts[1]);\n        if(!isFinite(lat)||!isFinite(lon)) return alert('Coordenadas inv\u00e1lidas');\n        map.setView([lat,lon],13);\n        L.marker([lat,lon]).addTo(map).bindPopup(`Coordenadas: ${lat}, ${lon}`).openPopup();\n      });\n    }\n\n    \/\/ Panel inside map (tablet\/desktop)\n    const PanelControl = L.Control.extend({\n      options:{position:'topleft'},\n      onAdd:function(){\n        const wrap=L.DomUtil.create('div');\n        wrap.innerHTML=panelHTML();\n        const panel=wrap.firstElementChild;\n        L.DomEvent.disableClickPropagation(panel);\n        L.DomEvent.disableScrollPropagation(panel);\n        wireSearchHandlers(panel);\n        return panel;\n      }\n    });\n\n    \/\/ Panel below map (mobile)\n    function mountPanelOutside(){\n      const container=document.getElementById('search-panel-outside');\n      container.innerHTML=panelHTML();\n      wireSearchHandlers(container);\n    }\n\n    \/\/ Usar mi ubicaci\u00f3n button\n    L.control.locate=function(opts){\n      const C=L.Control.extend({\n        options:{position:'topleft'},\n        onAdd:function(){\n          const btn=L.DomUtil.create('button','leaflet-bar');\n          btn.style.background='var(--brand)';\n          btn.style.color='#fff';\n          btn.style.border='none';\n          btn.style.borderRadius='6px';\n          btn.style.padding='6px 10px';\n          btn.style.marginTop='8px';\n          btn.style.cursor='pointer';\n          btn.textContent='\ud83d\udccd Usar mi ubicaci\u00f3n';\n          L.DomEvent.disableClickPropagation(btn);\n          btn.addEventListener('click',()=>{\n            if(!navigator.geolocation) return alert('Geolocalizaci\u00f3n no soportada.');\n            navigator.geolocation.getCurrentPosition(\n              pos=>{\n                const {latitude,longitude}=pos.coords;\n                map.setView([latitude,longitude],14,{animate:true});\n                L.marker([latitude,longitude]).addTo(map).bindPopup('Est\u00e1s aqu\u00ed').openPopup();\n              },\n              ()=>alert('No se pudo obtener tu ubicaci\u00f3n.')\n            );\n          });\n          return btn;\n        }\n      });\n      return new C(opts);\n    };\n    map.addControl(L.control.locate());\n\n    \/\/ Scroll-friendly map\n    function lockMap(){ map.scrollWheelZoom.disable(); map.touchZoom.disable(); map.dragging.disable(); }\n    function unlockMap(){ map.scrollWheelZoom.enable(); map.touchZoom.enable(); map.dragging.enable(); }\n    lockMap();\n    map.on('click', unlockMap);\n    document.addEventListener('scroll', lockMap, {passive:true});\n\n    \/\/ Conditional mount\n    const mq = window.matchMedia('(max-width: 768px)');\n    function mountPanel(){\n      const outside=document.getElementById('search-panel-outside');\n      if(outside) outside.innerHTML='';\n      if(window._panelControlInstance){\n        map.removeControl(window._panelControlInstance);\n        window._panelControlInstance=null;\n      }\n      if(mq.matches){\n        mountPanelOutside(); \/\/ MOBILE (below map)\n      }else{\n        window._panelControlInstance=new PanelControl();\n        map.addControl(window._panelControlInstance); \/\/ DESKTOP\/TABLET\n      }\n    }\n    mq.addEventListener('change', mountPanel);\n    mountPanel();\n  <\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-277","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/pages\/277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/comments?post=277"}],"version-history":[{"count":8,"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/pages\/277\/revisions"}],"predecessor-version":[{"id":286,"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/pages\/277\/revisions\/286"}],"wp:attachment":[{"href":"https:\/\/wisp360.mx\/index.php\/wp-json\/wp\/v2\/media?parent=277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}