ארכיון פוסטים שפורסמו בחודש אוגוסט 2008

מפת ישראל בגוגל מפס

שני, 18 באוגוסט 2008

בתקופה האחרונה יצא לי להתעסק הרבה עם שירות המפות של גוגל (Google Maps), וספציפית להשתמש בממשק שגוגל מציעים כדי להציג נתונים על מפה ולשלב את התוצאה באתר חיצוני.

הבעיה היא שנכון לרגע זה, גוגל לא מספקים מפות של ישראל, אלא רק תצלומי לווין. לעומת זאת, אתרים שכן מציגים מפות של ישראל (למשל emap ו-וואלה! מפות) לא מאפשרים לשלב את המפה באתר חיצוני או להציג עליה שכבות מידע נוספות. בפוסט הנוכחי אציג פתרון שמבוסס על הצגת מפות מהאתר ABMaps כשכבה בתוך גוגל מפס.

קוד עובד שמאפשר לעשות זאת ניתן להורדה פה תחת רישיון קוד פתוח. כיוון ששימוש בקוד בודאי מפר את תנאי השימוש של כמה אתרים, המלצתי האישית היא לא להשתמש בו בכלל, ובפרט לא באפליקציה מסחרית. הקוד מוצע להורדה למטרות חינוכיות בלבד, והתוצאה הסופית נראית כך:

abmaps.jpg

כדי להבין איך הפתרון עובד, צריך קודם להבין איך עובדות מפות באופן כללי. הרעיון הבסיסי הוא שיש לנו מידע שנמצא על שטח הפנים של כדור הארץ (או לחילופין על גלובוס), ואנחנו רוצים להציג אותו על דף ניר רגיל. כדור הארץ אמנם תלת מימדי, אבל שטח הפנים שלו דו מימדי - ולכן לפחות ברמה הראשונית לא נראה שאמורה להיות בעיה.

השאלה היא איך בדיוק עושים את זה. כדי להבין איפה הבעיה, תחשבו על תפוז, ותנסו לדמיין איך אפשר להוריד ממנו את הקליפה ולהציג אותה כמלבן מושלם - כשאסור לקרוע מהקליפה חלקים ולשנות את המיקום שלהם.

