高德API代码记录
class GaodeAPI:"""高德地图API客户端"""def __init__(self, api_key: str):"""初始化高德地图API客户端Args:api_key: 高德地图API密钥"""self.api_key = api_keyself.base_url = "https://restapi.amap.com/v3"def _make_request(self, endpoint: str, params: Dict) -> Dict:"""发送API请求Args:endpoint: API端点params: 请求参数Returns:API响应数据"""params['key'] = self.api_keyurl = f"{self.base_url}/{endpoint}"try:response = requests.get(url, params=params, timeout=10)response.raise_for_status()return response.json()except requests.exceptions.RequestException as e:print(f"API请求失败: {e}")return {"status": "0", "info": str(e)}def geocode(self, address: str, city: str = None, exclude_poi: bool = True) -> Dict:"""地理编码 - 将地址转换为经纬度Args:address: 地址city: 城市(可选)exclude_poi: 是否排除兴趣点级别的地址(默认True)Returns:包含经纬度信息的字典"""params = {'address': address,'output': 'json'}if city:params['city'] = cityresult = self._make_request('geocode/geo', params)if result.get('status') == '1' and result.get('geocodes'):geocodes = result['geocodes']if exclude_poi:filtered_geocodes = [geo for geo in geocodes if geo.get('level') != '兴趣点']if not filtered_geocodes:return {'status': 'error','message': '未找到非兴趣点级别的地址,请尝试更具体的地址'}geocode_info = filtered_geocodes[0]else:geocode_info = geocodes[0]location = geocode_info['location'].split(',')return {'status': 'success','longitude': float(location[0]),'latitude': float(location[1]),'formatted_address': geocode_info.get('formatted_address', ''),'level': geocode_info.get('level', ''),'adcode': geocode_info.get('adcode', ''),'total_results': len(geocodes),'filtered_results': len(filtered_geocodes) if exclude_poi else len(geocodes)}else:return {'status': 'error','message': result.get('info', '地理编码失败')}def reverse_geocode(self, longitude: float, latitude: float) -> Dict:"""逆地理编码 - 将经纬度转换为地址Args:longitude: 经度latitude: 纬度Returns:包含地址信息的字典"""params = {'location': f"{longitude},{latitude}",'output': 'json','extensions': 'all'}result = self._make_request('geocode/regeo', params)if result.get('status') == '1' and result.get('regeocode'):regeocode_info = result['regeocode']address_component = regeocode_info.get('addressComponent', {})return {'status': 'success','formatted_address': regeocode_info.get('formatted_address', ''),'country': address_component.get('country', ''),'province': address_component.get('province', ''),'city': address_component.get('city', ''),'district': address_component.get('district', ''),'township': address_component.get('township', ''),'adcode': address_component.get('adcode', ''),'citycode': address_component.get('citycode', '')}else:return {'status': 'error','message': result.get('info', '逆地理编码失败')}def driving_route(self, origin: str, destination: str, strategy: int = 0) -> Dict:"""驾车路径规划Args:origin: 起点坐标 "经度,纬度"destination: 终点坐标 "经度,纬度"strategy: 路径策略- 0: 速度优先- 1: 费用优先- 2: 距离优先- 3: 不走高速- 4: 多策略- 5: 不走高速且避免收费- 6: 不走高速且不走收费道路- 7: 躲避拥堵- 8: 躲避拥堵且不走高速- 9: 躲避拥堵且不走收费道路- 10: 躲避拥堵且不走高速不走收费道路Returns:路径规划结果"""params = {'origin': origin,'destination': destination,'strategy': strategy,'output': 'json'}result = self._make_request('direction/driving', params)if result.get('status') == '1' and result.get('route'):route_info = result['route']paths = route_info.get('paths', [])if paths:path = paths[0] return {'status': 'success','distance': int(path.get('distance', 0)),'duration': int(path.get('duration', 0)),'strategy': path.get('strategy', ''),'tolls': int(path.get('tolls', 0)),'toll_distance': int(path.get('toll_distance', 0)),'steps': path.get('steps', [])}return {'status': 'error','message': result.get('info', '路径规划失败')}def transit_route(self, origin: str, destination: str, city: str = None, strategy: int = 0, nightflag: int = 0) -> Dict:"""公交路径规划Args:origin: 起点坐标 "经度,纬度"destination: 终点坐标 "经度,纬度"city: 城市代码或名称strategy: 路径策略- 0: 最快捷模式- 1: 最经济模式- 2: 最少换乘模式- 3: 最少步行模式- 5: 不乘地铁模式nightflag: 是否计算夜班车- 0: 不计算夜班车- 1: 计算夜班车Returns:公交路径规划结果"""params = {'origin': origin,'destination': destination,'strategy': strategy,'nightflag': nightflag,'output': 'json'}if city:params['city'] = cityresult = self._make_request('direction/transit/integrated', params)if result.get('status') == '1' and result.get('route'):route_info = result['route']transits = route_info.get('transits', [])if transits:transit = transits[0] return {'status': 'success','distance': int(transit.get('distance', 0)),'duration': int(transit.get('duration', 0)),'cost': float(transit.get('cost', 0)),'walking_distance': int(transit.get('walking_distance', 0)),'segments': transit.get('segments', []),'total_transits': len(transits)}return {'status': 'error','message': result.get('info', '公交路径规划失败')}def get_transit_details(self, transit_result: Dict) -> List[Dict]:"""获取公交路径规划的步骤"""transit_result['segments'] = transit_result.get('segments', [])steps = []if len(transit_result['segments']) == 0:return {'duration': '','steps': steps}for segment in transit_result['segments']:if segment['bus']:for busline in segment['bus']['buslines']:departure_stop = busline['departure_stop']['name']arrival_stop = busline['arrival_stop']['name']name = busline['name']steps.append({'departure_stop': departure_stop,'arrival_stop': arrival_stop,'name': name})return {'duration': transit_result['duration'],'steps': steps}def walking_route(self, origin: str, destination: str) -> Dict:"""步行路径规划Args:origin: 起点坐标 "经度,纬度"destination: 终点坐标 "经度,纬度"Returns:步行路径规划结果"""params = {'origin': origin,'destination': destination,'output': 'json'}result = self._make_request('direction/walking', params)if result.get('status') == '1' and result.get('route'):route_info = result['route']paths = route_info.get('paths', [])if paths:path = paths[0] return {'status': 'success','distance': int(path.get('distance', 0)),'duration': int(path.get('duration', 0)),'steps': path.get('steps', [])}return {'status': 'error','message': result.get('info', '步行路径规划失败')}def search_poi(self, keywords: str, city: str = None, location: str = None, radius: int = 3000, page: int = 1, offset: int = 20) -> Dict:"""POI搜索Args:keywords: 搜索关键词city: 城市代码或名称location: 中心点坐标 "经度,纬度"radius: 搜索半径(米)page: 页码offset: 每页记录数Returns:POI搜索结果"""params = {'keywords': keywords,'output': 'json','page': page,'offset': offset}if city:params['city'] = cityif location:params['location'] = locationparams['radius'] = radiusresult = self._make_request('place/text', params)if result.get('status') == '1':pois = result.get('pois', [])return {'status': 'success','count': int(result.get('count', 0)),'pois': pois}else:return {'status': 'error','message': result.get('info', 'POI搜索失败')}def batch_geocode(self, addresses: List[str], city: str = None, delay: float = 0.1, exclude_poi: bool = True) -> List[Dict]:"""批量地理编码Args:addresses: 地址列表city: 城市(可选)delay: 请求间隔(秒)exclude_poi: 是否排除兴趣点级别的地址(默认True)Returns:地理编码结果列表"""results = []for i, address in enumerate(addresses):print(f"处理第 {i+1}/{len(addresses)} 个地址: {address}")result = self.geocode(address, city, exclude_poi)results.append({'address': address,'result': result})if delay > 0 and i < len(addresses) - 1:time.sleep(delay)return resultsdef batch_reverse_geocode(self, coordinates: List[Tuple[float, float]], delay: float = 0.1) -> List[Dict]:"""批量逆地理编码Args:coordinates: 坐标列表 [(经度, 纬度), ...]delay: 请求间隔(秒)Returns:逆地理编码结果列表"""results = []for i, (lon, lat) in enumerate(coordinates):print(f"处理第 {i+1}/{len(coordinates)} 个坐标: ({lon}, {lat})")result = self.reverse_geocode(lon, lat)results.append({'coordinate': (lon, lat),'result': result})if delay > 0 and i < len(coordinates) - 1:time.sleep(delay)return resultsdef create_map_with_markers(self, coordinates: List[Tuple[float, float]], labels: List[str] = None, center: Tuple[float, float] = None) -> folium.Map:"""创建带标记的地图Args:coordinates: 坐标列表 [(经度, 纬度), ...]labels: 标记标签列表center: 地图中心点坐标Returns:Folium地图对象"""if not coordinates:return Noneif center is None:center = coordinates[0]m = folium.Map(location=[center[1], center[0]], zoom_start=12,tiles='OpenStreetMap')for i, (lon, lat) in enumerate(coordinates):label = labels[i] if labels and i < len(labels) else f"点 {i+1}"folium.Marker([lat, lon],popup=label,tooltip=label).add_to(m)return m
全流程测试
def demo_usage():"""高德地图API使用示例"""api_key = "6107bae41fa349e9bc7323e2d2700a24"if api_key == "your_gaode_api_key_here":print("请先设置您的API密钥!")returngaode = GaodeAPI(api_key)print("=== 高德地图API使用示例 ===\n")print("1. 地理编码示例")address = "北京市朝阳区三里屯"geocode_result = gaode.geocode(address)print(f"地址: {address}")print(f"结果: {geocode_result}\n")print("2. 逆地理编码示例")longitude, latitude = 116.397428, 39.90923reverse_result = gaode.reverse_geocode(longitude, latitude)print(f"坐标: ({longitude}, {latitude})")print(f"结果: {reverse_result}\n")print("3. POI搜索示例")poi_result = gaode.search_poi("餐厅", "北京", f"{longitude},{latitude}", 1000)print(f"搜索结果: {poi_result}\n")print("4. 路径规划示例")origin = f"{longitude},{latitude}"destination = "116.407428,39.91923" route_result = gaode.driving_route(origin, destination)print(f"路径规划结果: {route_result}\n")print("5. 公交路径规划示例")transit_result = gaode.transit_route(origin, destination, city="北京")print(f"公交路径规划结果: {transit_result}\n")print("6. 批量处理示例")addresses = ["北京市朝阳区三里屯", "上海市浦东新区陆家嘴"]batch_result = gaode.batch_geocode(addresses, delay=0.1)print(f"批量处理结果: {batch_result}\n")print("示例完成!")
尝试具体地点
def test_shenzhen_route():"""测试深圳路径规划"""api_key = "6666"gaode = GaodeAPI(api_key)origin_result = gaode.geocode('广东省深圳市南山区后海地铁站')destination_result = gaode.geocode('深圳市购物公园地铁站')print("地理编码结果:")print(f"起点: {origin_result}")print(f"终点: {destination_result}")if origin_result.get('status') == 'success' and destination_result.get('status') == 'success':origin_coord = f"{origin_result['longitude']},{origin_result['latitude']}"destination_coord = f"{destination_result['longitude']},{destination_result['latitude']}"print(f"\n坐标信息:")print(f"起点坐标: {origin_coord}")print(f"终点坐标: {destination_coord}")driving_result = gaode.driving_route(origin_coord, destination_coord)print(f"\n驾车路径规划结果:")print(f"状态: {driving_result.get('status')}")if driving_result.get('status') == 'success':print(f"距离: {driving_result.get('distance')} 米")print(f"时间: {driving_result.get('duration')} 秒 ({driving_result.get('duration')//60} 分钟)")print(f"策略: {driving_result.get('strategy')}")else:print(f"错误信息: {driving_result.get('message')}")transit_result = gaode.transit_route(origin_coord, destination_coord, city="深圳")print(f"\n公交路径规划结果:")print(f"状态: {transit_result.get('status')}")if transit_result.get('status') == 'success':print(f"距离: {transit_result.get('distance')} 米")print(f"时间: {transit_result.get('duration')} 秒 ({transit_result.get('duration')//60} 分钟)")print(f"费用: {transit_result.get('cost')} 元")print(f"步行距离: {transit_result.get('walking_distance')} 米")print(f"公交路径规划步骤: {gaode.get_transit_details(transit_result)}\n")else:print(f"错误信息: {transit_result.get('message')}")else:print("地理编码失败,无法进行路径规划")if __name__ == "__main__":demo_usage()print("\n" + "="*50 + "\n")test_shenzhen_route()