创建应用获取 Key
天气查询-基础 API 文档-开发指南-Web服务 API | 高德地图API
代码编写
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气查询</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background: linear-gradient(to bottom, #87CEEB, #1E90FF);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 90%;
max-width: 500px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 10px;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #333;
}
.search-box {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.location-select {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
#search-btn {
padding: 10px 20px;
border-radius: 5px;
}
.weather-info {
display: none;
padding: 15px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
margin-top: 20px;
}
.weather-info h2 {
color: #1E90FF;
text-align: center;
margin-bottom: 15px;
}
.weather-details {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
padding: 10px;
}
.weather-item {
background-color: #f5f5f5;
border-radius: 8px;
padding: 15px;
text-align: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.weather-item h3 {
color: #333;
font-size: 14px;
margin-bottom: 8px;
}
.weather-item p {
color: #666;
font-size: 16px;
font-weight: bold;
}
.error-message {
color: red;
text-align: center;
margin-top: 10px;
display: none;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js"></script>
</head>
<body>
<div class="container">
<h1>天气查询</h1>
<div class="search-box">
<select id="province-select" class="location-select">
<option value="">请选择省份</option>
</select>
<select id="city-select" class="location-select" disabled>
<option value="">请选择城市</option>
</select>
<select id="district-select" class="location-select" disabled>
<option value="">请选择区县</option>
</select>
<button id="search-btn">查询</button>
</div>
<div id="error-message" class="error-message"></div>
<div id="weather-info" class="weather-info">
<h2 id="city-name"></h2>
<div class="weather-details">
<div class="weather-item">
<h3>天气现象</h3>
<p id="weather-desc"></p>
</div>
<div class="weather-item">
<h3>实时温度</h3>
<p id="temperature"></p>
</div>
<div class="weather-item">
<h3>空气湿度</h3>
<p id="humidity"></p>
</div>
<div class="weather-item">
<h3>风向</h3>
<p id="wind-direction"></p>
</div>
<div class="weather-item">
<h3>风力级别</h3>
<p id="wind-speed"></p>
</div>
<div class="weather-item">
<h3>数据发布时间</h3>
<p id="report-time"></p>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchBtn = document.getElementById('search-btn');
const weatherInfo = document.getElementById('weather-info');
const errorMessage = document.getElementById('error-message');
const cityName = document.getElementById('city-name');
const weatherDesc = document.getElementById('weather-desc');
const temperature = document.getElementById('temperature');
const humidity = document.getElementById('humidity');
const windSpeed = document.getElementById('wind-speed');
// 使用高德地图API,替换为您的密钥
// https://console.amap.com/dev/key/app
const API_KEY = '';
// 省份和城市数据
let provinces = [];
let citiesByProvince = {};
let districtsByCity = {};
let areaCodeMap = {};
// 加载并解析xlsx文件
async function loadCityData() {
try {
const response = await fetch('AMap_adcode_citycode.xlsx');
const arrayBuffer = await response.arrayBuffer();
const data = new Uint8Array(arrayBuffer);
const workbook = XLSX.read(data, {type: 'array'});
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = XLSX.utils.sheet_to_json(worksheet);
// 处理数据
jsonData.forEach(row => {
const name = row['中文名'] || '';
const code = String(row['adcode'] || '');
if (name && code) {
// 添加到区域编码映射
areaCodeMap[name] = code;
if (code.endsWith('0000')) {
// 处理直辖市和省份
const isDirectCity = ['北京市', '上海市', '天津市', '重庆市'].includes(name);
if (isDirectCity) {
// 直辖市作为城市处理
const province = name.substring(0, 2); // 去掉"市"字
if (!provinces.includes(province)) {
provinces.push(province);
citiesByProvince[province] = [name];
}
// 初始化直辖市的区县数组
districtsByCity[name] = [];
} else {
// 普通省份
provinces.push(name);
citiesByProvince[name] = [];
}
} else if (code.endsWith('00')) {
// 市级
const provinceCode = code.substring(0, 2) + '0000';
const province = jsonData.find(item =>
String(item['adcode']) === provinceCode
)?.['中文名'];
if (province) {
const provinceName = province.endsWith('市') ?
province.substring(0, 2) : province;
if (!citiesByProvince[provinceName]) {
citiesByProvince[provinceName] = [];
}
if (!citiesByProvince[provinceName].includes(name)) {
citiesByProvince[provinceName].push(name);
}
districtsByCity[name] = [];
}
} else {
// 区县级
const cityCode = code.substring(0, 4) + '00';
const city = jsonData.find(item =>
String(item['adcode']) === cityCode
)?.['中文名'];
// 处理直辖市的区县
const provinceCode = code.substring(0, 2) + '0000';
const province = jsonData.find(item =>
String(item['adcode']) === provinceCode
)?.['中文名'];
if (province && ['北京市', '上海市', '天津市', '重庆市'].includes(province)) {
// 直辖市的区县直接添加到市级
if (districtsByCity[province]) {
districtsByCity[province].push(name);
}
} else if (city && districtsByCity[city]) {
// 普通城市的区县
districtsByCity[city].push(name);
}
}
}
});
// 初始化下拉框
populateProvinceSelect();
console.log('城市数据加载完成');
} catch (error) {
console.error('加载城市数据失败:', error);
showError('加载城市数据失败');
}
}
// 填充省份下拉框
function populateProvinceSelect() {
const provinceSelect = document.getElementById('province-select');
const citySelect = document.getElementById('city-select');
const districtSelect = document.getElementById('district-select');
// 清空所有选择
provinceSelect.innerHTML = '<option value="">请选择省份</option>';
resetCitySelect();
resetDistrictSelect();
provinces.sort().forEach(province => {
const option = document.createElement('option');
option.value = province;
option.textContent = province;
provinceSelect.appendChild(option);
});
// 监听省份选择变化
provinceSelect.addEventListener('change', function() {
const selectedProvince = this.value;
if (selectedProvince) {
populateCitySelect(selectedProvince);
// 直辖市不需要在省级查询天气
if (!['北京', '上海', '天津', '重庆'].includes(selectedProvince)) {
fetchWeather(selectedProvince);
}
} else {
resetCitySelect();
resetDistrictSelect();
}
});
}
// 填充城市下拉框
function populateCitySelect(province) {
const citySelect = document.getElementById('city-select');
// 清空城市和区县选择
resetCitySelect();
resetDistrictSelect();
citySelect.disabled = false;
citiesByProvince[province].sort().forEach(city => {
const option = document.createElement('option');
option.value = city;
option.textContent = city;
citySelect.appendChild(option);
});
// 如果是直辖市,自动选择第一个城市
if (['北京', '上海', '天津', '重庆'].includes(province) && citiesByProvince[province].length > 0) {
citySelect.value = citiesByProvince[province][0];
const selectedCity = citySelect.value;
if (selectedCity) {
populateDistrictSelect(selectedCity);
fetchWeather(selectedCity);
}
}
// 监听城市选择变化
citySelect.addEventListener('change', function() {
const selectedCity = this.value;
if (selectedCity) {
populateDistrictSelect(selectedCity);
fetchWeather(selectedCity);
} else {
resetDistrictSelect();
}
});
}
// 添加区县选择处理
function populateDistrictSelect(city) {
const districtSelect = document.getElementById('district-select');
// 清空区县选择
resetDistrictSelect();
if (districtsByCity[city] && districtsByCity[city].length > 0) {
districtSelect.disabled = false;
districtsByCity[city].sort().forEach(district => {
const option = document.createElement('option');
option.value = district;
option.textContent = district;
districtSelect.appendChild(option);
});
}
// 监听区县选择变化
districtSelect.addEventListener('change', function() {
const selectedDistrict = this.value;
if (selectedDistrict) {
fetchWeather(selectedDistrict);
}
});
}
// 添加重置函数
function resetCitySelect() {
const citySelect = document.getElementById('city-select');
citySelect.innerHTML = '<option value="">请选择城市</option>';
citySelect.disabled = true;
}
function resetDistrictSelect() {
const districtSelect = document.getElementById('district-select');
districtSelect.innerHTML = '<option value="">请选择区县</option>';
districtSelect.disabled = true;
}
// 修改天气查询函数
function fetchWeather(area) {
weatherInfo.style.display = 'none';
errorMessage.style.display = 'none';
searchBtn.disabled = true;
searchBtn.textContent = '查询中...';
const areaCode = areaCodeMap[area];
if (!areaCode) {
showError('未找到该地区的编码');
searchBtn.disabled = false;
searchBtn.textContent = '查询';
return;
}
const weatherUrl = `https://restapi.amap.com/v3/weather/weatherInfo?city=${areaCode}&key=${API_KEY}`;
fetch(weatherUrl)
.then(response => response.json())
.then(data => {
if (data.status === '1' && data.lives && data.lives.length > 0) {
displayWeather(data, area);
} else {
showError('未找到天气信息');
}
})
.catch(error => {
showError('查询失败: ' + error.message);
console.error('Error:', error);
})
.finally(() => {
searchBtn.disabled = false;
searchBtn.textContent = '查询';
});
}
// 更新查询按钮事件监听
document.addEventListener('click', function(e) {
if (e.target && e.target.id === 'search-btn') {
const citySelect = document.getElementById('city-select');
const selectedCity = citySelect.value;
if (!selectedCity) {
showError('请选择城市');
return;
}
fetchWeather(selectedCity);
}
});
// 初始化
loadCityData();
function updateWeatherInfo() {
const weatherDetails = document.querySelector('.weather-details');
weatherDetails.innerHTML = `
<div class="weather-item">
<h3>天气现象</h3>
<p id="weather-desc"></p>
</div>
<div class="weather-item">
<h3>实时温度</h3>
<p id="temperature"></p>
</div>
<div class="weather-item">
<h3>空气湿度</h3>
<p id="humidity"></p>
</div>
<div class="weather-item">
<h3>风向</h3>
<p id="wind-direction"></p>
</div>
<div class="weather-item">
<h3>风力级别</h3>
<p id="wind-speed"></p>
</div>
<div class="weather-item">
<h3>数据发布时间</h3>
<p id="report-time"></p>
</div>
`;
}
function displayWeather(data, city) {
const weatherData = data.lives[0];
console.log('天气数据:', weatherData); // 调试用
// 更新城市名称
cityName.textContent = weatherData.city || city;
// 更新所有天气信息
document.getElementById('weather-desc').textContent = weatherData.weather || '未知';
document.getElementById('temperature').textContent = `${weatherData.temperature || '--'}°C`;
document.getElementById('humidity').textContent = `${weatherData.humidity || '--'}%`;
document.getElementById('wind-direction').textContent = weatherData.winddirection || '未知';
document.getElementById('wind-speed').textContent = `${weatherData.windpower || '--'} 级`;
// 格式化并显示发布时间
const reportTime = weatherData.reporttime || '';
const formattedTime = reportTime ? new Date(reportTime).toLocaleString('zh-CN') : '未知';
document.getElementById('report-time').textContent = formattedTime;
// 显示天气信息区域
weatherInfo.style.display = 'block';
}
function showError(message) {
errorMessage.textContent = message;
errorMessage.style.display = 'block';
weatherInfo.style.display = 'none';
}
// 更新天气信息展示区域
updateWeatherInfo();
});
</script>
</body>
</html>
效果实现