הפתרון מגיע מהמתמטיקה: בניסוח פורמאלי, השאלה היא כיצד למפות (ז"א להתאים באופן חד-חד ערכי) נקודות על פני כדור תלת-מימדי לנקודות במישור הדו-מימדי. העובדה שניתן לעשות זאת שקולה לכך ששטח הפנים של כדור הוא יריעה דו-מימדית (למשל ניתן לתאר כל נקודה כזו בעזרת שתי קורדינטות כדוריות).

מה שמעניין יותר, הוא שכל מיפוי כזה בהכרח יגרום לעיוותים במרחב, במובן שמרחקים בין נקודות ישתנו כשנעבור מהגלובוס למפה: שני זוגות של נקודות במרחק זהה על הגלובוס עלולים להיות פתאום במרחק שונה על המפה. אם נחשוב שוב על קליפת התפוז שלנו, המשמעות היא שאם אנחנו רוצים למלבן את הקליפה מבלי לשבור אותה לחתיכות, נהיה חייבים למתוח או לדחוס חלקים ממנה.

בפועל, במפות של כדור הארץ נהוג להשתמש בהתאמה בשם היטל מרקטור (Mercator projection), עם נוסחא נוראית מספיק בשביל לכלול לוגריתם של טנגנס. מה לגבי העיוותים במרחב? מתברר שלא חסרים כאלה. למשל, לפי המפות הסטנדרטיות נראה שלגרינלנד ולאפריקה שטח זהה, כשבפועל שטחה של אפריקה גדול פי 14. באופן דומה, אלסקה נראית גדולה יותר מברזיל, למרות שהאחרונה גדולה ממנה פי 5 ויותר. מי שלא מאמין (ואין לו גלובוס בבית בשביל לבדוק) יכול להשוות בין גוגל מפס לגוגל earth.

כעת יש לנו את הכלים להבין איך גוגל מפס עובד. עבור כל רמת זום שנתמכת בגוגל מפס, לגוגל יש מפה מלבנית מתאימה של העולם (שהתקבלה כמובן ע"י הפעלת היטל מרקטור). את המפה הזאת הם בחרו לחלק לריבועי תמונה בגודל 256 על 256 פיקסל כל אחד, ובכל פעם לשלוח לדפדפן רק את הריבועים המתאימים לאיזור הקטן שבו המפה מתמקדת.

למזלינו, גוגל היו חכמים ונחמדים מספיק בשביל לאפשר לכל אחד להרחיב את גוגל מפס, ולהצביע על אתר חיצוני שמספק ריבועים כאלה. אם היה אתר שיודע לספק ריבועי מפה כאלה שכוללים מפות של ישראל, היינו יכולים להצביע עליו והבעיה היתה נפתרת. שיטוט קצר במספר אתרי מפות באינטרנט (עם FireFox פתוח על FireBug, כדי לבחון אילו קבצים יורדים לדפדפן בכל גלישה כזו) העלה שהאתר ABMaps (של חברת AtlasCT הישראלית) מספק את הסחורה.

כעת נותרו שתי בעיות בלבד: ראשית, התברר ש-ABMaps עובדים עם מלבני מפה בגודל 400 על 280 פיקסלים, בעוד גוגל מוכנה לקבל ריבועים בלבד. למזלינו, מתברר שניתן (ע"י שינוי קל בכתובת התמונה) לבקש מ-ABMaps לספק חלקי מפה בכל גודל שהוא. Problem solved.

הבעיה השניה היתה כיצד להתאים בין הקורדינטות של גוגל לבין הקורדינטות של ABMaps. למשל, ריבוע המפה שלפי גוגל הפינה השמאלית העליונה שלו נמצאת בקורדינטות (256, 1024) לא הצביע על אותו איזור של הריבוע המקביל לפי ABMaps.

הנחתי ש-ABMaps לא המציאו את הגלגל מחדש, ובחרו גם הם להשתמש בהיטל מרקטור, או לכל היותר בטרנספורמציה לינארית שלו. לכן, פתרון לבעיה יהיה פשוט למצוא את המקדמים של הטרנספורמציה הזו, ז"א מדובר בבעיית רגרסיה לינארית. כדי לפתור אותה בחרתי 15 נקודות על כדור הארץ, ומצאתי את הקורדינטות שלהן לפי ABMaps ולפי גוגל מפס. והרי התוצאות:

abmaps-graph.png

המתאם המושלם בין הנתונים מאשש את ההשערה ש-ABMaps משתמשים בטרנספורמציה לינארית על היטל מרקטור הסטנדרטי. בנוסף, ממקדמי הרגרסיה שהתקבלו ניתן לשער שנקודות החיתוך עם הצירים הן בפועל 364000000 ו-164000000, ושהשיפוע זהה עבור קורדינטת ה-x וקורדינטת ה-y. לכן, מודל רגרסיה טוב יותר הוא כזה שמחפש רק את השיפוע (הזהה) האופטימלי בהינתן שנקודות החיתוך עם הצירים הן כנ"ל.

בשלב זה נטשתי את excel, וכתבתי קוד CVX שפותר את הבעיה, כדי להגיע לערך שיפוע של 1.072883578234450 (מה לעשות, כשלומדים למבחן באופטימיזציה לא-לינארית כל בעיה נראית כמו בעית תכנון קמור). התוצאה לא מושלמת - כשמזפזפים בין צילום הלווין של גוגל למפה של ABMaps מקומות זהים לא נופלים בדיוק אחד על השני - אבל היא קרובה מאוד למושלמות.

כאמור, ניתן להוריד את הקוד בקישור הבא.