ทำแผนที่ง่ายๆด้วย Folium — Flask
Make beautiful, interactive maps with Python and Leaflet.js
Folium
Make beautiful, interactive maps with Python and Leaflet.js
Folium จะทำให้การนำข้อมูลที่ถูกคำนวณใน python ไปแสดงบนแผนที่เป็นเรี่องกล้วยๆ เพราะ folium จะแปลงข้อมูลของเราจาก python ไปสร้างขึ้นมาเป็นแผนที่บน leaflet maps ในภาษา javascript แทนนั้นเอง
ติดตั้ง
$ pip install folium
การใช้งานร่วมกับ Flask
โดยนำโค้ดด้านล่างไปใส่ในเว็บ Flask ได้เลย
<สำหรับบล็อกเกี่ยวกับ flask จิ้มลิ้งด้านล่างได้เลย>
import folium
@app.route('/map')
def map():
start_coords = (7.1898, 100.5954) # ละติจูด,ลองจิจูด ของ สงขลา
folium_map = folium.Map(location=start_coords,
zoom_start=14)
return folium_map._repr_html_() # แสดงออกมาเป็น html
start_coords คือ จุดกึ่งกลางแผนที่เริ่มต้น
zoom_start คือ ระยะซูมของหน้าจอ
เมื่อเปิดหน้า /map ก็จะได้ประมาณนี้
และเราสามารถเปลี่ยนรูปแบบของแผนที่ได้โดยการเติม tiles เข้าไปโดยปกติแล้วถ้าไม่ใส่จะมีค่าเป็น OpenStreetMap
folium_map = folium.Map(location=start_coords,
zoom_start=14,
tiles='Stamen Terrain')
Stamen Terrain
Stamen Toner
เลือกที่ชอบที่ชอบนะครับ
Markers
เพิ่มจุดมาร์คบนแผนที่
แผนที่นั้นทำงานเป็น layers ซึ่งตัวแผนที่คือ base_layer ที่อยู่ชั้นล่างสุดดังนั้นจุดมาร์คก็ควรจะอยู่ข้างบนเพื่อให้ไม่โดนทับนั้นเอง เปรียบได้ว่าแผนที่คือ parent จุดมาร์คก็คือ child นั้นเอง
เพิ่มโค้ด (ใส่ในฟังก์ชั่น map ก่อน return นะครับ)
folium_map.add_child(folium.Marker(location=[7.1898,100.5954],
popup='hello'))
popup แสดงข้อความนั้นเมื่อกด marker ซึ่งสามารถใส่เป็น html ได้ด้วย แบบนี้
folium_map.add_child(folium.Marker(location=[7.1898, 100.5954],
popup='<b>I love Songkhla</b>',
tooltip='Songkhla'))
ส่วน tooltip จะแสดงข้อความนั้นเมื่อเมาส์วางอยู่บน marker
มาลองใส่ข้อความยาวๆกัน
Songkhla_detail = '''Songkhla, also known as Singgora or Singora, is a city in Songkhla Province of southern Thailand,near the border with Malaysia. As of 2006 it had a population of 75,048. Songkhla lies 968 km south of Bangkok'''folium_map.add_child(folium.Marker(location=[7.1898, 100.5954],
popup=Songkhla_detail,
tooltip='<b>Songkhla</b>'))
ก็จะได้ข้อความยาว ๆ เลย (ยาวจริง)
แต่ยังมันอ่านยากไปนะ เราสามารถแก้ขนาดได้โดยเอา folium.popup() มาช่วย แบบนี้
folium_map.add_child(folium.Marker(location=[7.1898, 100.5954],
popup=folium.Popup(Songkhla_detail,
max_width=400,min_width=300),
tooltip='<b>Songkhla</b>'))
ถาม:
แล้วถ้ามีจุดมาร์คหลาย ๆ จุดแล้วทำแบบข้างบน layer มันก็ซ้อนกันเรื่อยๆใช่ไหม
ตอบ:
ใช่ครับถ้า add_child() เพิ่มก็เหมือนกับเป็นการเพิ่ม layer ซึ่งมันไม่ควรเท่าไรเพราะจุดมาร์คมันคือชนิดเดียวกันอยู่ใน layer เดียวกันก็ได้จริงไหม
เราสามารถร่วบมันมาเป็นกลุ่ม layer เดียวกันได้ด้วย FeatureGroup() เช่น
Markers = folium.FeatureGroup(name="Markers") # สร้างกลุ่มสำหรับจุดมาร์ค
Markers.add_child( folium.Marker(1) ) # เพิ่มจุดมาร์ค1 ลงไปในกลุ่มMarkers
Markers.add_child( folium.Marker(2) ) # เพิ่มจุดมาร์ค2 ลงไปในกลุ่มMarkers
.
.
.
folium_map.add_child(Markers)return folium_map._repr_html_() # แสดงออกมาเป็น html
(ควรจะวนลูบนะ)
มาดูตัวอย่างด้วยข้อมูลยาว ๆ กันดีกว่า
Songkhla_detail = '''Songkhla, also known as Singgora or Singora, is a city in Songkhla Province of southern Thailand,near the border with Malaysia. As of 2006 it had a population of 75,048. Songkhla lies 968 km south of Bangkok'''Hatyai_detail = '''Hat Yai, a city in Thailand's far south near the Malaysian border, is a sprawling commercial hub and shopping destination.At the Khlong Hae Floating Market, vendors sell local foods and handicrafts from traditional boats docked in a canal.The Wat Hat Yai Nai temple is known for its 35m-long reclining Buddha. Outside the city center,Hat Yai Park is a hilly green area with a standing Buddha statue and a cable car.'''Satun_detail = '''Satun is one of the southern provinces of Thailand.Neighboring provinces are Trang, Phatthalung, and Songkhla. To the south it borders Perlis of Malaysia'''Provinces = [dict(
name="Songkhla",
coords=[7.1898,100.5954],
detail=Songkhla_detail),
dict(
name="Hatyai",
coords=[7.008661,100.474687],
detail=Hatyai_detail),
dict(
name="Satun",
coords=[6.623918, 100.067206],
detail=Satun_detail) ]@app.route(’/map’)
def map():
start_coords = (7.1898, 100.5954) # ละติจูด,ลองจิจูด ของสงขลา
folium_map = folium.Map(location=start_coords,
zoom_start=14)
Markers = folium.FeatureGroup(name="Markers")
for p in Provinces:
Markers.add_child(folium.Marker(location=p[’coords’],
popup=folium.Popup(p[’detail’],
max_width=400,min_width=300),
tooltip=f"<b> {p[’name’]} </b>"))folium_map.add_child(Markers)return folium_map._repr_html_() # แสดงออกมาเป็น html
ปล. โค้ดข้างบนเป็นเพียงส่วนกำหนดข้อมูล และฟังก์ชั่น map เท่านั้น
ลองรันเว็บก็จะได้ประมาณนี้
เมื่อวางเมาส์บนจุดมาร์คจะแสดง ชื่อจังหวัด (name)
เมื่อกดจะแสดง ข้อมูลจังหวัดนั้นๆ (detail)
Folium ยังทำอะไรได้อีกมากเลย เช่น สร้างเป็นตารางกราฟ หรือ แบ่งพื้นที่แต่งละเขตแล้วไฮไลต์เขตว่าส่วนไหนข้อมูลตรงนั้นมากสุด (%rate) เป็นต้น