过年的氛围总是让人怀揣着新的期待,尤其是当与朋友相约一场普陀山的朝拜之旅时,这份喜悦和憧憬便愈发浓烈。普陀山,这座充满神秘佛教文化的圣地,每年都会在新春之际迎来无数虔诚的信徒和游客,他们带着对新一年的美好期许,踏上这片神圣的土地。而在出发之前,为这次旅行绘制一张专属的旅游地图,标注好旅游路线以及行程中的主要点,不仅能让旅程更加有序,还能增添一份别样的仪式感。今天,我们就来学习如何使用 Python 的 folium
库,为普陀山之行打造一份独一无二的地图指南。
文章最后有完整代码,先来看效果
电脑上的效果
手机上的效果
一、前言
过年期间去普陀山朝拜,是很多人心中的传统习俗。普陀山作为中国四大佛教名山之一,不仅有着悠久的历史和深厚的文化底蕴,其秀丽的自然风光也令人陶醉。然而,对于初次前往普陀山的人来说,如何规划一条合理的旅游路线,确保不错过任何重要的景点,可能会是一个难题。这时候,一张详细的旅游地图就显得尤为重要。
二、准备工作
在开始绘制地图之前,我们需要做一些必要的准备工作。首先,要安装 folium
库,它是一个基于 Python 的交互式地图库,可以帮助我们轻松创建各种类型的地图。使用以下命令进行安装:
1. 导入必要的库
import folium
from folium.features import DivIcon
导入folium
库用于创建地图,DivIcon
类用于自定义地图标记的图标。
2. 定义坐标转换函数
def gcj02_to_wgs84(lat, lon):
return lat, lon
定义gcj02_to_wgs84
函数,用于将坐标从 GCJ - 02 坐标系转换为 WGS84 坐标系,但具体转换逻辑未实现。
3. 地点信息定义
我们将主要地点信息存储在一个列表中,每个地点用一个字典表示,包含名称、经纬度和描述等内容。以下是一个示例:
all_locations = [
{
"name": "普陀山码头",
"lat": 29.974852,
"lon": 122.381725,
"description": "普陀山码头是进入普陀山的重要门户,这里船只往来频繁,承载着无数游客开启心灵朝圣之旅的期待。"
},
{
"name": "普济禅寺",
"lat": 29.984244,
"lon": 122.389088,
"description": "普济禅寺是普陀山三大寺之一,历史悠久,建筑宏伟,每日香烟缭绕,梵音阵阵,是信众朝拜祈福的圣地。"
},
{
"name": "南海观音",
"lat": 29.974070,
"lon": 122.393710,
"description": "南海观音是普陀山的地标性建筑,观音像巍峨耸立,慈悲祥和的面容俯瞰着众生,吸引着无数游客和信众前来瞻仰朝拜。"
}
]
定义了一个包含多个地点信息的列表all_locations
,每个地点信息是一个字典,包含名称、经纬度、描述、图标和特色等内容。
4. 坐标转换
for loc in all_locations:
loc['wgs_lat'], loc['wgs_lon'] = gcj02_to_wgs84(loc['lat'], loc['lon'])
遍历all_locations
列表,调用gcj02_to_wgs84
函数将每个地点的经纬度转换为 WGS84 坐标系。
5. 创建地图对象
m = folium.Map(location=[all_locations[0]['wgs_lat'], all_locations[0]['wgs_lon']], zoom_start=13)
创建一个folium.Map
对象m
,设置地图的初始位置为all_locations
列表中第一个地点的坐标,并设置初始缩放级别为 13。
6. 添加地点标记
for loc in all_locations:
# 主标记
folium.Marker(
location=[loc['wgs_lat'], loc['wgs_lon']],
popup=folium.Popup(f"<b>{loc['name']}</b><hr>{loc['description']}", max_width=250),
icon=folium.Icon(icon=loc['icon'], prefix='fa', color='cadetblue')
).add_to(m)
# 文字标签
folium.Marker(
location=[loc['wgs_lat'], loc['wgs_lon']],
icon=DivIcon(
icon_size=(120, 40),
icon_anchor=(60, 20),
html=f'<div style="font-size:12px;font-weight:bold;color:#333">{loc["name"]}</div>'
)
).add_to(m)
遍历all_locations
列表,为每个地点添加主标记和文字标签。主标记包含地点名称和描述的弹出框,文字标签显示地点名称。
7. 行程路线定义
journey = [
{ # 阶段1:清晨活动
'path': ['百步阁宾馆', '普济禅寺', '西天景区'],
'time': '05:30 - 08:30',
'color': '#87CEEB',
'transport': '步行'
},
...
]
定义一个包含多个行程阶段的列表journey
,每个行程阶段是一个字典,包含路径、时间、颜色和交通方式等信息。
8. 绘制行程路线
def find_coord(name):
return next(([loc['wgs_lat'], loc['wgs_lon']] for loc in all_locations if loc['name'] == name), None)
for stage in journey:
coords = [find_coord(name) for name in stage['path']]
if '朱家尖码头' in stage['path'] and '普陀山码头' in stage['path']:
mid_point = [29.958, 122.376]
coords = [coords[0], coords[1], mid_point, coords[2], coords[3]]
polyline = folium.PolyLine(
locations=coords,
color=stage['color'],
weight=5,
opacity=0.7,
dash_array='5,5' if '步行' in stage['transport'] else None,
tooltip=f"{stage['time']} | {stage['transport']}"
).add_to(m)
for i in range(len(coords) - 1):
mid_point = [(coords[i][0] + coords[i + 1][0]) / 2, (coords[i][1] + coords[i + 1][1]) / 2]
folium.Marker(
location=mid_point,
icon=DivIcon(
icon_size=(150, 36),
icon_anchor=(75, 18),
html=f'<div style="font-size: 12pt; color: {stage["color"]}; text-align: center;">{stage["transport"]}</div>'
)
).add_to(m)
- 定义
find_coord
函数,用于根据地点名称查找其对应的 WGS84 坐标。 - 遍历
journey
列表,为每个行程阶段绘制路线:- 获取该阶段路径中每个地点的坐标。
- 若路径中包含 “朱家尖码头” 和 “普陀山码头”,则添加一个跨海路线中间点。
- 使用
folium.PolyLine
绘制路线,设置路线的颜色、宽度、透明度、虚线样式和提示信息。 - 在路线的每个线段中点添加标记,显示该阶段的交通方式。
9. 保存地图
m.save('map.html')
将创建好的地图保存为map.html
文件,用户可以使用浏览器打开该文件查看地图。
import folium
from folium.features import DivIcon
# 假设这是你的gcj02_to_wgs84函数定义
def gcj02_to_wgs84(lat, lon):
# 这里应该包含实际的转换逻辑,此处省略具体实现
return lat, lon
all_locations = [
{
"name": "普陀山码头",
"lat": 29.974852,
"lon": 122.381725,
"description": "普陀山码头是进入普陀山这一佛教圣地的重要门户,作为主要码头,每日迎接着来自五湖四海的游客。它不仅是交通枢纽,更是无数人开启心灵朝圣之旅的起点,承载着人们对普陀山佛教文化的向往与期待。码头上人来人往,船只穿梭,秩序井然,为每一位踏上这片土地的人提供安全、便捷的水上交通服务,让游客顺利抵达心中的圣地。",
"icon": "ship",
"特色": "交通枢纽"
},
{
"name": "百步阁宾馆",
"lat": 29.980471,
"lon": 122.390787,
"description": "百步阁宾馆坐落在普陀山这方充满佛韵的土地上,是游客们在旅途中温馨的休憩之所。宾馆环境清幽宁静,与周边的自然景观和佛教氛围完美融合。内部设施齐全,服务周到贴心,无论是独自前来修行感悟,还是与家人一同出游,都能在这里得到舒适的住宿体验,为探寻普陀山的佛教文化和自然风光养精蓄锐。",
"icon": "home",
"特色": "住宿休息"
},
{
"name": "普济寺站",
"lat": 29.984244,
"lon": 122.389087,
"description": "普济寺站作为公交车站,是游客前往普济寺的重要交通站点。它处于交通枢纽的关键位置,为前往这座历史悠久、规模宏大的佛教寺院的信众和游客提供了便利。从这里下车,便能迅速沉浸在普济寺的袅袅香烟和悠悠梵音之中,感受佛教文化的博大精深。周边人来人往,充满着浓厚的生活气息与朝圣氛围。",
"icon": "bus",
"特色": "交通枢纽"
},
{
"name": "索道口",
"lat": 30.018661,
"lon": 122.397788,
"description": "索道口是通往山顶佛教圣地的特殊通道起点,作为索道交通的关键节点,它为游客提供了便捷的上山方式。乘坐索道缓缓上升,既能俯瞰普陀山的壮丽自然风光,又能在心中默默期待着山顶慧济禅寺带来的神圣洗礼。站在索道口,能感受到游客们对山顶佛教寺院的向往与期待,是连接尘世与佛国净土的特殊纽带。",
"icon": "arrow-up",
"特色": "索道交通"
},
{
"name": "慧济禅寺",
"lat": 30.015454,
"lon": 122.393008,
"description": "慧济禅寺屹立于普陀山的山顶,是一座承载着深厚佛教文化底蕴的寺庙。它历史悠久,建筑风格古朴典雅,大雄宝殿庄严肃穆,供奉着众多佛像。每日清晨,第一缕阳光洒在寺庙的琉璃瓦上,僧人们的早课梵音在山林间回荡。这里不仅是信众们虔诚朝拜的圣地,也是游客们感受佛教智慧与宁静的心灵之所,吸引着无数人前来寻找内心的安宁与超脱。",
"icon": "university",
"特色": "佛教圣地"
},
{
"name": "大乘庵",
"lat": 29.994977,
"lon": 122.391233,
"description": "大乘庵作为著名庵堂,在普陀山的佛教文化中占据独特地位。庵内建筑古朴清幽,环境静谧祥和,处处弥漫着浓厚的佛教氛围。这里是修行者潜心修行的场所,也是信众们寄托信仰、祈求福祉的地方。庵堂内的佛事活动丰富多样,每逢重要节日,香火鼎盛,信徒们怀着虔诚之心前来,共同感受佛教文化的博大精深,体悟慈悲与智慧的真谛。",
"icon": "street-view",
"特色": "佛教文化"
},
{
"name": "法雨禅寺",
"lat": 30.000021,
"lon": 122.391935,
"description": "法雨禅寺是普陀山的主要寺庙之一,也是一处珍贵的古建筑群。其建筑风格融合了明清时期的建筑特色,飞檐斗拱,气势恢宏。寺内古木参天,香烟缭绕,大雄宝殿供奉的佛像庄严慈悲。这里不仅是佛教信仰的传承之地,更是历史文化的瑰宝,见证了岁月的变迁与佛教文化在普陀山的源远流长,吸引着众多游客和信徒前来领略其独特魅力。",
"icon": "street-view",
"特色": "古建筑"
},
{
"name": "南海观音",
"lat": 29.974070,
"lon": 122.393710,
"description": "南海观音作为普陀山的地标性建筑,其观音像巍峨耸立,慈悲祥和的面容俯瞰着众生。观音像高入云端,在阳光的照耀下熠熠生辉,吸引着无数游客和信众前来瞻仰朝拜。这里是佛教文化与艺术的完美结合,象征着慈悲与救渡,人们怀着敬畏与虔诚之心来到这里,祈求平安与福祉,感受佛教精神的力量。",
"icon": "female",
"特色": "地标"
},
{
"name": "紫竹林",
"lat": 29.977435,
"lon": 122.394244,
"description": "紫竹林是普陀山一处独特的自然景观,茂密的竹林郁郁葱葱,清幽宁静。这里不仅有迷人的自然风光,更与佛教文化紧密相连。传说中紫竹林是观音菩萨的修行之地,漫步其间,仿佛能感受到观音菩萨的慈悲与智慧。沙沙作响的竹叶声,仿佛是大自然与佛教文化的轻声对话,为游客带来一场身心愉悦的自然与文化交融之旅。",
"icon": "tree",
"特色": "竹林"
},
{
"name": "百步阁宾馆",
"lat": 29.980472,
"lon": 122.390787,
"icon": "home",
"type": "住宿",
"description": "百步阁宾馆坐落于普陀山这一佛教圣地,周边环境清幽宁静,与自然和人文景观相融。宾馆内部装修精致典雅,拥有多种房型,设施齐全,服务贴心周到,无论是家庭出游还是独自旅行,都能在此享受舒适惬意的住宿体验,为您的普陀山之行提供温馨的休憩港湾。"
},
{
"name": "普济禅寺",
"lat": 29.984244,
"lon": 122.389088,
"icon": "temple",
"type": "宗教场所",
"description": "普济禅寺作为普陀山三大寺之一,历史源远流长,是普陀山最古老且规模宏大的佛教寺院。寺内建筑遵循传统佛教规制,飞檐斗拱,庄严肃穆。大雄宝殿气势恢宏,供奉着众多佛像,每日香烟缭绕,梵音阵阵,吸引着无数信众和游客前来朝拜祈福,感受浓厚的佛教文化氛围。"
},
{
"name": "西天景区",
"lat": 29.989317,
"lon": 122.383542,
"icon": "mountain",
"type": "自然景观",
"description": "西天景区以其独特的山海风光闻名遐迩,漫步其间,山峦连绵起伏,怪石嶙峋,与葱郁的植被相互映衬。沿途有磐陀石、心字石等著名景点,不仅能欣赏到大自然的鬼斧神工,还能领略到深厚的历史文化底蕴,是一处让人流连忘返的自然与人文交融的胜地。"
},
{
"name": "普陀山码头",
"lat": 29.974852,
"lon": 122.381726,
"icon": "ship",
"type": "交通枢纽",
"description": "普陀山码头是游客进出普陀山的主要门户,也是连接普陀山与外界的重要交通枢纽。这里每日船只往来频繁,秩序井然,为游客提供了安全、便捷的水上交通服务。码头周边配套设施完善,无论是初来乍到还是即将返程,都能让您的旅途顺畅无忧。"
},
{
"name": "朱家尖码头",
"lat": 29.951088,
"lon": 122.370320,
"icon": "ship",
"type": "交通枢纽",
"description": "朱家尖码头在朱家尖的交通体系中占据关键地位,它作为重要的水上交通枢纽,承担着大量的客运和货运任务。码头设施先进,管理规范,不仅方便了本地居民的出行和物资运输,也为来自各地的游客提供了便捷的登岛通道,助力他们开启美好的朱家尖之旅。"
},
{
"name": "朱家尖普陀空港大酒店",
"lat": 29.932099,
"lon": 122.358962,
"icon": "hotel",
"type": "住宿",
"description": "朱家尖普陀空港大酒店临近普陀山机场,交通优势显著。酒店整体环境优雅舒适,拥有风格各异的客房,配备现代化的设施设备,无论是商务出行还是休闲度假,都能满足您的需求。此外,酒店还提供优质的餐饮服务和贴心的商务配套,让您的住宿体验更加完美。"
},
{
"name": "观音法界",
"lat": 29.933685,
"lon": 122.383509,
"icon": "pagoda",
"type": "宗教场所",
"description": "观音法界是一处集文化、艺术、宗教于一体的大型佛教文化主题园区。园区内建筑宏伟壮观,风格独特,融合了传统佛教建筑元素与现代设计理念。在这里,您可以深入了解观音文化的博大精深,欣赏到精美的佛教造像和艺术作品,感受浓厚的宗教氛围和心灵的洗礼。"
},
{
"name": "普陀山机场",
"lat": 29.932797,
"lon": 122.364679,
"icon": "plane",
"type": "交通枢纽",
"description": "普陀山机场作为区域重要的航空门户,航线网络不断拓展,已连接国内外众多城市。机场配备先进的设施设备,拥有高效的运营团队,从值机、安检到候机、登机,各个环节都为旅客提供便捷、舒适的服务,助力您轻松开启和结束每一段旅程。"
},
{
"name": "福州机场",
"lat": 25.931111,
"lon": 119.663333,
"icon": "plane",
"type": "交通枢纽",
"description": "福州机场是福建省重要的空中交通枢纽,地理位置优越,承担着大量的国内外航班起降任务。机场内布局合理,设施齐全,涵盖丰富的商业区域、舒适的候机环境以及便捷的换乘设施,为旅客提供全方位、高品质的出行服务,是连接福州与世界的空中桥梁。"
}
]
# 转换所有坐标到WGS84
for loc in all_locations:
loc['wgs_lat'], loc['wgs_lon'] = gcj02_to_wgs84(loc['lat'], loc['lon'])
# 创建地图对象
m = folium.Map(location=[all_locations[0]['wgs_lat'], all_locations[0]['wgs_lon']], zoom_start=13)
# 添加地点标记(优化标注位置)
for loc in all_locations:
# 主标记
folium.Marker(
location=[loc['wgs_lat'], loc['wgs_lon']],
popup=folium.Popup(f"<b>{loc['name']}</b><hr>{loc['description']}", max_width=250),
icon=folium.Icon(icon=loc['icon'], prefix='fa', color='cadetblue')
).add_to(m)
# 文字标签
folium.Marker(
location=[loc['wgs_lat'], loc['wgs_lon']],
icon=DivIcon(
icon_size=(120, 40),
icon_anchor=(60, 20),
html=f'<div style="font-size:12px;font-weight:bold;color:#333">{loc["name"]}</div>'
)
).add_to(m)
# 行程路线定义(优化路径顺序)
journey = [
{ # 阶段1:清晨活动
'path': ['百步阁宾馆', '普济禅寺', '西天景区'],
'time': '05:30 - 08:30',
'color': '#87CEEB',
'transport': '步行'
},
{ # 阶段2:离岛转移
'path': ['西天景区', '百步阁宾馆', '普陀山码头', '朱家尖码头'],
'time': '08:30 - 10:00',
'color': '#98FB98',
'transport': '轮渡'
},
{ # 阶段3:朱家尖行程
'path': ['朱家尖码头', '朱家尖普陀空港大酒店', '观音法界'],
'time': '10:00 - 17:00',
'color': '#FFA500',
'transport': '巴士/步行'
},
{ # 阶段4:返程
'path': ['观音法界', '朱家尖普陀空港大酒店', '普陀山机场'],
'time': '17:00 - 22:40',
'color': '#FF6347',
'transport': '出租车'
}
]
# 绘制行程路线(带自动路径查找)
def find_coord(name):
return next(([loc['wgs_lat'], loc['wgs_lon']] for loc in all_locations if loc['name'] == name), None)
for stage in journey:
coords = [find_coord(name) for name in stage['path']]
# 添加路径插值点(优化跨海路线)
if '朱家尖码头' in stage['path'] and '普陀山码头' in stage['path']:
mid_point = [29.958, 122.376] # 跨海路线中间点
coords = [coords[0], coords[1], mid_point, coords[2], coords[3]]
polyline = folium.PolyLine(
locations=coords,
color=stage['color'],
weight=5,
opacity=0.7,
dash_array='5,5' if '步行' in stage['transport'] else None,
tooltip=f"{stage['time']} | {stage['transport']}"
).add_to(m)
# 在路线上添加移动方式和预计时间
for i in range(len(coords) - 1):
mid_point = [(coords[i][0] + coords[i + 1][0]) / 2, (coords[i][1] + coords[i + 1][1]) / 2]
folium.Marker(
location=mid_point,
icon=DivIcon(
icon_size=(150, 36),
icon_anchor=(75, 18),
html=f'<div style="font-size: 12pt; color: {stage["color"]}; text-align: center;">{stage["transport"]}</div>'
)
).add_to(m)
# 显示地图
m.save('map.html')