Spaces:
Sleeping
Sleeping
File size: 8,237 Bytes
50c0328 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
// 初始化地圖
var map = L.map('map').setView([23.5, 121], 8);
console.log('地圖初始化成功'); // 調試代碼
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
errorTileUrl: 'no-image-icon-23494.png' // 可選:設置錯誤時的替代圖像
}).addTo(map).on('tileerror', function(error) {
console.error('地圖圖層加載失敗', error); // 調試代碼
});
console.log('圖層添加成功'); // 調試代碼
// 測試地圖圖層加載
fetch('https://a.tile.openstreetmap.org/0/0/0.png')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.blob();
})
.then(blob => {
console.log('地圖圖層加載成功');
})
.catch(error => {
console.error('地圖圖層加載失敗', error);
});
// 定義顏色對應的poi_type
var poiTypeColors = {
"mrt": "red",
"school": "blue",
"landfill": "green",
"hospital": "yellow",
"collage": "purple",
"park": "orange",
"financial_industry": "cyan",
"entertainment": "magenta",
"shopping": "lime",
"temple": "brown",
"funeral_industry": "navy",
"night_market": "olive",
"hsr": "teal",
"gas_station": "pink",
"station": "coral",
"bus_station": "gold"
};
// 創建標記圖層
var markersLayer = L.layerGroup().addTo(map);
var poiMarkers = {};
var selectedMarker = null; // 用於保存所選位置的標記
// 動態生成下拉選單選項
var select = document.getElementById('poiTypeSelect');
var latInput = document.getElementById('latInput');
var lngInput = document.getElementById('lngInput');
var searchButton = document.getElementById('searchButton');
var uploadButton = document.getElementById('uploadButton');
var clearButton = document.getElementById('clearButton');
var fileInput = document.getElementById('fileInput');
var confirmationModal = $('#confirmationModal');
var confirmationMessage = document.getElementById('confirmationMessage');
var confirmButton = document.getElementById('confirmButton');
// 監聽POI類型選擇改變事件
select.addEventListener('change', function(e) {
var selectedType = e.target.value;
// 使用者選擇POI類型後,自動取得當前地圖中心點的經緯度進行查詢
var center = map.getCenter();
searchNearestPOIs(center.lat, center.lng, selectedType);
});
searchButton.addEventListener('click', function() {
var lat = parseFloat(latInput.value);
var lng = parseFloat(lngInput.value);
var poiType = select.value;
if (!isNaN(lat) && !isNaN(lng)) {
setMarker(lat, lng);
searchNearestPOIs(lat, lng, poiType);
} else {
alert('請輸入有效的經緯度');
}
});
// 上傳POI數據
uploadButton.addEventListener('click', function() {
fileInput.click();
});
fileInput.addEventListener('change', function() {
var file = fileInput.files[0];
if (file) {
confirmationMessage.textContent = '確定要上傳這個POI數據文件嗎?';
confirmButton.onclick = function() {
var formData = new FormData();
formData.append("file", file);
fetch('https://chienweichang-poi-data.hf.space/upload-poi', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
confirmationModal.modal('hide');
})
.catch(error => {
console.error('Error uploading POI data:', error);
confirmationModal.modal('hide');
alert('上傳POI數據失敗');
});
};
confirmationModal.modal('show');
}
});
// 清除POI
clearButton.addEventListener('click', function() {
confirmationMessage.textContent = '確定要清除所有POI數據嗎?';
confirmButton.onclick = function() {
fetch('https://chienweichang-poi-data.hf.space/clear-kdtrees', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
confirmationModal.modal('hide');
})
.catch(error => {
console.error('Error clearing POI:', error);
confirmationModal.modal('hide');
alert('清除POI失敗');
});
};
confirmationModal.modal('show');
});
// 查詢最近的POI
function searchNearestPOIs(lat, lng, poiType) {
// 清空現有標記
markersLayer.clearLayers();
poiMarkers = {};
// 調用後端API獲取最近的POI
fetch(`https://chienweichang-poi-data.hf.space/poi/nearest?lat=${lat}&lng=${lng}&poi_type=${poiType}`)
.then(response => response.json())
.then(data => {
if (data && data.length > 0) {
let infoHtml = generatePOITable(data);
document.getElementById('info').innerHTML = infoHtml;
// 更新地圖圖例
updateLegend(new Set(data.map(poi => poi.poi_type)));
// 為每個表格行添加點擊事件
data.forEach((poi, index) => {
document.getElementById(`poi-${index}`).addEventListener('click', () => {
var marker = poiMarkers[index];
map.setView(marker.getLatLng(), 15); // 跳轉到POI位置並放大地圖
marker.openPopup(); // 開啟POI的彈出訊息
// 取消之前選中的標記樣式
Object.values(poiMarkers).forEach(m => m.getElement().classList.remove('highlight'));
// 添加選中標記的樣式
marker.getElement().classList.add('highlight');
});
});
} else {
document.getElementById('info').innerHTML = `沒有找到附近的 POI`;
}
})
.catch(error => {
console.error('Error fetching nearest POI:', error);
document.getElementById('info').innerHTML = `錯誤:無法獲取最近的POI`;
});
}
function generatePOITable(data) {
let infoHtml = `<table class="table table-bordered">
<thead>
<tr>
<th scope="col">名稱</th>
<th scope="col">類型</th>
<th scope="col">距離 (米)</th>
</tr>
</thead>
<tbody>`;
data.forEach((poi, index) => {
var customIcon = L.divIcon({
className: 'custom-icon',
html: `<div style="background-color: ${poiTypeColors[poi.poi_type] || 'gray'}; width: 12px; height: 12px;"></div>`
});
var marker = L.marker([poi.latitude, poi.longitude], { icon: customIcon })
.bindPopup(`<b>${poi.name}</b><br>距離:${poi.distance} 米`)
.bindTooltip(`<b>${poi.name}</b><br>距離:${poi.distance} 米`, { permanent: false, direction: 'top' })
.addTo(markersLayer);
// 保存marker以便後續使用
poiMarkers[index] = marker;
infoHtml += `<tr id="poi-${index}" class="poi-row">
<td>${poi.name}</td>
<td>${poi.poi_type}</td>
<td>${poi.distance}</td>
</tr>`;
});
infoHtml += `</tbody></table>`;
return infoHtml;
}
// 點擊地圖事件
map.on('click', function(e) {
var lat = e.latlng.lat;
var lng = e.latlng.lng;
var poiType = select.value;
latInput.value = lat.toFixed(6);
lngInput.value = lng.toFixed(6);
setMarker(lat, lng);
searchNearestPOIs(lat, lng, poiType);
});
// 在地圖上設置或更新標記
function setMarker(lat, lng) {
if (selectedMarker) {
map.removeLayer(selectedMarker);
}
selectedMarker = L.marker([lat, lng], {
icon: L.icon({
iconUrl: 'https://unpkg.com/[email protected]/dist/images/marker-icon.png',
shadowUrl: 'https://unpkg.com/[email protected]/dist/images/marker-shadow.png',
iconAnchor: [12, 41], // 設置圖標的錨點為圖標底部中心
shadowAnchor: [13, 41], // 設置陰影的錨點為陰影底部中心
popupAnchor: [0, -41] // 設置彈出框的錨點為圖標頂部
})
}).addTo(map);
map.setView([lat, lng], 15); // 跳轉到所選位置並放大地圖
}
// 更新地圖圖例
function updateLegend(displayedTypes) {
var legendHtml = '<b>圖例</b><br>';
displayedTypes.forEach(type => {
legendHtml += `<i style="background:${poiTypeColors[type]}; width: 12px; height: 12px; display: inline-block; margin-right: 5px;"></i> ${type}<br>`;
});
document.getElementById('legend').innerHTML = legendHtml;
}
// 初始加載圖例
updateLegend(new Set());
|