mapas_restoration.html 9.22 KB
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SISTEMA GIS - ADN ORIGINAL (Fase Éxito)</title>
    <!-- MapLibre GL JS -->
    <script src="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.css" rel="stylesheet" />
    <!-- Google Font: Inter -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    
    <style>
        body, html { height: 100%; margin: 0; font-family: 'Inter', sans-serif; overflow: hidden; }
        #map { width: 100%; height: 100%; position: absolute; top: 0; bottom: 0; }

        /* Tarjeta Translucida Flotante (ADN SIGEM) */
        .overlay-card {
            position: absolute;
            top: 20px;
            left: 20px;
            width: 280px;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            z-index: 1000;
            padding: 15px;
            border: 1px solid rgba(0,0,0,0.05);
        }

        .stats-header { border-bottom: 1px solid #eee; padding-bottom: 10px; margin-bottom: 15px; font-weight: 700; color: #1e293b; display: flex; justify-content: space-between; align-items: center; }
        .stats-item { display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 14px; }
        .stats-label { color: #64748b; font-weight: 500; }
        .stats-value { font-weight: 700; color: #0f172a; }

        .btn-action { width: 100%; padding: 10px; border: none; border-radius: 8px; background: #007bff; color: white; font-weight: 600; margin-top: 10px; cursor: pointer; transition: 0.2s; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 13px; }
        .btn-action:hover { background: #0056b3; }
        .btn-action.btn-secondary { background: #6c757d; }
        .btn-action.btn-danger { background: #dc3545; }

        .legend-box { margin-top: 15px; border-top: 1px solid #eee; padding-top: 10px; font-size: 11px; }
        .legend-item { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
        .color-dot { width: 12px; height: 12px; border-radius: 3px; }

        .muni-title { font-size: 11px; text-transform: uppercase; color: #3b82f6; font-weight: 700; letter-spacing: 0.5px; }
        
        .maplibre-popup-content { border-radius: 8px; padding: 0; box-shadow: 0 10px 25px rgba(0,0,0,0.1); }
        .popup-head { background: #007bff; color: white; padding: 5px 12px; font-weight: bold; border-radius: 8px 8px 0 0; font-size: 11px; }
        .popup-body { padding: 12px; font-size: 13px; color: #333; }
    </style>
</head>
<body>

<div id="map"></div>

<!-- Tarjeta de Control Flotante (ADN SIGEM) -->
<div class="overlay-card">
    <div class="muni-title" id="muni-display">Cargando...</div>
    <div class="stats-header">
        <span>Resumen Municipal</span>
        <button onclick="logout()" style="background:none; border:none; color:#dc3545; cursor:pointer;"><i class="fas fa-sign-out-alt"></i></button>
    </div>
    
    <div class="stats-item">
        <span class="stats-label"><i class="fas fa-map-marked-alt mr-2"></i> Lotes Totales:</span>
        <span class="stats-value" id="count-lotes">0</span>
    </div>
    <div class="stats-item">
        <span class="stats-label"><i class="fas fa-exclamation-circle mr-2"></i> En Morosidad:</span>
        <span class="stats-value text-danger" id="count-morosos" style="color:#dc3545">0</span>
    </div>

    <hr style="opacity: 0.1; margin: 15px 0;">

    <button class="btn-action" onclick="applyMorosidad()">
        <i class="fas fa-dollar-sign"></i> Mostrar Morosidad
    </button>
    <button class="btn-action btn-secondary" onclick="resetView()">
        <i class="fas fa-redo"></i> Vista Original
    </button>
    
    <div class="legend-box" id="legend" style="display:none;">
        <div class="legend-item"><div class="color-dot" style="background:#6b9070"></div> Sin Deuda (Al día) 🟢</div>
        <div class="legend-item"><div class="color-dot" style="background:#dc3545"></div> Con Morosidad 🔴</div>
    </div>

    <button class="btn-action btn-secondary" style="margin-top:20px; font-size:11px;" onclick="syncFdw()">
        <i class="fas fa-sync-alt"></i> Sincronizar FDW
    </button>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    const token = localStorage.getItem('jwt');
    const entidad = localStorage.getItem('entidad') || '505';
    const userName = localStorage.getItem('user_name') || 'Operador';
    
    if (!token) window.location.href = '/gis-geoserver/login.html';

    document.getElementById('muni-display').innerText = `MUNICIPIO ENTIDAD ${entidad}`;

    // Mapa LibRe Elite (ADN Original - Fase Exito 03 Abril)
    const map = new maplibregl.Map({
        container: 'map',
        style: {
            'version': 8,
            'sources': {
                'osm': {
                    'type': 'raster',
                    'tiles': ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
                    'tileSize': 256,
                    'attribution': '&copy; OpenStreetMap'
                },
                'lotes-png': {
                    'type': 'raster',
                    'tiles': [
                        `${window.location.origin}/geoserver/sigem/wms?service=WMS&version=1.1.1&request=GetMap&layers=sigem:vw_lotes_morosidad_${entidad}&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857&format=image/png&transparent=true`
                    ],
                    'tileSize': 256
                },
                'lotes-mvt': {
                    'type': 'vector',
                    'tiles': [`${window.location.origin}/gis-geoserver/sigem/gwc/service/tms/1.0.0/sigem:vw_lotes_morosidad_${entidad}@EPSG:900913@pbf/{z}/{x}/{y}.pbf`],
                    'minzoom': 13,
                    'maxzoom': 22
                }
            },
            'layers': [
                { 'id': 'osm-tiles', 'type': 'raster', 'source': 'osm' },
                { 'id': 'lotes-raster', 'type': 'raster', 'source': 'lotes-png', 'paint': { 'raster-opacity': 0.8 }, 'layout': { 'visibility': 'none' } },
                {
                    'id': 'lotes-vector',
                    'type': 'line',
                    'source': 'lotes-mvt',
                    'source-layer': `vw_lotes_morosidad_${entidad}`,
                    'paint': {
                        'line-color': '#000000',
                        'line-width': 0.5
                    }
                }
            ]
        },
        center: [
            parseFloat(localStorage.getItem('map_lng') || -56.446949),
            parseFloat(localStorage.getItem('map_lat') || -25.456443)
        ],
        zoom: parseInt(localStorage.getItem('map_zoom') || 14),
        antialias: true
    });

    map.on('load', () => {
        loadStats();
    });

    function applyMorosidad() {
        map.setLayoutProperty('lotes-raster', 'visibility', 'visible');
        document.getElementById('legend').style.display = 'block';
    }

    function resetView() {
        map.setLayoutProperty('lotes-raster', 'visibility', 'none');
        document.getElementById('legend').style.display = 'none';
        map.flyTo({ zoom: 14 });
    }

    async function loadStats() {
        try {
            const res = await fetch(`/gis-geoserver/api/gis/entidad/${entidad}/resumen`, {
                headers: { 'Authorization': `Bearer ${token}` }
            });
            const data = await res.json();
            document.getElementById('count-lotes').innerText = data.total_lotes.toLocaleString();
            document.getElementById('count-morosos').innerText = data.lotes_con_deuda.toLocaleString();
        } catch (err) { console.error(err); }
    }

    async function syncFdw() {
        if(!confirm("¿Desea sincronizar los datos de morosidad ahora?")) return;
        try {
            const res = await fetch(`/gis-geoserver/api/admin/fdw/update/${entidad}`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}` }
            });
            const data = await res.json();
            alert(data.success ? "✅ Éxito" : "❌ Error");
            if(data.success) location.reload();
        } catch (err) { alert("Error de red"); }
    }

    function logout() {
        localStorage.clear();
        window.location.href = 'login.html';
    }

    // Interacción de Lotes
    map.on('click', 'lotes-vector', (e) => {
        const p = e.features[0].properties;
        new maplibregl.Popup()
            .setLngLat(e.lngLat)
            .setHTML(`
                <div class="popup-head">LOTE: ${p.ccc}</div>
                <div class="popup-body">
                    <b>Ficha:</b> ${p.inm_ficha}<br>
                    <b style="color:red">Deuda:</b> Gs. ${parseFloat(p.trb_total_deuda || 0).toLocaleString()}<br>
                    <b>Último Pago:</b> ${p.ultimo_pago || 'Nunca'}
                </div>
            `).addTo(map);
    });
</script>
</body>
</html>
GitLab Appliance - Powered by TurnKey Linux