تحلیل شبکه و دسترسی (Network & Accessibility Analysis)¶
1. مقدمه¶
تحلیل شبکه (Network Analysis) یکی از روشهای اساسی در برنامهریزی و طراحی شهری است که کاربردهای تخصصی فراوانی دارد. مسائل مربوط به برنامهریزی در شرایط بحرانی، مکانیابی تأسیسات حیاتی، و طراحی زیرساختهای پرهزینه خدمات عمومی و حملونقل. دسترسپذیری و تحلیل شبکه، به ارتباط میان الگوهای حرکتی و سهولت استفاده از فرصتها و مکانها میپردازند. تحلیل شبکه به ما کمک میکند تا بفهمیم افراد، وسایل نقلیه، یا خدمات چگونه در شبکه شهری جابهجا میشوند و چه مناطقی دارای بیشترین یا کمترین دسترسی هستند.
2. مفاهیم کلیدی¶
شبکه شهری (Urban Network)¶
اکثر مطالعات شبکههای فضایی تا به امروز، شبکهها را با استفاده از دو نوع عنصر شبکه نشان دادهاند – گرهها و یالها. نمایش گرافی کمک میکند تا روابط بین موجودیتها را در تحلیل شبکه بررسی کنیم. در مورد شبکههای خیابانی شهری، معمولاً یالها نمایانگر قطعات خیابان و گرهها نقاط تقاطع هستند که در آن دو یا چند یال همدیگر را قطع میکنند. میتوان گفت شبکه شهری مجموعهای از گرهها (Nodes) و یالها (Edges) است که خیابانها، مسیرهای پیادهروی، یا خطوط حملونقل را نمایش میدهد.
*گرهها (Nodes):* تقاطعها یا ایستگاهها
*یالها (Edges):* مسیرهای ارتباطی میان گرهها
چارچوب تحلیل شبکه شهری (Urban Network Analysis – UNA) از یک سیستم سه جانبه با سه عنصر اصلی استفاده میکند: 1. یالها (Edges): مسیرهایی که مسافران میتوانند از طریق آنها حرکت کنند. 2. گرهها (Nodes): تقاطعهایی که دو یا چند یال در آنها همدیگر را قطع میکنند. 3. ساختمانها (Buildings): مکانهایی که ترافیک خیابانها وارد محیطهای داخلی میشود یا بالعکس. با این رویکرد، واحد تحلیل،ساختمانها میشود و شاخصهای مختلف گراف میتوانند بهطور جداگانه برای هر ساختمان محاسبه شوند. این روش به کاربر اجازه میدهد تا تراکم نامتوازن ساختمانها و الگوهای کاربری زمین در سراسر شبکه را در نظر بگیرد، که در اکثر روشهای قبلی تحلیل شبکه شهری بررسی نمیشدند. نمایش UNA فرض میکند که هر ساختمان به نزدیکترین قطعه خیابان (یال) متصل است، از طریق کوتاهترین اتصال عمود بر مسیر.
🔹 دسترسیپذیری (Accessibility)¶
ویژگی یک مکان که سهولت دسترسی به آن مکان از فرم شهری اطراف و جاذبههای کاربری زمین را توصیف میکند.
3. ابزارهای تحلیل شبکه¶
ابزارهای مختلفی برای انجام تحلیل شبکه وجود دارند، از جمله: - QGIS (Network Analysis Plugin) - ArcGIS Network Analyst - Mapbox & Mapbox Directions API - Python (NetworkX, OSMnx)
4. تحلیل ترافیک با Mapbox¶
در این تمرین از Mapbox برای تحلیل شبکه ترافیکی استفاده میکنیم. در این بخش با استفاده از دادههای شبکه راهها و نقاط مبدا/مقصد، میزان دسترسی و الگوهای ترافیکی بررسی میشود.
مراحل کلی:¶
- تعریف محدوده و کاشیها → آمادهسازی دانلود داده تراکم.
- دانلود دادههای ترافیک Mapbox و ذخیره در Shapefile.
- ساخت گراف خیابانی از OSM (گرهها و یالها).
- خواندن دادههای تراکم و محاسبه سرعت واقعی و زمان سفر برای هر خیابان.
- ساخت گراف NetworkX با وزن زمان سفر برای هر یال و زمان.
- افزودن ایستگاههای آتشنشانی و یافتن نزدیکترین گرهها.
- محاسبه محدوده دسترسی ۱۰ دقیقهای برای هر ایستگاه.
- ترسیم شبکه و محدودههای دسترسی روی نقشه.
کاشیهای Mapbox (یا به طور عمومی Web Map Tiles) در واقع بخشهای کوچک و مربعی نقشه هستند که نقشهٔ بزرگ را به قطعات کوچک تقسیم میکنند تا بتوان آنها را سریع و بهینه بارگذاری و نمایش داد.
مشخصات کاشیها:¶
- مربعی و ثابت اندازه هستند (معمولاً ۲۵۶×۲۵۶ پیکسل).
- هر کاشی با مختصات x و y و سطح زوم z شناخته میشود.
- مثال:
z=14, x=4823, y=6163
- مثال:
- در مجموع، این سه عدد موقعیت کاشی در شبکه جهانی نقشه را مشخص میکنند.
۱. تعریف محدوده و کاشیها (Mapbox)¶
- محدوده جغرافیایی (
BBox) و سطح زوم (Zoom) مشخص شد. - با کتابخانه mercantile مختصات جغرافیایی به کاشیهای Mapbox تبدیل شدند (
x_min, x_max, y_min, y_max). - هدف: تقسیم محدوده به کاشیهای کوچک برای دانلود دادههای تراکم ترافیک.
۲. دانلود دادههای ترافیک از Mapbox¶
- حلقه روی همه کاشیها میچرخد و با استفاده از URL Mapbox، دادهها به فرمت MVT (Mapbox Vector Tile) دانلود میشوند.
- دادهها به پوشه موقت ذخیره میشوند، سپس به GeoDataFrame تبدیل شده و با هم ترکیب میشوند.
- دادهها به شکل Shapefile ذخیره میشوند (
traffic_YYYYMMDD_HHMM.shp). - هدف: دریافت دادههای ترافیک زنده یا تاریخی برای محدوده شهری مشخص.
۳. ساخت گراف خیابانی با OSMnx¶
G_osm = ox.graph_from_bbox(BBox, network_type='drive')
osm_segments = ox.graph_to_gdfs(G_osm, nodes=False, edges=True)
osm_nodes = ox.graph_to_gdfs(G_osm, nodes=True, edges=False)`
- شبکه خیابانی خودرو (
drive) از OSM ساخته شد. - به دو GeoDataFrame تقسیم شد:
osm_segments: خیابانها (یالها)osm_nodes: تقاطعها (گرهها)...
۴. خواندن و آمادهسازی دادههای ترافیک¶
- همه Shapefileهای ترافیک خوانده شدند و CRS آنها با شبکه OSM هماهنگ شد.
- سرعت نامی خیابانها (
maxspeed) خوانده شد و به m/s تبدیل شد. - ضرایب تراکم ترافیک تعریف شد (
low, moderate, heavy, severe). -
برای هر زمان، سرعت واقعی و زمان سفر هر یال محاسبه شد:
adj_spd = max_speed * congestion_factor trvl_time = length / adj_spd
۵. ساخت گراف NetworkX با وزن زمان سفر¶
- گراف
MultiDiGraphساخته شد. - هر یال با طول و زمان سفر در دو زمان مختلف به گراف اضافه شد.
- خیابانهای دوطرفه، یال معکوس هم دریافت کردند.
۶. افزودن گرهها (Nodes) به گراف¶
for idx, row in osm_nodes.iterrows():
attrs = row.drop('geometry').to_dict()
attrs['geometry'] = row.geometry
G.add_node(idx, **attrs)
- تمام تقاطعها به گراف اضافه شدند و اطلاعات مکانی آنها ذخیره شد.
۷. اضافه کردن ایستگاههای آتشنشانی¶
tags = {'amenity':'fire_station'}
fire_stations = ox.features_from_bbox(BBox, tags)
fire_stations = fire_stations[fire_stations.geometry.type == 'Point']
- ایستگاههای آتشنشانی داخل BBox از OSM گرفته شد.
- نقاط فقط
Pointانتخاب شدند. - گره نزدیکترین به هر ایستگاه با
ox.nearest_nodesپیدا شد.
۸. تحلیل محدوده دسترسی (Service Area)¶
- برای هر ایستگاه و هر زمان، از
nx.single_source_dijkstra_path_lengthاستفاده شد تا تمام خیابانهایی که در ۱۰ دقیقه دسترس هستند پیدا شوند. - برای هر ایستگاه، یک Subgraph از مسیرهای قابل دسترس ساخته شد (
service_time1وservice_time2).
۹. ترسیم گراف و نتایج¶
- شبکه کلی به رنگ خاکستری رسم شد.
+Subgraphهای دسترسی ایستگاهها:
- زمان اول → رنگ قرمز
- زمان دوم → رنگ آبی
- ایستگاههای آتشنشانی به رنگ سبز رسم شدند.
- عنوان نمودار:
'Fire station Service in time'.
دادههای ترافیکی و استفاده از Mapbox¶
دادههای ترافیکی بهعنوان بخشی از دادههای جابهجایی محسوب میشوند. با توجه به استفاده گسترده از نقشههای ترافیکی آنلاین، میتوان نتیجه گرفت که دادههای ترافیکی برای کشور ایران نیز در دسترس هستند. با این حال، دسترسی به این دادهها بهراحتی امکانپذیر نیست، زیرا شرکتهایی نظیر گوگل و بینگ از این اطلاعات بهعنوان منابع درآمدی خود بهرهبرداری میکنند و بهطور رایگان آنها را در اختیار عموم قرار نمیدهند.
اگرچه دادههای ترافیکی جزو اطلاعات محرمانه بهشمار نمیروند، اما در کشور ما دسترسی به آنها بهسادگی فراهم نیست. یکی از سرویسهایی که میتوانیم برای دسترسی به این دادهها استفاده کنیم، Mapbox است که امکان دریافت دادههای ترافیکی را بهطور آنلاین و آسان فراهم میآورد.
معرفی Mapbox¶
سایت Mapbox یکی از پیشرفتهترین پلتفرمهای نقشهسازی و تجزیه و تحلیل دادههای جغرافیایی است. این پلتفرم ابزارهایی را برای ایجاد نقشههای تعاملی، تحلیل دادههای جغرافیایی و افزودن ویژگیهایی مانند ترافیک، حملونقل، و دادههای مکانمحور فراهم میکند.
یکی از ویژگیهای برجسته Mapbox، قابلیت دریافت دادههای ترافیکی در زمان واقعی است. این ویژگی به کاربران این امکان را میدهد که وضعیت ترافیک جادهها را بهصورت زنده و با دقت بالا مشاهده کنند.
برای استفاده از خدمات Mapbox Traffic v1 یا سایر دادههای جغرافیایی این پلتفرم، میتوانید به سایت رسمی Mapbox مراجعه کنید:
Mapbox Official Site
استفاده از API Mapbox¶
با استفاده از API Mapbox، میتوان بهراحتی دادههای ترافیکی را از سرویسهای Mapbox دریافت کرد. برای دسترسی به لایههای داده از طریق Vector Tiles API، میتوان از الگوی زیر استفاده نمود:
در این URL، {z}، {x} و {y} نمایانگر مقادیر مربوط به موقعیت جغرافیایی هستند. با تغییر این مقادیر، میتوان دادههای مورد نظر را دریافت کرد.
وکتور تایلها (Vector Tiles)¶
وکتور تایلها یک فرمت برای ذخیرهسازی و انتقال دادههای جغرافیایی هستند که در نمایش نقشهها در وب و اپلیکیشنهای موبایل استفاده میشوند. برخلاف رستر تایلها که تصاویر ثابت هستند، وکتور تایلها از دادههای جغرافیایی بهصورت وکتوری (شکلها و خطوط) استفاده میکنند. این امر این امکان را فراهم میآورد که نقشهها بهصورت پویا و با کیفیت بالا روی دستگاههای مختلف بارگذاری و تغییر اندازه داده شوند.
وکتور تایلها برای پروژههایی که نیاز به نقشههای تعاملی و پویا دارند بسیار مناسب هستند و در مقایسه با رستر تایلها مزایای زیادی دارند. در سرویسهایی مانند Mapbox و Google Maps، این نوع تایلها بهطور گسترده استفاده میشوند.
دادههای ترافیکی Mapbox¶
دادههای ترافیکی Mapbox بهصورت کیفی و پویا در دسترس هستند و بهطور مداوم وضعیت ترافیک در جادهها را در زمان واقعی نشان میدهند. این دادهها به کاربران این امکان را میدهند که وضعیت ترافیک را در سطح جادهها، خیابانها و بزرگراهها مشاهده کنند.
اطلاعات کیفی ترافیک¶
دادههای ترافیکی Mapbox بهطور عمده بهصورت کیفی نمایش داده میشوند، به این معنا که وضعیت کلی ترافیک بهصورت رنگها و شاخصهای قابلدرک به نمایش درمیآید.
نمونه URL برای دریافت دادههای ترافیکی از Mapbox¶
برای دریافت دادهها از سرویس ترافیک Mapbox Traffic v1، میتوانید از URL زیر استفاده کنید:
https://api.mapbox.com/v4/mapbox.mapbox-traffic-v1.json?access_token=YOUR_ACCESS_TOKEN
در اینجا، YOUR_ACCESS_TOKEN باید با توکن دسترسی واقعی شما جایگزین شود.
نحوه دریافت Access Token از Mapbox¶
-
ساخت حساب کاربری در Mapbox
ابتدا باید یک حساب کاربری در Mapbox ایجاد کنید. برای این منظور، به سایت Mapbox مراجعه کرده و یک حساب کاربری جدید بسازید:
Mapbox Signup -
ورود به حساب کاربری
پس از ایجاد حساب کاربری، وارد حساب خود شوید. -
دریافت Access Token
بعد از ورود به حساب کاربری، مراحل زیر را دنبال کنید: - به صفحه Account یا Dashboard بروید.
- در این صفحه، گزینهای به نام Access Tokens خواهید دید. روی آن کلیک کنید.
Bounding Box چیست؟¶
یک مفهوم مهم در جغرافیا و دادههای جغرافیایی است. این مستطیل، منطقهای را روی نقشه مشخص میکند که با استفاده از مختصات جغرافیایی (عرض و طول جغرافیایی) آن را محدود میکنیم. بهعبارتدیگر، Bounding Box یک ناحیه جغرافیایی را تعریف میکند که از چهار مرز تشکیل شده است:
عرض جغرافیایی پایین (South Latitude)
عرض جغرافیایی بالا (North Latitude)
طول جغرافیایی چپ (West Longitude)
طول جغرافیایی راست (East Longitude))
برای تعیین Bounding Box میتوانید از سایت bboxfinder.com استفاده کنید. این ابزار به شما این امکان را میدهد که یک ناحیه خاص را روی نقشه انتخاب کرده و مختصات دقیق آن را به دست آورید.
مراحل استفاده از پلیگون در bboxfinder.com:¶
- باز کردن سایت: ابتدا به سایت bboxfinder.com بروید.
- انتخاب ابزار کشیدن پلیگون: در سایت، ابزارهای مختلفی برای انتخاب منطقه وجود دارد. یکی از این ابزارها، ابزار Polygon است که به شما اجازه میدهد با کشیدن یک پلیگون، منطقه خاصی را بر روی نقشه مشخص کنید.
- کشیدن پلیگون: برای استفاده از این ابزار، کافی است که در نقشه روی نقاط مختلف کلیک کنید تا یک پلیگون بسازید. نقاطی که انتخاب میکنید، به ترتیب به هم وصل میشوند تا محدوده مورد نظر شما تشکیل شود.
الگوی URL برای درخواست دادهها از Mapbox¶
https://api.mapbox.com/v4/mapbox.mapbox-traffic-v1.json?access_token=YOUR_ACCESS_TOKEN&bbox={}&zoom={}
در این URL، bbox={} و zoom={} بهعنوان پارامترهایی برای تعیین محدوده جغرافیایی (Bounding Box) و میزان بزرگنمایی (Zoom) در نقشه استفاده میشوند.
مثال Bounding Box:¶
BBOX = (51.376259, 35.700060, 51.457455, 35.741859)
در این مثال، مختصات طول و عرض جغرافیایی برای تعیین محدوده جغرافیایی مشخص شدهاند:
طول جغرافیایی پایین (West Longitude): 51.376259
عرض جغرافیایی پایین (South Latitude): 35.700060
طول جغرافیایی بالا (East Longitude): 51.457455
عرض جغرافیایی بالا (North Latitude): 35.741859
کد کامل برای دریافت دادههای ترافیکی از Mapbox¶
import os
import requests
import geopandas as gpd
import pandas as pd
import mercantile
BBOX = (51.376259, 35.700060, 51.457455, 35.741859)
ZOOM = 14
OUT_DIR = os.path.join('data', 'traffic')
os.makedirs(OUT_DIR, exist_ok=True)
tile_ul = mercantile.tile(BBOX[0], BBOX[3], ZOOM)
tile_lr = mercantile.tile(BBOX[2], BBOX[1], ZOOM)
x_min, x_max = min(tile_ul.x, tile_lr.x), max(tile_ul.x, tile_lr.x)
y_min, y_max = min(tile_ul.y, tile_lr.y), max(tile_ul.y, tile_lr.y)
# URL Template درست برای درخواست تایلها از Mapbox
URL_Template = 'https://api.mapbox.com/v4/mapbox.mapbox-traffic-v1/{z}/{x}/{y}.mvt?access_token=YOUR_ACCESS_TOKEN'
for x in range(x_min, x_max + 1):
for y in range(y_min, y_max + 1):
url = URL_Template.format(z=ZOOM, x=x, y=y)
outfile = os.path.join(OUT_DIR, f"{ZOOM}_{x}_{y}.mvt")
try:
resp = requests.get(url, headers=None, timeout=15)
if resp.status_code == 200 and resp.content:
with open(outfile, 'wb') as f:
f.write(resp.content)
else:
print(f"[WARN] {resp.status_code}: {url}")
except Exception as e:
print(f"[ERROR] {e}: {url}")
gdfs = []
for file in os.listdir(OUT_DIR):
if file.endswith('.mvt'):
mvt_path = os.path.join(OUT_DIR, file)
gdf = gpd.read_file(mvt_path)
gdfs.append(gdf)
merge_gdfs = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True), crs=gdfs[0].crs)
merge_gdfs.to_file(os.path.join(OUT_DIR, 'traffic.shp'))
ساخت پوشه مقصد در صورت عدم وجود:
این خط از کد بررسی میکند که آیا پوشه data/traffic وجود دارد یا خیر. اگر وجود نداشته باشد، آن را میسازد. گزینه exist_ok=True باعث میشود اگر پوشه قبلاً وجود داشته باشد، خطا ندهد.
تبدیل مختصات به تایلها:
در اینجا با استفاده از کتابخانه mercantile، مختصات گوشه بالا سمت چپ و پایین سمت راست Bounding Box (مستطیل محصور) به تایلهای Web Mercator تبدیل میشوند. این تبدیل به ما این امکان را میدهد که دادهها را به صورت تایلهای کوچک از Mapbox درخواست کنیم.
BBOX[0]: طول جغرافیایی غرب (minimum longitude).
BBOX[1]: عرض جغرافیایی پایین (minimum latitude).
BBOX[2]: طول جغرافیایی شرق (maximum longitude).
BBOX[3]: عرض جغرافیایی بالا (maximum latitude).
محاسبه مرزهای تایلها:
x_min, x_max = min(tile_ul.x, tile_lr.x), max(tile_ul.x, tile_lr.x)
y_min, y_max = min(tile_ul.y, tile_lr.y), max(tile_ul.y, tile_lr.y)
این کد مرزهای افقی و عمودی تایلها را محاسبه میکند. برای مثال، اگر چندین تایل در منطقه خاصی نیاز داریم، این خطوط مرزهای آن تایلها را مشخص میکند.
در این خط، یک قالب URL برای دریافت دادههای ترافیکی از Mapbox تعریف میشود. با استفاده از این URL میتوان دادههای ترافیکی مربوط به هر تایل را دریافت کرد. پارامترهای bbox و zoom به ترتیب مربوط به محدوده جغرافیایی و سطح بزرگنمایی هستند.
درخواست دادهها از Mapbox
for x in range(x_min, x_max + 1):
for y in range(y_min, y_max + 1):
url = URL_Template.format(z=ZOOM, x=x, y=y)
outfile = os.path.join(OUT_DIR, f"{ZOOM}_{x}_{y}.mvt")
در این حلقههای for، برای هر تایل در منطقه مشخصشده، یک درخواست به Mapbox ارسال میشود. x و y مختصات افقی و عمودی هر تایل هستند. سپس دادهها برای هر تایل در فایلهای .mvt ذخیره میشوند.
ارسال درخواست HTTP به Mapbox:
در این خط، درخواست GET به Mapbox ارسال میشود تا دادههای ترافیکی برای تایل خاص دریافت شود. همچنین برای جلوگیری از وقفههای طولانی، زمان تایماوت 15 ثانیه تعیین شده است.
بررسی وضعیت پاسخ و ذخیره دادهها:
اگر پاسخ موفقیتآمیز باشد (کد وضعیت 200) و دادهها وجود داشته باشند، این دادهها در فایلی که نامش شامل سطح زوم و شماره تایل است ذخیره میشود.
مدیریت خطاها:
اگر درخواست به Mapbox موفقیتآمیز نباشد، کد وضعیت و URL درخواست چاپ میشود تا بتوان دلیل مشکل را شناسایی کرد.
مدیریت استثناها:
در صورتی که خطایی در طول ارسال درخواست یا ذخیرهسازی فایل پیش آید، پیام خطا همراه با URL درخواست چاپ میشود تا بتوان خطا را پیگیری کرد.
خواندن و پردازش دادههای .mvt:
gdfs = []
for file in os.listdir(OUT_DIR):
if file.endswith('.mvt'):
mvt_path = os.path.join(OUT_DIR, file)
gdf = gpd.read_file(mvt_path)
gdfs.append(gdf)
تمام فایلهای .mvt که در پوشه OUT_DIR ذخیره شدهاند خوانده میشوند و به یک لیست از GeoDataFrameها (gdfs) اضافه میشوند. این دادهها بعداً برای ترکیب استفاده خواهند شد.
ترکیب دادهها در یک GeoDataFrame:
تمام GeoDataFrameهای خواندهشده از فایلهای .mvt به یک GeoDataFrame واحد ترکیب میشوند. این ترکیب به ما این امکان را میدهد که تمام دادهها را در یک مجموعه داشته باشیم.
ذخیره دادههای نهایی بهصورت Shapefile:
در نهایت، دادههای ترکیبشده به فرمت Shapefile ذخیره میشوند.