ทำแผนที่ง่ายๆด้วย Folium — Flask

Make beautiful, interactive maps with Python and Leaflet.js

4 min readDec 6, 2019

--

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) เป็นต้น

— Code

— Ref

--

--

Piravit Chenpittaya
Piravit Chenpittaya

Written by Piravit Chenpittaya

call me karn | Computer of Engineering : PSU | IG: karn.svg | git: https://github.com/karnzx /

No responses yet