📢

🎓 同学蹭饭地图

正在加载...
// ====================== // 数据读取 // ====================== let classmatesData = window.classmates || []; // ====================== // 地图初始化 // ====================== let map = new AMap.Map( "map", { zoom:5, center:[ 105, 35 ] } ); function resizeMapAfterLayout(delay = 150) { window.setTimeout(() => { map.resize(); }, delay); } function resetMap() { map.setZoomAndCenter(5, [105, 35]); } // ====================== // 公告初始化:只初始化一次 // ====================== const announcementConfig = window.announcementConfig || { enabled: false, text: "", speed: 16, pauseOnHover: true }; const announcementBar = document.getElementById("announcementBar"); const announcementText = document.getElementById("announcementText"); const announcementClose = document.getElementById("announcementClose"); function initAnnouncement() { const text = String(announcementConfig.text || "").trim(); if (!announcementConfig.enabled || !text) { announcementBar.style.display = "none"; document.body.classList.add("announcement-hidden"); resizeMapAfterLayout(); return; } announcementText.textContent = text; announcementText.style.animationDuration = `${Math.max(6, Number(announcementConfig.speed) || 16)}s`; if (announcementConfig.pauseOnHover) { announcementBar.classList.add("pause-on-hover"); } announcementClose.addEventListener("click", () => { announcementBar.style.display = "none"; document.body.classList.add("announcement-hidden"); resizeMapAfterLayout(); }); resizeMapAfterLayout(); } initAnnouncement(); // ====================== // 总人数 // ====================== document.getElementById("count").textContent = `共 ${classmatesData.length} 位同学`; // ====================== // 城市分组 // ====================== const cityGroups = {}; classmatesData.forEach((item) => { if (!cityGroups[item.city]) { cityGroups[item.city] = []; } cityGroups[item.city].push(item); }); function getCityCenter(people) { const lng = people.reduce((sum, person) => sum + Number(person.lng), 0) / people.length; const lat = people.reduce((sum, person) => sum + Number(person.lat), 0) / people.length; return [lng, lat]; } // ====================== // 排行榜 // ====================== const ranking = document.getElementById("ranking"); const rankData = Object.keys(cityGroups) .map((city) => ({ city, num: cityGroups[city].length })) .sort((a, b) => b.num - a.num); ranking.innerHTML = `

🍚 全国蹭饭热度榜

${rankData .slice(0, 10) .map( (item, index) => ` ` ) .join("")} `; ranking.addEventListener("click", (event) => { const button = event.target.closest(".rank"); if (!button) return; const city = button.dataset.city; const people = cityGroups[city]; if (!people) return; map.setZoomAndCenter(10, getCityCenter(people)); }); // ====================== // 城市聚合点 // ====================== const cityMarkers = []; Object.keys(cityGroups).forEach((city) => { const people = cityGroups[city]; const [lng, lat] = getCityCenter(people); const size = 35 + people.length * 5; const marker = new AMap.Marker({ position: [lng, lat], content: `
${people.length}
`, offset: new AMap.Pixel(-size / 2, -size / 2) }); marker.setMap(map); cityMarkers.push(marker); marker.on("click", () => { let html = `

📍${city}

🍚 ${people.length} 位饭友


