使用高德api实现天气查询

创建应用获取 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/xlsx@0.18.5/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>

效果实现

项目地址

https://github.com/R-K05/weather_inquiry

相关推荐
前端风云志2 分钟前
TypeScript结构化类型初探
javascript
musk121218 分钟前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
翻滚吧键盘1 小时前
js代码09
开发语言·javascript·ecmascript
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl022 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang2 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景2 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼2 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿2 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端