当前位置:首页>python>Python | 调用高德地图API批量获取地址经纬度

Python | 调用高德地图API批量获取地址经纬度

  • 2026-10-13 16:50:03
Python | 调用高德地图API批量获取地址经纬度
一、数据准备
二、申请高德地图API密钥

https://console.amap.com/dev/key/app

三、Python提取各地址对应的经纬度并创建SHP
import pandas as pdimport requestsimport timeimport mathimport geopandas as gpdfrom shapely.geometry import Pointdef gcj02_to_wgs84(lng, lat):    if not (lng > 73.66 and lng < 135.05 and lat > 3.86 and lat < 53.55):        return lng, lat    a = 6378137.0    ee = 0.00669342162296594323    def transform_lat(x, y):        ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))        ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0        ret += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0        ret += (160.0 * math.sin(y / 12.0 * math.pi) + 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0        return ret    def transform_lng(x, y):        ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x))        ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0        ret += (20.0 * math.sin(x * math.pi) + 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0        ret += (150.0 * math.sin(x / 12.0 * math.pi) + 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0        return ret    dlat = transform_lat(lng - 105.0, lat - 35.0)    dlng = transform_lng(lng - 105.0, lat - 35.0)    radlat = lat / 180.0 * math.pi    magic = math.sin(radlat)    magic = 1 - ee * magic * magic    sqrtmagic = math.sqrt(magic)    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi)    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi)    mglat = lat + dlat    mglng = lng + dlng    return lng * 2 - mglng, lat * 2 - mglatdef get_amap_coordinates(address, key):    url = "https://restapi.amap.com/v3/geocode/geo"    params = {"address": address, "key": key, "output": "json"}    try:        r = requests.get(url, params=params, timeout=8)        if r.status_code == 200:            j = r.json()            if j.get("status") == "1" and int(j.get("count")) > 0:                location = j["geocodes"][0]["location"]                lng_gcj, lat_gcj = map(float, location.split(','))                return gcj02_to_wgs84(lng_gcj, lat_gcj)    except:        pass    return None, Nonedef process_excel_with_coordinates(input_file, output_file, shp_file, key):    df = pd.read_excel(input_file)    if "经度" not in df.columns: df["经度"] = None    if "纬度" not in df.columns: df["纬度"] = None    for i, row in df.iterrows():        addr = str(row.get("地址", "")).strip()        if not addr or addr == 'nan': continue        lng_wgs, lat_wgs = get_amap_coordinates(addr, key)        if lng_wgs:            df.at[i, "经度"], df.at[i, "纬度"] = lng_wgs, lat_wgs            print(f"处理成功 [{i + 1}]: {addr} -> WGS84: {lng_wgs:.6f}, {lat_wgs:.6f}")        else:            print(f"处理失败 [{i + 1}]: {addr}")        time.sleep(0.1)    df.to_excel(output_file, index=False)    valid = df.dropna(subset=["经度", "纬度"]).copy()    if not valid.empty:        valid["geometry"] = valid.apply(lambda x: Point(float(x["经度"]), float(x["纬度"])), axis=1)        gdf = gpd.GeoDataFrame(valid, geometry="geometry", crs="EPSG:4326")        for col in gdf.columns:            if gdf[col].dtype == 'object' and col != 'geometry':                gdf[col] = gdf[col].astype(str)        gdf.to_file(shp_file, encoding="utf-8")        print("\n所有操作已完成,Shapefile 已生成。")if __name__ == "__main__":    MY_KEY = "d8668f5a89842f71835d2c6cf652bb7c"    in_path = r"C:\Users\Ayu\Documents\工作簿1.xlsx"    out_path = r"C:\Users\Ayu\Documents\工作簿11.xlsx"    shp_path = r"C:\Users\Ayu\Documents\工作簿11.shp"    process_excel_with_coordinates(in_path, out_path, shp_path, MY_KEY)

最新文章

随机文章