کار با کاشی‌ها یا چطور بستر نقشه آماده می‌شود؟

احتمالاً اولین باری که اسم یک اپلیکیشن نقشه رو شنیدین یا از نزدیک باهاش کار کردین، شما هم مثل من درگیر امکانات مختلفی که این اپلیکیشن‌ها دارن شدین. از مسیریابی بگیر که یکی از بزرگترین کاربردهای روزمره‌ی اینجور اپلیکیشن‌هاست تا سرچ و مکان‌هایی مثل مغازه و بیمارستان و … که روی نقشه هستن. اما یک چیز دیگه‌ای هم توی اپلیکیشن‌های نقشه وجود داره که انقدر پایه‌ایه و همه جا هست که گاهی حواسمون بهش نیست و متوجه حضورش نیستیم، اونم Tileها یا در‌واقع کاشی‌های نقشه.

قبل از اینکه جلوتر بریم یه کم صبر کنین و با خودتون فکر کنین. این چیزی که روی نقشه می‌بینیم به نظرتون چه شکلی به وجود اومده؟ انگار یه بستری وجود داره که روی اون یه سری چیز دیگه کشیده شدن. به عکس ۱ دقت کنین، یک بک‌گراند خاکستری رنگ وجود داره که پس‌زمینه‌ی نقشه‌ست و روش چیزهای مختلف دیگه‌ کشیده شدن. بزرگراه‌ها و آزادراه‌هایی که با رنگ بنفش طراحی شدن، یک سری نقطه (که ما بهشون می‌گیم poi یا point of interest) مثل رستوران باغ بهشت سمت لواسون یا بیمارستان نیکان سمت ازگل، مجتمع کوروش سمت غرب و … . یه کم دقیق‌تر بشیم، دیگه چی می‌بینیم روی اون پس‌زمینه‌ی خاکستری رنگ؟ یه سری جا هستن که آبی‌ن، به نظر میاد رود یا دریاچه‌ن. مثل سد لتیان سمت شرق عکس و دریاچه‌ی چیتگر سمت غرب عکس. یه سری جا هستن که سبز رنگن و به نظر میاد پارکهای مختلف رو نشون می‌دن. یه سری خط زرد هم هستن که انگار خیابون‌های اصلی شهر رو نشون می‌دن و کلی چیزهای دیگه.

عکس ۱
عکس ۱

تازه اوضاع به همین ختم نمی‌شه. یه کم که سطح بزرگنمایی نقشه رو عوض کنین و جلو عقب برین یه سری چیز حذف می‌شن و چیزهای دیگه جاشون رو می‌گیرن.

عکس ۲
عکس ۲

به نظرتون همه‌ی این چیزهای مختلفی که روی نقشه هستن و سطح بزرگنمایی‌های(zoom level) مختلفی که استفاده می‌شن برای نمایش و عدم نمایش چه شکلی درست شدن؟


کاشی یا Tile

یه کم اگر بخوایم از حرف‌های کلی بگذریم و برسیم سر اتفاقی که در پشت صحنه می‌افته و چنین تصاویری تولید می‌شه باید اول از همه از کاشی‌ها حرف بزنیم. یکی از استانداردهای خیلی مرسوم برای کار کردن با نقشه، کاشی کاشی کردن اونه. یعنی چی؟ یعنی فرض کنین انقدر از بالا دارین به نقشه‌ی جهان نگاه می‌کنین که کل نقشه‌ی جهان توی یه مربع جا می‌شه. مثل عکس ۳.

عکس ۳
عکس ۳

این در‌واقع اولین کاشی نقشه‌ی ماست. اولین کاشی که اصطلاحاً توی سطح بزرگنمایی ۰ وجود داره کاشی‌ایه که کل جهان توش جا می‌شه. حالا اگر یه کم بیشتر بزرگنمایی کنیم چی؟ عکس از طول و عرض به دو قسمت مساوی تقسیم می‌شه و نتیجه میشه ۴ تا کاشی که توی سطح بزرگنمایی ۱ وجود دارن. مثل عکس ۴.

عکس ۴
عکس ۴

