2026-03-17 13:17:02 +08:00

244 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)