import requests from typing import Dict, Any, Optional, List class AmapAPI: """高德地图API调用类""" def __init__(self, api_key: str): """ 初始化高德地图API Args: api_key: 高德地图API密钥 """ self.api_key = api_key self.base_url = "https://restapi.amap.com" def geocode(self, address: str) -> Dict[str, Any]: """ 地理编码API - 将地址转换为经纬度坐标 Args: address: 需要转换的地址 Returns: Dict: 包含地理编码结果的字典 """ endpoint = f"{self.base_url}/v3/geocode/geo" params = { "key": self.api_key, "address": address } response = requests.get(endpoint, params=params) response.raise_for_status() # 如果请求失败则抛出异常 result = response.json() if result.get("status") != "1": raise Exception(f"高德地图API调用失败: {result.get('info')}") return result def parse_location(self, geocode_result: Dict[str, Any]) -> Optional[Dict[str, Any]]: """ 解析地理编码结果,提取位置信息 Args: geocode_result: 地理编码API返回的结果 Returns: Optional[Dict]: 提取的位置信息,如果解析失败则返回None """ if not geocode_result or "geocodes" not in geocode_result or not geocode_result["geocodes"]: return None geocode = geocode_result["geocodes"][0] # 解析经纬度 location = geocode.get("location", "") longitude, latitude = location.split(",") if "," in location else ("", "") location_info = { "formatted_address": geocode.get("formatted_address", ""), "country": geocode.get("country", ""), "province": geocode.get("province", ""), "city": geocode.get("city", ""), "district": geocode.get("district", ""), "adcode": geocode.get("adcode", ""), "longitude": longitude, "latitude": latitude, "level": geocode.get("level", "") } return location_info def search_around(self, location: str, keywords: str, radius: int = 2000, types: str = "", page: int = 1, offset: int = 20) -> Dict[str, Any]: """ 周边搜索API - 根据经纬度坐标搜索周边的POI信息 Args: location: 中心点坐标,格式为"longitude,latitude" keywords: 搜索关键词,如"加油站" radius: 搜索半径,单位:米,默认2000米 types: POI类型,可选 page: 页码,默认1 offset: 每页记录数,默认20,最大25 Returns: Dict: 包含POI搜索结果的字典 """ endpoint = f"{self.base_url}/v3/place/around" params = { "key": self.api_key, "location": location, "keywords": keywords, "radius": radius, "page": page, "offset": offset } # 如果指定了类型,添加到参数中 if types: params["types"] = types response = requests.get(endpoint, params=params) response.raise_for_status() # 如果请求失败则抛出异常 result = response.json() if result.get("status") != "1": raise Exception(f"高德地图API调用失败: {result.get('info')}") return result def parse_pois(self, search_result: Dict[str, Any]) -> List[Dict[str, Any]]: """ 解析周边搜索结果,提取POI信息列表 Args: search_result: 周边搜索API返回的结果 Returns: List[Dict]: 提取的POI信息列表,如果解析失败则返回空列表 """ if not search_result or "pois" not in search_result or not search_result["pois"]: return [] pois_list = [] for poi in search_result["pois"]: # 解析经纬度 location = poi.get("location", "") longitude, latitude = location.split(",") if "," in location else ("", "") # 提取评分信息 rating = "" if "biz_ext" in poi and "rating" in poi["biz_ext"]: rating = poi["biz_ext"]["rating"] # 提取第一张照片URL(如果有) photo_url = "" if "photos" in poi and poi["photos"] and "url" in poi["photos"][0]: photo_url = poi["photos"][0]["url"] poi_info = { "id": poi.get("id", ""), "name": poi.get("name", ""), "type": poi.get("type", ""), "typecode": poi.get("typecode", ""), "address": poi.get("address", ""), "province": poi.get("pname", ""), "city": poi.get("cityname", ""), "district": poi.get("adname", ""), "distance": poi.get("distance", ""), "longitude": longitude, "latitude": latitude, "tel": poi.get("tel", ""), "rating": rating, "photo_url": photo_url } pois_list.append(poi_info) return pois_list # 使用高德地图API搜索周边设施 def search_nearby(address: str, keywords: str, radius: int = 1000, limit: int = 10) -> str: """ 根据地址搜索周边设施 Args: address: 搜索的中心地址,如"骏丰商务中心" keywords: 搜索关键词,如"美食"、"加油站"、"酒店"等 radius: 搜索半径,单位:米,默认1000米 limit: 返回结果数量,默认10条 Returns: str: 格式化的搜索结果字符串 """ # 创建API实例 api_key = "ea26b6bf15cece38dc812d9e6c1a7c65" amap = AmapAPI(api_key=api_key) result = [] try: # 1. 地理编码获取位置坐标 result.append(f"▶ 正在获取 '{address}' 的经纬度...") geocode_result = amap.geocode(address) location_info = amap.parse_location(geocode_result) if not location_info: return "无法获取位置信息,请检查地址是否正确" result.append(f"✓ 位置信息: {location_info['formatted_address']}") result.append(f"✓ 经纬度坐标: {location_info['longitude']},{location_info['latitude']}") # 2. 使用获取到的坐标搜索周边设施 location = f"{location_info['longitude']},{location_info['latitude']}" result.append(f"\n▶ 正在搜索 '{address}' 周边{radius}米范围内的{keywords}...") search_result = amap.search_around( location=location, keywords=keywords, radius=radius, offset=limit ) pois = amap.parse_pois(search_result) if not pois: return f"未找到 '{address}' 周边的{keywords}" result.append(f"✓ 找到 {len(pois)} 个{keywords}地点:") # 3. 格式化结果列表 for i, poi in enumerate(pois, 1): poi_info = [] poi_info.append(f"\n{i}. {poi['name']}") poi_info.append(f" 类型: {poi['type']}") poi_info.append(f" 地址: {poi['address']}") poi_info.append(f" 距离: {poi['distance']}米") if poi['rating']: poi_info.append(f" 评分: {poi['rating']}") if poi['tel']: poi_info.append(f" 电话: {poi['tel']}") result.append("\n".join(poi_info)) return "\n".join(result) except Exception as e: return f"搜索过程中发生错误: {e}" if __name__ == "__main__": # 执行示例 result = search_nearby("骏丰商务中心", "加油站") print(result)