`; people.forEach((person) => { const eat = Math.max( 0, Math.min(5, Number(person.eat) || 0) ); html += `
👤 ${person.name}
🏫 ${person.school}
🍚 蹭饭指数: ${"⭐".repeat(eat)}
`; }); html += "
"; const infoWindow = new AMap.InfoWindow({ content: html, offset: new AMap.Pixel(0, -25) }); infoWindow.open(map, [lng, lat]); }); }); // 横幅和地图都完成后再适配视野,避免底图错位或空白 window.setTimeout(() => { map.resize(); if (cityMarkers.length > 0) { map.setFitView(cityMarkers, false, [40, 40, 40, 40]); } }, 350); // ====================== // 同学列表 // ====================== const list = document.getElementById("list"); function renderList(data) { list.innerHTML = ""; data.forEach((item) => { const card = document.createElement("button"); card.type = "button"; card.className = "person"; card.innerHTML = ` ${item.name} 🏫 ${item.school} 📍 ${item.city} `; card.addEventListener("click", () => { map.setZoomAndCenter(14, [item.lng, item.lat]); }); list.appendChild(card); }); } renderList(classmatesData); // ====================== // 搜索 // ====================== document .getElementById("search") .addEventListener("input", function () { const keyword = this.value.trim().toLowerCase(); if (!keyword) { renderList(classmatesData); return; } const result = classmatesData.filter((item) => { return ( String(item.name).toLowerCase().includes(keyword) || String(item.school).toLowerCase().includes(keyword) || String(item.city).toLowerCase().includes(keyword) ); }); renderList(result); }); // ====================== // 旅行路线 // ====================== const tripBtn = document.getElementById("tripBtn"); const tripInput = document.getElementById("tripInput"); const tripResult = document.getElementById("tripResult"); let tripLine = null; tripBtn.addEventListener("click", () => { const text = tripInput.value.trim(); if (!text) { alert("请输入至少两个城市,例如:上海 青岛"); return; } const cities = text .split(/[\s,,、]+/) .map((city) => city.trim()) .filter(Boolean); const route = []; let html = "

🚄 推荐路线

"; let validIndex = 0; cities.forEach((city) => { const people = cityGroups[city]; if (!people) { html += `

❌ 未找到:${city}

`; return; } validIndex += 1; html += `

第${validIndex}站:${city}

`; people.forEach((person) => { html += `

👤 ${person.name}
🏫 ${person.school}

`; }); html += "
"; route.push(getCityCenter(people)); }); tripResult.innerHTML = html; if (tripLine) { map.remove(tripLine); tripLine = null; } if (route.length < 2) { alert("至少需要两个有效城市才能生成路线"); return; } tripLine = new AMap.Polyline({ path: route, strokeColor: "#1677ff", strokeWeight: 6, strokeOpacity: 0.85, showDir: true }); tripLine.setMap(map); window.setTimeout(() => { map.resize(); map.setFitView([tripLine], false, [70, 70, 70, 70]); }, 100); }); // ====================== // 高德导航 // ====================== function gotoSchool(lng, lat) { const url = "https://uri.amap.com/navigation" + `?to=${encodeURIComponent(`${lng},${lat},学校`)}` + "&mode=car" + "&policy=1" + "&src=classmates-map" + "&coordinate=gaode" + "&callnative=1"; window.open(url, "_blank", "noopener,noreferrer"); } window.gotoSchool = gotoSchool; window.resetMap = resetMap; // ====================== // 导航 // ====================== function gotoSchool(lng, lat){ const url = "https://uri.amap.com/navigation?to=" + lng + "," + lat; window.open(url,"_blank"); } // ====================== // 高铁查询 // ====================== function trainRoute(city){ console.log("查询高铁:", city); window.open( "https://www.12306.cn/", "_blank" ); } // ====================== // 飞机查询 // ====================== function flightRoute(city){ console.log("查询飞机:", city); window.open( "https://www.ctrip.com/", "_blank" ); } // 暴露给按钮调用 window.gotoSchool = gotoSchool; window.trainRoute = trainRoute; window.flightRoute = flightRoute; window.resetMap = resetMap; // ====================== // 弹窗按钮事件 // ====================== document.addEventListener( "click", function(e){ if(e.target.classList.contains("train-btn")){ let city = e.target.dataset.city; window.open( "https://www.12306.cn/", "_blank" ); } if(e.target.classList.contains("flight-btn")){ let city = e.target.dataset.city; window.open( "https://www.ctrip.com/", "_blank" ); } if(e.target.classList.contains("nav-btn")){ let lng = e.target.dataset.lng; let lat = e.target.dataset.lat; window.open( "https://uri.amap.com/navigation?to=" + lng + "," + lat, "_blank" ); } });