همون‌طور که مشخصه دیگه فقط سطح بزرگنمایی کافی نیست برای اینکه بگیم با کدوم کاشی کار داریم. توی سطح بزرگنمایی ۱ تعداد کاشی‌هامون چهار تاست. برای اینکه بتونیم بگیم با کدوم کاشی سطح بزرگنمایی ۱ کار داریم میایم و دو تا پارامتر دیگه علاوه بر سطح بزرگنمایی وارد می‌کنیم، x و y. جفت این عدد‌ها از صفر شروع می‌شن و یکی یکی می‌رن بالا و بهمون یه آدرسی از هر کاشی میدن. مثلاً کاشی بالا سمت چپ سطح بزرگنمایی ۱ میشه کاشی‌ای با مشخصات zoom=1, x=0, y=0. اما کاشی‌ای که پایین سمت راست قرار داره مشخصاتش اینه: zoom=1, x=1, y=1 .

احتمالاً دیگه می‌تونین حدس بزنین که توی سطح بزرگنمایی ۲ چند تا کاشی داریم و آدرس‌دهی‌شون چه شکلیه. حالا اگر همین روند رو ادامه بدیم همین‌طور می‌تونیم بزرگنمایی نقشه رو بیشتر و بیشتر کنیم و کاشی‌های بیشتر و دقیق‌تری داشته باشیم. در‌واقع با هر بار بیشتر کردن بزرگنمایی نقشه محدوده‌ی هر کاشی مشخص‌تر میشه و راحت‌تر میشه فهمید هر عنصری که روی نقشه داریم کجاست:

عکس ۵
عکس ۵

حالا که یکی از مفاهیم پایه‌ای کار با نقشه رو متوجه شدیم بیاین یه کم دقیق‌تر ببینیم که حالا چه شکلی میشه چیزهای مختلف مثل جاده‌ها، poiها، دریاچه‌ها و … رو به کمک همین کاشی‌ها روی نقشه آورد.


از دیتای خام تا کاشی‌ها

اول با poiها شروع کنیم که ساده‌ترن. فرض کنین نقطه‌ی مهمی داریم که می‌خوایم اون رو روی نقشه نشون بدیم. مثلاً برج میلاد. برج میلاد لوکیشن مشخصی داره. حدوداً latitude: 35.742 و longitude:51.373. اگر با این دو عدد آشنا نیستین فقط یه اشاره‌ی ریز بکنم که یه جور آدرس دهی روی فضای کره‌ی زمینه که در واقع همون طول و عرض جغرافیاییه. اینجا بیشتر راجع به این دو تا عدد توضیح داده شده.

حالا برج میلاد رو توی چه سطح بزرگنمایی‌ نشون بدیم؟ احتمالا نمایش برج میلاد توی سطح بزرگنمایی ۰، که کل جهان نمایش داده میشه، کار جالبی نیست. کلی برج دیگه هست که اهمیتشون با برج میلاد یکیه و اگر بخوایم همه رو از اول نشون بدیم نقشه به شدت شلوغ می‌شه و اصلاً نمی‌فهمیم چی به چی شد. مثلا شاید نمایش برج میلاد از سطح بزرگنمایی ۱۲ به بعد خوب باشه، مثلا ۱۲ تا ۱۸. حالا چه شکلی باید اسم و آیکون برج میلاد رو توی جایی که لوکیشن واقعی‌ش قرار داره توی سطح بزرگنمایی ۱۲ تا ۱۸ بذاریم؟

اینجاست که باید بفهمیم برج میلاد به ازای سطح بزرگنمایی‌های ۱۲ تا ۱۸ توی کدوم کاشی می‌افته. در واقع در هر کدوم از این سطح بزرگنمایی‌ها باید x و yای که مختصات برج میلاد توش می‌افته رو به دست بیاریم. اما این کار ساده‌ای نیست که به صورت دستی بیایم و محاسبه‌ش کنیم.

