Spaces:
Running
Running
<html lang="es"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Foto a KML con UTM WGS84 Zona 18S</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.8.0/proj4.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
#videoElement { | |
transform: scaleX(-1); | |
} | |
#canvasElement { | |
transform: scaleX(-1); | |
display: none; | |
} | |
#canvasWithOverlay { | |
display: none; | |
} | |
.hidden { | |
display: none; | |
} | |
.kml-download { | |
animation: pulse 2s infinite; | |
} | |
.photo-overlay { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
background: rgba(0, 0, 0, 0.7); | |
color: white; | |
padding: 10px; | |
font-family: Arial, sans-serif; | |
} | |
.photo-title { | |
font-size: 18px; | |
font-weight: bold; | |
margin-bottom: 5px; | |
text-align: center; | |
} | |
.photo-coords { | |
font-size: 14px; | |
text-align: center; | |
} | |
@keyframes pulse { | |
0% { transform: scale(1); } | |
50% { transform: scale(1.05); } | |
100% { transform: scale(1); } | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 min-h-screen"> | |
<div class="container mx-auto px-4 py-8"> | |
<div class="max-w-2xl mx-auto bg-white rounded-xl shadow-md overflow-hidden"> | |
<div class="p-8"> | |
<h1 class="text-3xl font-bold text-center text-blue-600 mb-6"> | |
<i class="fas fa-camera-retro mr-2"></i> Foto a KML con UTM WGS84 Zona 18S | |
</h1> | |
<div class="mb-6 bg-blue-50 p-4 rounded-lg"> | |
<h2 class="text-xl font-semibold text-blue-800 mb-2"> | |
<i class="fas fa-info-circle mr-2"></i>Instrucciones: | |
</h2> | |
<ol class="list-decimal pl-5 space-y-2 text-gray-700"> | |
<li>Permite el acceso a la c谩mara cuando se te solicite.</li> | |
<li>Enfoca lo que quieras capturar en la vista previa.</li> | |
<li>Haz clic en "Tomar Foto" para capturar la imagen.</li> | |
<li>La aplicaci贸n obtendr谩 autom谩ticamente tu ubicaci贸n.</li> | |
<li>Haz clic en "Generar KML" para descargar el archivo con la foto y coordenadas UTM WGS84 Zona 18S.</li> | |
</ol> | |
</div> | |
<!-- Vista de c谩mara --> | |
<div id="cameraView" class="mb-6"> | |
<div class="relative bg-black rounded-lg overflow-hidden"> | |
<video id="videoElement" autoplay playsinline class="w-full h-auto"></video> | |
<canvas id="canvasElement"></canvas> | |
<canvas id="canvasWithOverlay"></canvas> | |
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-4"> | |
<button id="captureBtn" class="w-16 h-16 mx-auto bg-white rounded-full flex items-center justify-center shadow-lg hover:bg-gray-100 transition"> | |
<i class="fas fa-camera text-2xl text-gray-800"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Vista de foto capturada --> | |
<div id="photoView" class="hidden mb-6"> | |
<div class="relative bg-gray-200 rounded-lg overflow-hidden"> | |
<img id="photoResult" src="" alt="Foto capturada" class="w-full h-auto"> | |
<div id="photoOverlay" class="photo-overlay"> | |
<div class="photo-title">Obra Q72 Ampliaci贸n Ruta S-839</div> | |
<div id="utmCoords" class="photo-coords"></div> | |
</div> | |
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-4 flex justify-between items-center"> | |
<button id="retakeBtn" class="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition"> | |
<i class="fas fa-redo mr-2"></i>Volver a tomar | |
</button> | |
<div class="text-white"> | |
<i class="fas fa-map-marker-alt mr-2"></i> | |
<span id="locationInfo">Obteniendo ubicaci贸n...</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Controles --> | |
<div class="flex flex-col space-y-4"> | |
<button id="generateKmlBtn" class="hidden kml-download px-6 py-3 bg-green-600 text-white rounded-lg font-semibold hover:bg-green-700 transition flex items-center justify-center"> | |
<i class="fas fa-file-download mr-2"></i> Generar y Descargar KML | |
</button> | |
<div id="errorMsg" class="hidden bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"> | |
<i class="fas fa-exclamation-triangle mr-2"></i> | |
<span id="errorText"></span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Definir proyecciones UTM Zona 18 Sur (EPSG:32718) | |
proj4.defs("EPSG:4326", "+proj=longlat +datum=WGS84 +no_defs"); | |
proj4.defs("EPSG:32718", "+proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs"); | |
// Elementos del DOM | |
const videoElement = document.getElementById('videoElement'); | |
const canvasElement = document.getElementById('canvasElement'); | |
const canvasWithOverlay = document.getElementById('canvasWithOverlay'); | |
const photoResult = document.getElementById('photoResult'); | |
const captureBtn = document.getElementById('captureBtn'); | |
const retakeBtn = document.getElementById('retakeBtn'); | |
const generateKmlBtn = document.getElementById('generateKmlBtn'); | |
const cameraView = document.getElementById('cameraView'); | |
const photoView = document.getElementById('photoView'); | |
const locationInfo = document.getElementById('locationInfo'); | |
const errorMsg = document.getElementById('errorMsg'); | |
const errorText = document.getElementById('errorText'); | |
const photoOverlay = document.getElementById('photoOverlay'); | |
const utmCoords = document.getElementById('utmCoords'); | |
// Variables de estado | |
let photoDataUrl = ''; | |
let photoWithOverlayDataUrl = ''; | |
let currentLocation = null; | |
let photoDateTime = ''; | |
// Iniciar c谩mara | |
async function startCamera() { | |
try { | |
const stream = await navigator.mediaDevices.getUserMedia({ | |
video: { facingMode: 'environment' }, | |
audio: false | |
}); | |
videoElement.srcObject = stream; | |
} catch (err) { | |
showError('No se pudo acceder a la c谩mara. Aseg煤rate de haber dado los permisos necesarios.'); | |
console.error('Error al acceder a la c谩mara:', err); | |
} | |
} | |
// Funci贸n para convertir grados decimales a UTM Zona 18 Sur (EPSG:32718) | |
function toUTM(lat, lng) { | |
try { | |
// Convertir de WGS84 (EPSG:4326) a UTM Zona 18 Sur (EPSG:32718) | |
const utmCoords = proj4("EPSG:4326", "EPSG:32718", [lng, lat]); | |
return { | |
zone: 18, | |
hemisphere: 'S', | |
easting: utmCoords[0].toFixed(2), | |
northing: utmCoords[1].toFixed(2) | |
}; | |
} catch (error) { | |
console.error('Error en conversi贸n UTM:', error); | |
return { | |
zone: 18, | |
hemisphere: 'S', | |
easting: 'N/A', | |
northing: 'N/A' | |
}; | |
} | |
} | |
// Capturar foto y agregar overlay | |
function capturePhoto() { | |
const context = canvasElement.getContext('2d'); | |
canvasElement.width = videoElement.videoWidth; | |
canvasElement.height = videoElement.videoHeight; | |
context.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height); | |
photoDataUrl = canvasElement.toDataURL('image/jpeg'); | |
photoResult.src = photoDataUrl; | |
// Obtener fecha y hora actual | |
const now = new Date(); | |
photoDateTime = now.toISOString(); | |
// Cambiar vistas | |
cameraView.classList.add('hidden'); | |
photoView.classList.remove('hidden'); | |
// Obtener ubicaci贸n | |
getLocation(); | |
} | |
// Crear imagen con overlay de coordenadas | |
function createImageWithOverlay() { | |
return new Promise((resolve) => { | |
const img = new Image(); | |
img.onload = function() { | |
// Configurar canvas con overlay | |
canvasWithOverlay.width = img.width; | |
canvasWithOverlay.height = img.height; | |
const ctx = canvasWithOverlay.getContext('2d'); | |
// Dibujar la imagen original | |
ctx.drawImage(img, 0, 0); | |
// Configurar estilo para el texto | |
ctx.font = 'bold 24px Arial'; | |
ctx.fillStyle = 'white'; | |
ctx.textAlign = 'center'; | |
ctx.textBaseline = 'bottom'; | |
// Dibujar fondo semitransparente para el texto | |
const text = "Obra Q72 Ampliaci贸n Ruta S-839"; | |
const textWidth = ctx.measureText(text).width; | |
const padding = 20; | |
const rectHeight = 80; | |
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; | |
ctx.fillRect( | |
(canvasWithOverlay.width - textWidth - padding * 2) / 2, | |
canvasWithOverlay.height - rectHeight - 10, | |
textWidth + padding * 2, | |
rectHeight | |
); | |
// Dibujar t铆tulo | |
ctx.fillStyle = 'white'; | |
ctx.font = 'bold 24px Arial'; | |
ctx.fillText( | |
"Obra Q72 Ampliaci贸n Ruta S-839", | |
canvasWithOverlay.width / 2, | |
canvasWithOverlay.height - 50 | |
); | |
// Dibujar coordenadas UTM Zona 18S | |
if (currentLocation) { | |
const utm = toUTM(currentLocation.lat, currentLocation.lng); | |
const coordsText = `UTM WGS84 Zona ${utm.zone}${utm.hemisphere} Este: ${utm.easting} Norte: ${utm.northing}`; | |
ctx.font = '18px Arial'; | |
ctx.fillText( | |
coordsText, | |
canvasWithOverlay.width / 2, | |
canvasWithOverlay.height - 20 | |
); | |
} | |
// Obtener la imagen con overlay como Data URL | |
photoWithOverlayDataUrl = canvasWithOverlay.toDataURL('image/jpeg'); | |
resolve(photoWithOverlayDataUrl); | |
}; | |
img.src = photoDataUrl; | |
}); | |
} | |
// Obtener ubicaci贸n | |
function getLocation() { | |
if (navigator.geolocation) { | |
locationInfo.textContent = 'Obteniendo ubicaci贸n...'; | |
navigator.geolocation.getCurrentPosition( | |
async (position) => { | |
currentLocation = { | |
lat: position.coords.latitude, | |
lng: position.coords.longitude, | |
alt: position.coords.altitude || 0 | |
}; | |
// Convertir a UTM Zona 18S usando proj4js | |
const utm = toUTM(currentLocation.lat, currentLocation.lng); | |
// Mostrar en el overlay | |
locationInfo.textContent = `UTM WGS84 Zona ${utm.zone}${utm.hemisphere}`; | |
utmCoords.textContent = `Este: ${utm.easting} Norte: ${utm.northing}`; | |
// Crear imagen con overlay | |
await createImageWithOverlay(); | |
// Mostrar bot贸n de generar KML | |
generateKmlBtn.classList.remove('hidden'); | |
}, | |
(error) => { | |
let errorMessage = 'No se pudo obtener la ubicaci贸n.'; | |
switch(error.code) { | |
case error.PERMISSION_DENIED: | |
errorMessage = 'Permiso de ubicaci贸n denegado.'; | |
break; | |
case error.POSITION_UNAVAILABLE: | |
errorMessage = 'Informaci贸n de ubicaci贸n no disponible.'; | |
break; | |
case error.TIMEOUT: | |
errorMessage = 'Tiempo de espera para obtener ubicaci贸n agotado.'; | |
break; | |
} | |
locationInfo.textContent = errorMessage; | |
showError(errorMessage); | |
}, | |
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 } | |
); | |
} else { | |
showError('Geolocalizaci贸n no es soportada por tu navegador.'); | |
} | |
} | |
// Volver a tomar foto | |
function retakePhoto() { | |
cameraView.classList.remove('hidden'); | |
photoView.classList.add('hidden'); | |
generateKmlBtn.classList.add('hidden'); | |
currentLocation = null; | |
photoDataUrl = ''; | |
photoWithOverlayDataUrl = ''; | |
startCamera(); | |
} | |
// Generar y descargar KML con UTM WGS84 Zona 18S | |
async function generateKml() { | |
if (!currentLocation || !photoDataUrl) { | |
showError('No hay foto o ubicaci贸n disponible.'); | |
return; | |
} | |
// Asegurarse de que tenemos la imagen con overlay | |
if (!photoWithOverlayDataUrl) { | |
await createImageWithOverlay(); | |
} | |
// Convertir a UTM Zona 18S usando proj4js | |
const utm = toUTM(currentLocation.lat, currentLocation.lng); | |
// Crear contenido KML | |
const kmlContent = `<?xml version="1.0" encoding="UTF-8"?> | |
<kml xmlns="http://www.opengis.net/kml/2.2"> | |
<Document> | |
<name>Obra Q72 Ampliaci贸n Ruta S-839</name> | |
<description><![CDATA[ | |
<h1>OBRA Q72 AMPLIACI脫N RUTA S-839</h1> | |
<img src="${photoWithOverlayDataUrl}" width="800" style="display: block; margin: 0 auto;"/> | |
<h2>Informaci贸n de la obra</h2> | |
<p><strong>Fecha:</strong> ${new Date(photoDateTime).toLocaleString()}</p> | |
<p><strong>Coordenadas UTM WGS84 Zona 18S</strong></p> | |
<p><strong>Este:</strong> ${utm.easting}</p> | |
<p><strong>Norte:</strong> ${utm.northing}</p> | |
<p><strong>Altitud:</strong> ${currentLocation.alt.toFixed(2)} metros</p> | |
<p><strong>Coordenadas originales WGS84:</strong> ${currentLocation.lat.toFixed(6)}, ${currentLocation.lng.toFixed(6)}</p> | |
]]></description> | |
<Placemark> | |
<name>Ubicaci贸n exacta UTM WGS84 Zona 18S</name> | |
<description><![CDATA[ | |
<p><strong>Este:</strong> ${utm.easting}</p> | |
<p><strong>Norte:</strong> ${utm.northing}</p> | |
<p><strong>Zona:</strong> ${utm.zone}${utm.hemisphere}</p> | |
]]></description> | |
<Point> | |
<coordinates>${currentLocation.lng},${currentLocation.lat},${currentLocation.alt}</coordinates> | |
</Point> | |
<Style> | |
<IconStyle> | |
<Icon> | |
<href>https://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href> | |
</Icon> | |
<color>ff0000ff</color> | |
<scale>1.2</scale> | |
</IconStyle> | |
</Style> | |
</Placemark> | |
</Document> | |
</kml>`; | |
// Crear y descargar archivo | |
const blob = new Blob([kmlContent], { type: 'application/vnd.google-earth.kml+xml' }); | |
const url = URL.createObjectURL(blob); | |
const a = document.createElement('a'); | |
a.href = url; | |
a.download = `Obra_Q72_UTM18S_${new Date(photoDateTime).toISOString().replace(/[:.]/g, '-')}.kml`; | |
document.body.appendChild(a); | |
a.click(); | |
document.body.removeChild(a); | |
URL.revokeObjectURL(url); | |
} | |
// Mostrar error | |
function showError(message) { | |
errorText.textContent = message; | |
errorMsg.classList.remove('hidden'); | |
setTimeout(() => errorMsg.classList.add('hidden'), 5000); | |
} | |
// Event listeners | |
captureBtn.addEventListener('click', capturePhoto); | |
retakeBtn.addEventListener('click', retakePhoto); | |
generateKmlBtn.addEventListener('click', generateKml); | |
// Iniciar la aplicaci贸n | |
startCamera(); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 馃К <a href="https://enzostvs-deepsite.hf.space?remix=ignaciomdr/fotokmz" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |