hoàn thành chức năng phân lô trên ảnh predict
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Test Shapefile Selection</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; padding: 20px; }
|
||||
#map { height: 400px; border: 2px solid #ccc; margin: 20px 0; }
|
||||
.info-box { background: #f0f0f0; padding: 15px; margin: 10px 0; border-radius: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🧪 Test Shapefile Auto-Select Bbox</h1>
|
||||
|
||||
<div class="info-box">
|
||||
<h3>Chọn Shapefile:</h3>
|
||||
<select id="shapefileOverlay" onchange="onShapefileSelected(event)" style="width: 100%; padding: 10px; font-size: 14px;">
|
||||
<option value="">-- Chọn shapefile --</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<div class="info-box">
|
||||
<h3>Current Bbox:</h3>
|
||||
<pre id="bboxInfo">Chưa chọn shapefile</pre>
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
<h3>Console Logs:</h3>
|
||||
<pre id="console" style="max-height: 200px; overflow-y: auto; background: #000; color: #0f0; padding: 10px;"></pre>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script>
|
||||
// Global variables
|
||||
let map, drawnItems, selectedBbox = null;
|
||||
|
||||
// Custom console.log to display in page
|
||||
const originalLog = console.log;
|
||||
console.log = function(...args) {
|
||||
originalLog.apply(console, args);
|
||||
const consoleEl = document.getElementById('console');
|
||||
consoleEl.textContent += args.join(' ') + '\n';
|
||||
consoleEl.scrollTop = consoleEl.scrollHeight;
|
||||
};
|
||||
|
||||
// Initialize map
|
||||
function initMap() {
|
||||
map = L.map('map').setView([10.0, 105.8], 10);
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(map);
|
||||
|
||||
drawnItems = new L.FeatureGroup();
|
||||
map.addLayer(drawnItems);
|
||||
|
||||
console.log('✅ Map initialized');
|
||||
}
|
||||
|
||||
// Load shapefiles from API
|
||||
async function loadShapefiles() {
|
||||
try {
|
||||
console.log('📡 Fetching shapefiles from API...');
|
||||
const response = await fetch('http://localhost:8000/api/overlay/shapefiles');
|
||||
const data = await response.json();
|
||||
|
||||
const select = document.getElementById('shapefileOverlay');
|
||||
select.innerHTML = '<option value="">-- Chọn shapefile --</option>';
|
||||
|
||||
if (data.shapefiles && data.shapefiles.length > 0) {
|
||||
data.shapefiles.forEach(shp => {
|
||||
const option = document.createElement('option');
|
||||
option.value = shp.path;
|
||||
|
||||
let label = `${shp.filename} - ${shp.feature_count} features`;
|
||||
if (shp.crs) {
|
||||
const crsCode = shp.crs.split(':').pop();
|
||||
label += ` | CRS: ${crsCode}`;
|
||||
}
|
||||
if (shp.bbox && shp.bbox.length === 4) {
|
||||
const [minLon, minLat, maxLon, maxLat] = shp.bbox;
|
||||
label += ` | [${minLon.toFixed(2)}, ${minLat.toFixed(2)}, ${maxLon.toFixed(2)}, ${maxLat.toFixed(2)}]`;
|
||||
}
|
||||
|
||||
option.textContent = label;
|
||||
option.dataset.crs = shp.crs || '';
|
||||
option.dataset.bbox = JSON.stringify(shp.bbox || []);
|
||||
option.dataset.featureCount = shp.feature_count;
|
||||
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
console.log(`✅ Loaded ${data.shapefiles.length} shapefiles`);
|
||||
} else {
|
||||
console.log('⚠️ No shapefiles found');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Error loading shapefiles:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle shapefile selection
|
||||
function onShapefileSelected(event) {
|
||||
console.log('🔔 Shapefile selection changed');
|
||||
|
||||
const selectedOption = event.target.selectedOptions[0];
|
||||
|
||||
if (!selectedOption || !selectedOption.value) {
|
||||
console.log('ℹ️ No shapefile selected');
|
||||
document.getElementById('bboxInfo').textContent = 'Chưa chọn shapefile';
|
||||
return;
|
||||
}
|
||||
|
||||
const bboxData = selectedOption.dataset.bbox;
|
||||
console.log('📦 Bbox data from option:', bboxData);
|
||||
|
||||
if (!bboxData || bboxData === '[]') {
|
||||
console.log('⚠️ No bbox data in selected option');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const bbox = JSON.parse(bboxData);
|
||||
console.log('📊 Parsed bbox:', bbox);
|
||||
|
||||
if (bbox.length !== 4) {
|
||||
console.log('❌ Invalid bbox length:', bbox.length);
|
||||
return;
|
||||
}
|
||||
|
||||
const [minLon, minLat, maxLon, maxLat] = bbox;
|
||||
|
||||
// Validate bbox
|
||||
if (minLon < -180 || maxLon > 180 || minLat < -90 || maxLat > 90) {
|
||||
console.log('❌ Bbox out of valid range');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('✅ Valid bbox:', {minLon, minLat, maxLon, maxLat});
|
||||
|
||||
// Update map
|
||||
const bounds = [[minLat, minLon], [maxLat, maxLon]];
|
||||
const rectangle = L.rectangle(bounds, {
|
||||
color: '#667eea',
|
||||
weight: 3,
|
||||
fillOpacity: 0.2
|
||||
});
|
||||
|
||||
drawnItems.clearLayers();
|
||||
drawnItems.addLayer(rectangle);
|
||||
map.fitBounds(bounds, { padding: [50, 50] });
|
||||
|
||||
selectedBbox = {min_lon: minLon, min_lat: minLat, max_lon: maxLon, max_lat: maxLat};
|
||||
|
||||
console.log('🗺️ Map updated with new bbox');
|
||||
|
||||
// Update bbox info display
|
||||
document.getElementById('bboxInfo').textContent = JSON.stringify(selectedBbox, null, 2);
|
||||
|
||||
alert(`✅ Bbox updated!\n\nmin_lon: ${minLon.toFixed(4)}\nmin_lat: ${minLat.toFixed(4)}\nmax_lon: ${maxLon.toFixed(4)}\nmax_lat: ${maxLat.toFixed(4)}`);
|
||||
|
||||
} catch (e) {
|
||||
console.error('❌ Error:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on load
|
||||
window.onload = function() {
|
||||
console.log('🚀 Page loaded, initializing...');
|
||||
initMap();
|
||||
loadShapefiles();
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user