از طرف دیگه اسم poiای که نماینده‌ی برج میلاده رو می‌خوایم چی بذاریم؟ آیکونش چی باشه؟ آیا مشخصات دیگه‌ای ازش هست که بخوایم روی نقشه نشون بدیم؟ مثلا امتیازش؟ یا تعداد کامنت‌هاش؟ خب. برای اینکارها چیکار می‌کنیم؟ یک فایلی با فرمت geojson تولید می‌کنیم. geojson در واقع همون jsonایه که مختص کار با نقشه و فضاهای جغرافیایی‌ه. توی این فایل مختصات poi و پارامترهای دیگه‌ای که برامون مهمه و میخوایم روی نقشه نمایششون بدیم یا باهاشون یک ‌سری فیلتر انجام بدیم رو می‌ذاریم. مثلا فرض کنید برای برج میلاد همچین حالتی پیدا می‌کنه:

{
  &quottype&quot: &quotFeatureCollection&quot,
  &quotfeatures&quot: [
    {
      &quottype&quot: &quotFeature&quot,
      &quotgeometry&quot: {
        &quottype&quot: &quotPoint&quot,
        &quotcoordinates&quot: [51.373, 35.742]
      },
      &quotproperties&quot: {
        &quotname&quot: &quotبرج میلاد&quot,
        &quotrate&quot: 4.5,
        &quottype&quot: &quottourism&quot,
        &quotminzoom&quot: 12,
        &quotmaxzoom&quot: 18
      }
    }
}

حالا وقتشه که از ابزارهایی استفاده کنیم که geojson رو به کاشی تبدیل می‌کنن. ابزارهای مختلفی برای اینکار وجود دارن که با یه سرچ ساده می‌تونین پیداشون کنین. این ابزارها geojsonای که شما بهشون می‌دین رو تبدیل می‌کنن به کلی کاشی متناسب با سطح بزرگنمایی‌های مختلف که توی هر کاشی اطلاعاتی که باید توی اون محدوده از نقشه نمایش داده بشه وجود داره.

دیگه همه چیز آماده است! کافیه از ابزاری استفاده کنین که تایل‌های نقشه رو بتونه بخونه و اون‌ها رو نمایش بده. از جمله leaflet که یکی از ابزارهای متن‌باز خوب برای اینکاره.


اگر بخوایم خلاصه یه مروری داشته باشیم بر کل فرآیند. باید اول از همه اطلاعاتی که میخوایم روی نقشه نشون بدیم رو از دیتابیس بگیریم، بعد اطلاعات رو به فرمت مناسب داخل geoson بنویسیم و بدیم به ابزاری که برامون geojson رو به کاشی‌ها تبدیل می‌کنه. آخرین مرحله هم دادن آدرس فایل‌های کاشی‌ها به یک ابزار رندر نقشه و بالا اومدن یک بستر نقشه‌ست :)


چند نکته‌ی تکمیلی

  • برای معابر و چندضلعی‌ها که به جای یک نقطه‌ی poi حاوی چند نقطه‌ی متصل بهم هستن هم کار تا حدی مشابهه. مختصات نقاط متصل رو توی فایل geojson داخل فیلد coordinates می‌ذاریم و بقیه‌ی ماجرا.
  • همیشه اطلاعاتی که داخل geojson می‌ذاریم برای نمایش روی نقشه نیستن، توی مثال بالا دیدین که دو تا پارامتر minzoom و maxzoom وجود داشتن. این دو تا پارامتر دارن به ابزار تبدیل کننده‌ی geojson به کاشی می‌گن که این poi توی سطح بزرگنمایی‌های ۱۲ تا ۱۸ ایجاد کن.
  • علاوه بر مورد بالا. گاهی اطلاعاتی داخل geojson می‌نویسیم که برای فیلتر کردن بهمون کمک می‌کنن. مثلا ممکنه بگیم poiهایی که مساحتشون از یه حدی بیشتره رو خاکستری کن یا اون‌هایی که تایپشون tourismئه رو آیکون دیگه‌ای بذار و ...

توی این متن سعی کردم خیلی خلاصه اصول اولیه‌ای رو که دونستنشون برای کار با کاشی‌ها و بالا آوردن نقشه کمک می‌کنه بگم، حتما خیلی چیزهای دیگه‌ای هست و دونستنش کمک می‌کنه. خوشحال می‌شم اگر سوالی یا پیشنهادی بود توی کامنت‌ها مطرح کنین :)