Network analysis with OpenStreetMap
OpenStreetMap (OSM) คือแนวคิดการทำงานร่วมกัน ลักษณะชวนคนเข้ามาร่วมสร้างข้อมูล GIS และพัฒนาฐานข้อมูลแบบเปิด เพื่อให้เกิดการใช้งานร่วมกัน ช่วยกัน update แผนที่ มีทั้งถนน อาคาร และ POI
ผมมีโอกาสได้ร่วมงานกับ OSM ในส่วนการ update ข้อมูลแผนที ตั้งแต่สมัยช่วงเริ่มต้น ปัจจุบันผ่านมากว่า 10 ปี OSM ยิ่งเติบโต และมีข้อมูลเพิ่มขึ้นมหาศาล ทั่วโลก จำนวนผู้ใช้กว่า 4 million users
ตรงนี้เป็นการรันตรี ความสำเร็จของแนวคิดโปรเจค crowd-sourced dataset (ซึ่งตอนเปิดตัว หลายคนเชื่อว่ามันจะไม่ work)
ถ้าจำกันได้บทความก่อนหน้า สอนเรื่องการใช้ geocode api จาก OSM ไปแล้ว รวมถึงการดึงข้อมูล based map จาก OSM WMS Tile มาใช้งานบน interactive มาจุดนี้ผมจะมานำเสนอ อีกกระบวนการในการเข้าถึง และใช้งานข้อมูลแผนที่รายละเอียดสูง เช่น route table ของ OSM จาก python ด้วย Lib ชื่อว่า Osmnx
Osmnx พัฒนาบน NetworkX, matplotlib และ geopandas เพื่อรองรับการทำงานด้าน network analysis จากฐานข้อมูลถนนและเส้นทาง ของ OSM Map Service ซึ่ง มีหลายฟังก์ชั่นและโมดูลงานที่สำคัญ ในการวิเคราะห์การเดินทาง, คำนวณต้นทุน/คำนวณเวลาเดินทาง,หาเส้นทางสั้นสุด(shortest paths) ,การจัดระบบการขนส่ง แม้แต่งาน fleet management ก็สามาถประบุกต์ใช้ Osmnx ได้
นอกจาก Osmnx ยังรองรับการ visualization และ routing data model อีกด้วย ซึ่งในบทความนี้ผมจะสาธิต วิธีการใช้งานเบื้องต้นในการทำ network analysis ให้ได้ศึกษากัน
Installation
การติดตั้งไม่ยาก บน window สามารถติดตั้งผ่าน conda ได้โดยใช้คำสั่ง
conda install -c conda-forge osmnx
> หลังจากติดตั้งสำเร็จ ทำการเรียกใช้งานโมดูลสำคัญ ด้วยการ import
#Import module
import osmnx as ox
Retrieving OSM Network Data
การเข้าถึงข้อมูล OSM Map Service โดยการดึงข้อมูลstreet networks ซึ่งสามารถเรียกข้อมูลโดยการระบุ parameter ในการ query ได้หลายชนิด เช่น ค้นหาจาก bounding box, place name , street name หรือ polygon เป็นต้น
นอกจากนี้เรายังสามารถระบุประเภท output ของ network ที่ต้องการได้อีกด้วย เช่น drive, walk , bike เป็นตัน สามารถทำการเขียน code คำสั่งสามารถทำได้ดังนี้
#ตัวอย่างที่ 1 : เรียกข้อมูล network จากชื่อเมือง
#Download BKK route data
ox.plot_graph(ox.graph_from_place(‘Bangkok, Thailand’))
> ผลลัพธ์ที่ได้ ภาพแผนที่ โครงข่ายถนน บริเวณเขต กรุงเทพ
#ตัวอย่างที่ 2 : เรียกข้อมูล network จาก ชื่อสถานที่
ทดลองกำหนด place ชื่อสถานที่แบบเฉพาะ เช่น ห้างสยามพารากอน โดยเรียกดูข้อมูลถนน ระยะ 5 km
place_name = “Siam Paragon, Bangkok,Thailand”
graph = ox.graph_from_place(place_name, network_type=’drive’ ,buffer_dist=5000)
ox.plot_graph(graph)
>ผลลัพธ์ที่ได้ ภาพแผนที่ โครงข่ายถนน บริเวณ สยามพารากอน
#ตัวอย่างที่ 3: เรียกข้อมูล network จาก BBOX
ทดลองกำหนดขอบเขตพิกัดแบบ BBOX เพื่อเรียกข้อมูล network จาก OSM
G = ox.graph_from_bbox(13.745,13.736,100.5428,100.524, network_type=’all’)
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected)
>ผลลัพธ์ที่ได้ ภาพแผนที่ โครงข่ายถนน บริเวณ จุฬาลงกรณ์มหาวิทยาลัย
> จำแนกข้อมูล node และ edge ออกจากกัน แสดงผลแบบ 2 layer
Retrieving City boundaries & Building Data
นอกจากข้อมูล network แล้วใน OSM ยังมีข้อมูลประเภท polygon เช่น ขอบเขตเมือง, และข้อมูลอาคาร (bulding) ให้สามารถดาวน์โหลดนำไปใช้งานได้อีกด้วย
ซึ่งเราสามารถใช้ python เรียกข้อมูลเหล่านี้ แปลงเข้าสู่ geodataframe หรือจะส่งออกเป็น shapefile ก็สามารถทำได้เช่นกัน
city = ox.gdf_from_place(‘Phra Nakhon Si Ayutthaya Province Thailand’)
ox.save_gdf_shapefile(city)
ox.plot_shape(ox.project_gdf(city))
>ผลลัพธ์ที่ได้ ภาพแผนที่ ขอบเขต จังหวัด อยุธยา
การเรียกข้อมูล อาคาร จาก OSM สามารถทำได้ผ่าน โดยจะผลลัพธ์เป็น GeoDataFrame ซึ่งพร้อมที่ใช้ทำการวิเคราะห์เชิงพื้นที่ หรือทำ geoprocessing ต่อได้ทันทีเลย
ตัวอย่าง เขียน code เพื่อเข้าถึงข้อมูล อาคาร ในบริเวณ จุฬาลงกรณ์
place_name = “Chulalongkorn University, Bangkok,Thailand”
buildings = ox.buildings_from_place(place_name)
ox.plot_shape(ox.project_gdf(buildings))
>ผลลัพธ์ที่ได้ ภาพแผนที่ อาคารบริเวณ จุฬา
>เรียกข้อมูล ถนนภายในมหาวิทยาลัยมาซ้อนทับ
Network Stat
ก่อนทำการวิเคราะห์ จำเป็นต้องทราบรายละเอียดของข้อมูล network ก่อน โดยเราสามารถเรียกใช้งาน ox.basic_stats หรือ ox.extended_stats ได้
>ตัวอย่างนี้ใช้ข้อมูล route ก่อนหน้าบริเวณจุฬา ที่ได้ทำการ download ไว้
> ทำการเขียน code เพื่อเรียกดู stat ของข้อมูล
> แสดงผลลัพธ์ในรูปแบบ dataframe โดยมีค่าสถิติสำคัญต่างๆ ของ node , edge , intersection เป็นต้น
> ใช้คำสั่ง get_node_colors_by_stat เพื่อตรวจสอบข้อมูลแบบโหมด Betweenness centrality แล้วแสดงผล node รายสี เพื่อทำการตรวจสอบ topology
> แสดงผลลัพธ์รูปแบบแผนที่
Network Analysis
การวิเคราะห์ network analysis ทำผ่าน nx.shortest_path โดยต้องเตรียมข้อมูล graph ที่สร้างจาก route ที่ทำการ download จาก OSM ตัวอย่างนี้จะใช้ network type ทุกประเภท(Drive & Walk) วิเคราะห์รวมกัน
รวมถึงการกำหนดจุดเริ่มต้น และสิ้นสุด จากพิกัด ที่เราต้องการ ซึ่งสามารถใช้ ox.get_nearest_node ทำการ snap ตัวพิกัด ลงบน node ใกล้เคียง เพื่อรัน network analysis ได้ทันที
> แสดงผลลัพธ์ที่ได้
Interactive web mapping
ความเจ๋งอีกอย่างของ OSMnx คือมี build-in ฟังชั่นการส่งออก graph ไปยัง folium เพื่อแสดงผลแบบ Interactive web mapping ได้ทันที เรียกว่าเมื่อรัน network analysis เสร็จ สามารถ save เป็น web mapping เพื่อ ใช้แสดงผลออนไลน์ ได้เลย โดยไม่ต้อง เขียน code ในการพัฒนาเว็บเพิ่มเติม
สามารถเปิดไฟล์ route_graph.html ได้ทันที หรือจะ upload ขึ้น server เพื่อแสดงผลข้อมูลแผนที่ ก็ได้เช่นกัน
ตรงนี้สามารถเรียนรู้การใช้ folium เพิ่มเติม เพื่อเพิ่มความสามารถ ตกแต่ง application และอื่นๆ