486 lines
25 KiB
HTML
486 lines
25 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>GPS Navigator</title>
|
||
<!-- NOTA: NO usar document.documentElement.style.zoom — rompe las coordenadas del mapa.
|
||
CSS zoom en el elemento raíz hace que offsetWidth (que OL usa para su viewport) y
|
||
getBoundingClientRect (que OL usa para calcular evt.pixel) devuelvan valores en
|
||
espacios de coordenadas distintos → desfase sistemático en todo el mapa. -->
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v9.2.4/ol.css">
|
||
<link rel="stylesheet" href="css/main.css">
|
||
</head>
|
||
<body>
|
||
|
||
<div id="app">
|
||
|
||
<!-- ── HEADER ──────────────────────────────────────────────────────────── -->
|
||
<header>
|
||
<!-- Brand -->
|
||
<div class="brand">
|
||
<img src="assets/images/ar_logo_full.png" class="brand-logo" alt="AR Electronics" />
|
||
<span class="brand-name">GPS<span class="brand-sub">NAVIGATOR</span></span>
|
||
</div>
|
||
|
||
<span class="hdr-sep"></span>
|
||
|
||
<!-- GPS status: dot + port label -->
|
||
<div class="hdr-gps">
|
||
<span class="status-dot" id="dot-gps"></span>
|
||
<span id="lbl-port" class="hdr-port">NO GPS</span>
|
||
</div>
|
||
|
||
<!-- Fix badge — separado del chip GPS -->
|
||
<span id="fix-badge" class="fix-badge fix-none">NO FIX</span>
|
||
|
||
<!-- Botón PORT — ícono pequeño -->
|
||
<button class="port-btn" id="btn-connect" onclick="showConnectModal()" title="Configure GPS port">⚙</button>
|
||
|
||
<!-- Spacer: empuja los modos hacia la derecha -->
|
||
<div style="flex:1"></div>
|
||
|
||
<!-- Selector de modo — segmented control -->
|
||
<div class="mode-seg">
|
||
<button class="mode-btn" id="mode-night" onclick="setMode('night')">NIGHT</button>
|
||
<button class="mode-btn" id="mode-dusk" onclick="setMode('dusk')">DUSK</button>
|
||
<button class="mode-btn active" id="mode-day" onclick="setMode('day')">DAY</button>
|
||
<button class="mode-btn" id="mode-dayplus" onclick="setMode('dayplus')">DAY+</button>
|
||
</div>
|
||
|
||
<span class="hdr-sep"></span>
|
||
|
||
<!-- Reloj UTC -->
|
||
<div id="utc-clock" class="utc-clock">--:--:-- UTC</div>
|
||
</header>
|
||
|
||
<!-- ── MAIN AREA ────────────────────────────────────────────────────────── -->
|
||
<div id="main">
|
||
|
||
<!-- LEFT PANEL: GPS readout + Waypoints / Routes / NMEA tabs -->
|
||
<div id="left-panel">
|
||
|
||
<!-- ── Tab selector ──────────────────────────────────────────────── -->
|
||
<div class="lp-tabs">
|
||
<button class="lp-tab active" id="lptab-gps" onclick="lpTab('gps')">GPS</button>
|
||
<button class="lp-tab" id="lptab-wpt" onclick="lpTab('wpt')">📍 WPT</button>
|
||
<button class="lp-tab" id="lptab-rte" onclick="lpTab('rte')">🗺 RTE</button>
|
||
<button class="lp-tab" id="lptab-mrk" onclick="lpTab('mrk')">📍 MRK</button>
|
||
<button class="lp-tab" id="lptab-nmea" onclick="lpTab('nmea')">📡 NMEA</button>
|
||
</div>
|
||
|
||
<!-- ── Tab: GPS ───────────────────────────────────────────────────── -->
|
||
<div id="lp-gps" class="lp-content">
|
||
|
||
<div class="lp-section">
|
||
<div class="lp-title">POSITION</div>
|
||
<div class="readout-big" id="r-lat">--°--'-.--</div>
|
||
<div class="readout-big" id="r-lon">--°--'-.--</div>
|
||
</div>
|
||
|
||
<div class="lp-section">
|
||
<div class="lp-row">
|
||
<div class="lp-field"><div class="lp-lbl">SOG</div><div class="lp-val" id="r-sog">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">COG</div><div class="lp-val" id="r-cog">--</div></div>
|
||
</div>
|
||
<div class="lp-row" style="margin-top:6px">
|
||
<div class="lp-field"><div class="lp-lbl">COG MAG</div><div class="lp-val" id="r-cogm">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">MAGVAR</div><div class="lp-val" id="r-magvar">--</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="lp-section">
|
||
<div class="lp-row">
|
||
<div class="lp-field"><div class="lp-lbl">ALT</div><div class="lp-val" id="r-alt">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">FIX</div><div class="lp-val" id="r-fix">--</div></div>
|
||
</div>
|
||
<div class="lp-row" style="margin-top:6px">
|
||
<div class="lp-field"><div class="lp-lbl">HDOP</div><div class="lp-val" id="r-hdop">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">VDOP</div><div class="lp-val" id="r-vdop">--</div></div>
|
||
</div>
|
||
<div class="lp-row" style="margin-top:6px">
|
||
<div class="lp-field"><div class="lp-lbl">PDOP</div><div class="lp-val" id="r-pdop">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">SATS</div><div class="lp-val" id="r-sats">--</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Compass + Ecosonda -->
|
||
<div class="lp-section" id="sensors-section">
|
||
<div class="lp-title">SENSORS</div>
|
||
<div class="lp-row">
|
||
<div class="lp-field"><div class="lp-lbl">HDG TRUE</div><div class="lp-val" id="r-hdg-t">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">HDG MAG</div><div class="lp-val" id="r-hdg-m">--</div></div>
|
||
</div>
|
||
<div class="lp-row" style="margin-top:6px">
|
||
<div class="lp-field"><div class="lp-lbl">DEPTH</div><div class="lp-val" id="r-depth">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">TEMP</div><div class="lp-val" id="r-water-temp">--</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Active waypoint navigation (GO-TO) -->
|
||
<div class="lp-section" id="nav-section" style="display:none">
|
||
<div class="lp-title" style="color:var(--cyan)">▶ GOTO</div>
|
||
<div class="lp-field" style="margin-bottom:4px">
|
||
<div class="lp-lbl">WAYPOINT</div>
|
||
<div class="lp-val" id="nav-wpt-name" style="color:var(--cyan)">--</div>
|
||
</div>
|
||
<div class="lp-row">
|
||
<div class="lp-field"><div class="lp-lbl">BRG</div><div class="lp-val" id="nav-brg">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">DIST</div><div class="lp-val" id="nav-dist">--</div></div>
|
||
</div>
|
||
<div class="lp-row" style="margin-top:6px">
|
||
<div class="lp-field"><div class="lp-lbl">XTE</div><div class="lp-val" id="nav-xte">--</div></div>
|
||
<div class="lp-field"><div class="lp-lbl">ETA</div><div class="lp-val" id="nav-eta">--</div></div>
|
||
</div>
|
||
<button class="small-btn" onclick="stopNav()" style="margin-top:8px;width:100%">■ STOP NAV</button>
|
||
</div>
|
||
|
||
</div><!-- /lp-gps -->
|
||
|
||
<!-- ── Tab: Waypoints ─────────────────────────────────────────────── -->
|
||
<div id="lp-wpt" class="lp-content hidden">
|
||
<div class="lp-section-tools">
|
||
<button class="small-btn" onclick="addWptFromGPS()">+ FROM GPS</button>
|
||
<button class="small-btn" onclick="addWptManual()">+ MANUAL</button>
|
||
</div>
|
||
<div id="wpt-list" class="item-list"></div>
|
||
</div>
|
||
|
||
<!-- ── Tab: Routes ────────────────────────────────────────────────── -->
|
||
<div id="lp-rte" class="lp-content hidden">
|
||
<div class="lp-section-tools">
|
||
<button class="small-btn" onclick="newRoute()">+ NEW ROUTE</button>
|
||
</div>
|
||
<div id="route-list" class="item-list"></div>
|
||
</div>
|
||
|
||
<!-- ── Tab: Marcas ──────────────────────────────────────────────────── -->
|
||
<div id="lp-mrk" class="lp-content hidden">
|
||
<div id="mark-list" class="item-list"></div>
|
||
</div>
|
||
|
||
<!-- ── Tab: NMEA ──────────────────────────────────────────────────── -->
|
||
<div id="lp-nmea" class="lp-content hidden" style="padding:8px">
|
||
<div id="nmea-log" class="nmea-log"></div>
|
||
</div>
|
||
|
||
<!-- ── Map Tools — siempre visible al fondo del panel ────────────── -->
|
||
<div id="lp-maptools">
|
||
<div class="mt-label">MAP TOOLS</div>
|
||
<!-- Boat center — botón prominente, ancho completo -->
|
||
<button class="mt-btn mt-boat-center" onclick="centerOnGPS()" title="Center map on own ship">
|
||
⛵ BOAT CENTER
|
||
</button>
|
||
<div class="mt-grid" style="margin-top:4px">
|
||
<button class="mt-btn active" id="btn-north" onclick="setOrientation('N')" title="North Up">N↑</button>
|
||
<button class="mt-btn" id="btn-course" onclick="setOrientation('C')" title="Course Up">C↑</button>
|
||
<button class="mt-btn" id="btn-track" onclick="toggleTrack()" title="Toggle track">TRK</button>
|
||
<button class="mt-btn" onclick="clearTrack()" title="Clear track">✕TRK</button>
|
||
<button class="mt-btn" id="btn-draw-wpt" onclick="toggleDrawWpt()" title="Click en el mapa para añadir WPT">✚WPT</button>
|
||
<button class="mt-btn" id="btn-draw-route" onclick="toggleDrawRoute()" title="Trazar ruta en el mapa">✚RTE</button>
|
||
<button class="mt-btn" id="btn-draw-mark" onclick="openMarcaModal()" title="Colocar marca en el mapa">📍MARCA</button>
|
||
<button class="mt-btn" onclick="showChartsModal()" title="ENC charts">⛵ENC</button>
|
||
</div>
|
||
<!-- ENC detail level -->
|
||
<div class="mt-label" style="margin-top:7px">CARTAS ENC</div>
|
||
<div class="enc-level-sel">
|
||
<button class="enc-lvl active" id="enc-lvl-basic"
|
||
onclick="ChartLayer.setDetailLevel('basic')"
|
||
title="Balizas + tierra (más rápido)">BÁSICO</button>
|
||
<button class="enc-lvl" id="enc-lvl-medium"
|
||
onclick="ChartLayer.setDetailLevel('medium')"
|
||
title="+ profundidades y peligros">MEDIO</button>
|
||
<button class="enc-lvl" id="enc-lvl-advanced"
|
||
onclick="openEncLayersModal()"
|
||
title="Seleccionar capas ENC">AVANZADO</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /left-panel -->
|
||
|
||
<!-- CENTER: Map -->
|
||
<div id="map-wrap">
|
||
<div id="map"></div>
|
||
|
||
<!-- Zoom controls — overlay esquina superior derecha del mapa -->
|
||
<div id="map-zoom-ctrl">
|
||
<button class="map-zoom-btn" onclick="GPSMap.zoomIn()" title="Zoom in">+</button>
|
||
<button class="map-zoom-btn" onclick="GPSMap.zoomOut()" title="Zoom out">−</button>
|
||
</div>
|
||
|
||
<div id="map-coords">LAT -- LON --</div>
|
||
<!-- Chart name under cursor (auto-show) -->
|
||
<div id="map-chart-info"></div>
|
||
</div>
|
||
|
||
<!-- RIGHT PANEL: Satellites + Feature Info -->
|
||
<div id="right-panel">
|
||
<div class="rp-title">SATELLITES</div>
|
||
<div class="canvas-wrap">
|
||
<canvas id="sky-canvas" width="258" height="258"></canvas>
|
||
<div id="sky-labels" class="canvas-labels"></div>
|
||
</div>
|
||
<div class="rp-title" style="margin-top:10px">SIGNAL</div>
|
||
<div class="canvas-wrap">
|
||
<canvas id="snr-canvas" width="258" height="150"></canvas>
|
||
<div id="snr-labels" class="canvas-labels"></div>
|
||
</div>
|
||
<div class="rp-sat-count">
|
||
<span id="sat-used">0</span> used / <span id="sat-view">0</span> in view
|
||
</div>
|
||
|
||
<!-- Feature / AIS info — aparece al hacer click en el mapa -->
|
||
<div id="rp-feat-info" style="display:none"></div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div><!-- /app -->
|
||
|
||
<!-- ── MODALS ─────────────────────────────────────────────────────────────── -->
|
||
<div id="modal-overlay" class="modal-overlay hidden">
|
||
|
||
<!-- Connect port -->
|
||
<div id="modal-connect" class="modal">
|
||
<div class="modal-header">GPS PORT<button class="modal-close" onclick="closeModal()">×</button></div>
|
||
<div class="modal-body">
|
||
<div class="form-field">
|
||
<label class="form-lbl">Port</label>
|
||
<select class="form-sel" id="sel-port"></select>
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-lbl">Baud rate</label>
|
||
<select class="form-sel" id="sel-baud">
|
||
<option value="4800">4800</option>
|
||
<option value="9600" selected>9600</option>
|
||
<option value="38400">38400</option>
|
||
<option value="115200">115200</option>
|
||
</select>
|
||
</div>
|
||
<div class="modal-btns">
|
||
<button class="btn-primary" onclick="doConnect()">CONNECT</button>
|
||
<button class="btn-secondary" onclick="doDisconnect()">DISCONNECT</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCEL</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Add / Edit waypoint -->
|
||
<div id="modal-wpt" class="modal">
|
||
<div class="modal-header">WAYPOINT<button class="modal-close" onclick="closeModal()">×</button></div>
|
||
<div class="modal-body">
|
||
<div class="form-field">
|
||
<label class="form-lbl">Name *</label>
|
||
<input class="form-inp" id="wpt-name" type="text" placeholder="WPT 001">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-lbl">Latitude</label>
|
||
<input class="form-inp" id="wpt-lat" type="number" step="0.00001" placeholder="10.51234">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-lbl">Longitude</label>
|
||
<input class="form-inp" id="wpt-lon" type="number" step="0.00001" placeholder="-74.80700">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-lbl">Notes</label>
|
||
<input class="form-inp" id="wpt-notes" type="text" placeholder="optional">
|
||
</div>
|
||
<input type="hidden" id="wpt-id">
|
||
<div class="modal-btns">
|
||
<button class="btn-primary" onclick="saveWpt()">SAVE</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCEL</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- New / Edit route -->
|
||
<div id="modal-route" class="modal">
|
||
<div class="modal-header">ROUTE<button class="modal-close" onclick="closeModal()">×</button></div>
|
||
<div class="modal-body">
|
||
<div class="form-field">
|
||
<label class="form-lbl">Name *</label>
|
||
<input class="form-inp" id="rte-name" type="text" placeholder="Route 1">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-lbl">Waypoints (select in order)</label>
|
||
<div id="rte-wpt-selector" class="wpt-selector"></div>
|
||
</div>
|
||
<input type="hidden" id="rte-id">
|
||
<div class="modal-btns">
|
||
<button class="btn-primary" onclick="saveRoute()">SAVE</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCEL</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Chart management -->
|
||
<div id="modal-charts" class="modal hidden" style="max-width:500px">
|
||
<div class="modal-header">ENC CHARTS<button class="modal-close" onclick="closeModal()">×</button></div>
|
||
<div class="modal-body">
|
||
<div style="display:flex;gap:8px;margin-bottom:6px;align-items:center">
|
||
<label class="form-lbl" style="margin:0;white-space:nowrap">ENC File</label>
|
||
<button class="btn-primary" id="btn-upload-chart" onclick="uploadChart()" style="white-space:nowrap;flex:1">📁 OPEN .000 / .ZIP</button>
|
||
</div>
|
||
<div style="display:flex;gap:8px;margin-bottom:4px;align-items:center">
|
||
<label class="form-lbl" style="margin:0;white-space:nowrap">📂 SD / Path</label>
|
||
<input type="text" id="chart-path-inp" placeholder="E:\ENC_Charts"
|
||
style="flex:1;font-size:0.72rem;color:var(--text);background:var(--bg3);border:1px solid var(--border);border-radius:3px;padding:3px 6px;font-family:monospace">
|
||
<button class="btn-primary" id="btn-scan-chart" onclick="scanChartsPath()" style="white-space:nowrap">SCAN</button>
|
||
</div>
|
||
<div style="font-size:0.68rem;color:var(--muted);margin-bottom:10px">
|
||
IHO S-57 ENC (.000) o NOAA/CIOH ZIP. Pega la ruta de la tarjeta SD para importar todo.
|
||
</div>
|
||
<div id="chart-cell-list" style="border-top:1px solid var(--border);padding-top:8px;max-height:260px;overflow-y:auto">
|
||
<div class="empty-list">No charts installed</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── ENC Layer selector (AVANZADO) ──────────────────────────────────── -->
|
||
<div id="modal-enc-layers" class="modal hidden" style="max-width:340px">
|
||
<div class="modal-header">CAPAS ENC
|
||
<button class="modal-close" onclick="closeModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
|
||
<div class="el-section-hdr">🌊 PROFUNDIDADES</div>
|
||
<div class="enc-layer-group">
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-depare" checked>
|
||
<div><span class="el-name">Áreas de profundidad</span><span class="el-desc">DEPARE — rellenos azules por rango de calado</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-depcnt" checked>
|
||
<div><span class="el-name">Veriles / isobatas</span><span class="el-desc">DEPCNT — líneas de igual profundidad</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-soundg">
|
||
<div><span class="el-name">Sondas</span><span class="el-desc">SOUNDG — valores numéricos de profundidad</span></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="el-section-hdr">⚠️ PELIGROS Y ZONAS</div>
|
||
<div class="enc-layer-group">
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-hazards" checked>
|
||
<div><span class="el-name">Peligros</span><span class="el-desc">Naufragios, rocas sumergidas, obstrucciones</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-zones">
|
||
<div><span class="el-name">Zonas náuticas</span><span class="el-desc">Restringidas, fondeo, tráfico separado</span></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="el-section-hdr">🏝️ TIERRA Y COSTA</div>
|
||
<div class="enc-layer-group">
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-coalne" checked>
|
||
<div><span class="el-name">Línea de costa</span><span class="el-desc">COALNE — contorno de costa S-57</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-landmask" checked>
|
||
<div><span class="el-name">Relleno de tierra</span><span class="el-desc">LANDMASK — color S-52 beige en áreas de tierra</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-lndare">
|
||
<div><span class="el-name">Bordes polígono tierra</span><span class="el-desc">LNDARE — puede generar líneas diagonales</span></div>
|
||
</label>
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-buaare">
|
||
<div><span class="el-name">Zonas urbanas</span><span class="el-desc">BUAARE — límites de áreas edificadas</span></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="el-section-hdr">🗺️ MAPA BASE</div>
|
||
<div class="enc-layer-group">
|
||
<label class="enc-layer-lbl">
|
||
<input type="checkbox" id="el-osm" checked>
|
||
<div><span class="el-name">Mapa OSM</span><span class="el-desc">OpenStreetMap — mapa base satelital/calles</span></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="modal-btns" style="margin-top:14px">
|
||
<button class="btn-primary" onclick="applyEncLayers()">APLICAR</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCELAR</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Selector de tipo de MARCA ─────────────────────────────────────── -->
|
||
<div id="modal-marca" class="modal hidden" style="max-width:380px">
|
||
<div class="modal-header">COLOCAR MARCA
|
||
<button class="modal-close" onclick="closeModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p style="font-size:0.78rem;color:var(--muted);margin:0 0 8px">Selecciona el tipo de marca y haz click en el mapa:</p>
|
||
<div class="marca-grid" id="marca-type-grid">
|
||
<div class="marca-item" data-type="fishing" onclick="selectMarcaType(this)"><span class="marca-icon">🎣</span><span class="marca-label">Pesca</span></div>
|
||
<div class="marca-item" data-type="marina" onclick="selectMarcaType(this)"><span class="marca-icon">⚓</span><span class="marca-label">Marina</span></div>
|
||
<div class="marca-item" data-type="fuel" onclick="selectMarcaType(this)"><span class="marca-icon">⛽</span><span class="marca-label">Combustible</span></div>
|
||
<div class="marca-item" data-type="restaurant" onclick="selectMarcaType(this)"><span class="marca-icon">🍴</span><span class="marca-label">Restaurante</span></div>
|
||
<div class="marca-item" data-type="dive" onclick="selectMarcaType(this)"><span class="marca-icon">🤿</span><span class="marca-label">Buceo</span></div>
|
||
<div class="marca-item" data-type="anchorage" onclick="selectMarcaType(this)"><span class="marca-icon">🚢</span><span class="marca-label">Fondeo</span></div>
|
||
<div class="marca-item" data-type="beach" onclick="selectMarcaType(this)"><span class="marca-icon">🏖️</span><span class="marca-label">Playa</span></div>
|
||
<div class="marca-item" data-type="ramp" onclick="selectMarcaType(this)"><span class="marca-icon">🚤</span><span class="marca-label">Rampa</span></div>
|
||
<div class="marca-item" data-type="repair" onclick="selectMarcaType(this)"><span class="marca-icon">🔧</span><span class="marca-label">Taller</span></div>
|
||
<div class="marca-item" data-type="hospital" onclick="selectMarcaType(this)"><span class="marca-icon">🏥</span><span class="marca-label">Emergencia</span></div>
|
||
<div class="marca-item" data-type="customs" onclick="selectMarcaType(this)"><span class="marca-icon">🛂</span><span class="marca-label">Aduana</span></div>
|
||
<div class="marca-item" data-type="danger" onclick="selectMarcaType(this)"><span class="marca-icon">⚠️</span><span class="marca-label">Peligro</span></div>
|
||
<div class="marca-item" data-type="hotel" onclick="selectMarcaType(this)"><span class="marca-icon">🏨</span><span class="marca-label">Hotel</span></div>
|
||
<div class="marca-item" data-type="poi" onclick="selectMarcaType(this)"><span class="marca-icon">📍</span><span class="marca-label">Punto POI</span></div>
|
||
</div>
|
||
<div style="font-size:0.74rem;color:var(--muted);margin-top:6px" id="marca-type-hint">— Ningún tipo seleccionado —</div>
|
||
<div class="modal-btns" style="margin-top:10px">
|
||
<button class="btn-primary" id="btn-marca-ok" onclick="startMarcaDraw()" disabled>COLOCAR EN MAPA</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCELAR</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Editar MARCA ───────────────────────────────────────────────────── -->
|
||
<div id="modal-mark" class="modal hidden" style="max-width:340px">
|
||
<div class="modal-header">EDITAR MARCA
|
||
<button class="modal-close" onclick="closeModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" id="mark-id">
|
||
<input type="hidden" id="mark-type-val">
|
||
<div class="form-group">
|
||
<label class="form-label">Nombre</label>
|
||
<input type="text" id="mark-name" class="form-input">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo</label>
|
||
<div id="mark-type-display" style="font-size:1.2rem;padding:4px 0"></div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Lat</label>
|
||
<input type="number" id="mark-lat" class="form-input" step="0.000001">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Lon</label>
|
||
<input type="number" id="mark-lon" class="form-input" step="0.000001">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Notas</label>
|
||
<textarea id="mark-notes" class="form-input" rows="2"></textarea>
|
||
</div>
|
||
<div class="modal-btns">
|
||
<button class="btn-primary" onclick="saveMark()">GUARDAR</button>
|
||
<button class="btn-secondary" onclick="closeModal()">CANCELAR</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /modal-overlay -->
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/ol@v9.2.4/dist/ol.js"></script>
|
||
<script src="js/skyplot.js"></script>
|
||
<script src="js/map.js"></script>
|
||
<script src="js/chart_layer.js"></script>
|
||
<script src="js/app.js"></script>
|
||
<!-- bridge.js must load LAST — it calls bootApp() once QWebChannel is ready -->
|
||
<script src="js/bridge.js"></script>
|
||
</body>
|
||
</html>
|