יותר

באמצעות מצולע תוחם, במקום תיבת תוחם

באמצעות מצולע תוחם, במקום תיבת תוחם


יש לי קבוצה גדולה של קואורדינטות LAT / LON. עד עכשיו, כשהייתי צריך לבחור את אלה שנפלו באזור מסוים, הייתי פשוט יוצר תיבת גבולות באמצעות כמה ערכי MINx, MAXx, MINy, MAXy ומנסה להתקרב אליו ככל האפשר לאזור בו הייתי מעוניין ב.

ברצוני לדייק יותר על ידי שימוש ביותר מ -4 נקודות כמידת אזור החיפוש שלי, במקרה ספציפי זה, 14 נקודות.

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


אתה יכול להשתמש ב- Shapely לביצוע הפעולה (למשל בתוך). אתה יכול לטעון את שתי הגיאומטריות באמצעות שיטות פעולה אחת של Shapely.


ל- PostGIS יש אוסף של מפעילים יחסיים שצריכים לעשות מה שאתה רוצה.


נפח גבולות

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

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


תיבת גבולות

תיבה תוחמת (בדרך כלל מקוצרת ל- bbox) היא אזור המוגדר על ידי שני קווי אורך ושני קווי רוחב, כאשר:

  • קו רוחב הוא מספר עשרוני בין -90.0 ל -90.0.
  • קו האורך הוא מספר עשרוני בין -180.0 ל- 180.0.

בדרך כלל הם פועלים לפי הפורמט הסטנדרטי של:

לדוגמה, לונדון הגדולה מוקפת על ידי:

הקישור "נתוני ייצוא" באתר הראשי מאפשר לך לצייר תיבה, וקואורדינטות הקצוות מוצגות לך.

ב- WikiProject המכיל דף משנה של params, תוכל להשיג את תיבת התוחם באמצעות תבנית pBbox.


כשעלילנד העלו "רוחב" ו"גובה "הם מונחים מעורפלים במקצת.

הנה גישה פשוטה למציאת רוחב וגובה ה- AABB:

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

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


הקוד שלך נראה דומה להפליא לקוד awt הממשי שמשמש במצולע כדי לקבל את boundingBox. התחל עם ערכי מינימום / מקסימום קיצוניים ואז עבור משם.

לעתים קרובות אני מוצא שהאפשרות להשתמש בפונקציות min () / max () במקום אם התנאים הם גם המהירים ביותר, ולכן אני מסכים עם הקוד שלך שם.

מה שחשש לי מעט, הוא השימוש ב:

זו שיחה מעניינת, שעשויה או לא עשויה לעשות הרבה עבודה. שקול את יישומו:

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

בעיקרו של דבר, אם אתה בודק את הגבולות לעיתים קרובות ולא משנה את המצולעים, הרי שהבדיקה שלך מוגבלת די טוב. אם לא, אז אתה עושה הרבה עבודה מיותרת.

על מנת לשפר את הזמן שחלף (זמן ביצוע), בערך שני הדברים היחידים שאני יכול להמליץ ​​עליהם הם:

הקבלה המשולבת / פרימיטיבית תהיה קלה ליישום באמצעות זרמי Java 8, והתעללות בכך שנתוני המצולע הם ציבוריים.

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

האמור לעיל יהיה מהיר יותר אם בכל מקרה אחרת תצטרך לחשב את כל גבולות הפולי.

למרבה הצער, הכל תלוי במקרה השימוש שלך וביכולת שלך לריבוט רב.

אם אתה מוגבל, אז אתה יכול גם לדבוק במה שיש לך, זה מהיר, מסודר, אחרת בסדר.


תחביר

מחלקת תכונות הנקודה או המצולע שעבורה יבוצע ניתוח נקודה חמה.

מחלקת תכונות הפלט לקבלת תוצאות z- ציון, ערך p ו- Gi_Bin.

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

שיטת הצבירה בה ניתן להשתמש כדי ליצור תכונות משוקללות לניתוח מנתוני נקודת אירוע.

  • COUNT_INCIDENTS_WITHIN_FISHNET_POLYGONS - רשת מצולע רשת דייג תחפה על נתוני נקודת האירוע ומספר האירועים בתוך כל תא מצולע ייספר. אם לא מופיע מצולע תוחם בפרמטר Bounding_Polygons_Defining_Where_Incidents_Are_Possible, רק תאים עם אירוע אחד לפחות ישמשו בניתוח אחרת, כל התאים בתוך המצולעים המגבילים ינותחו.
  • COUNT_INCIDENTS_WITHIN_AGGREGATION_POLYGONS - אתה מספק מצולעי צבירה כדי להעלות את נתוני נקודת האירוע בפרמטר Polygons_For_Aggregating_Incidents_Into_Counts. האירועים בתוך כל מצולע נספרים.
  • SNAP_NEARBY_INCIDENTS_TO_CREATE_WEIGHTED_POINTS - אירועים קרובים יצטברו יחד כדי ליצור נקודה משוקללת אחת. המשקל עבור כל נקודה הוא מספר האירועים המצטברים במקום זה.

מחלקת תכונות מצולע המגדירה היכן יתכן האירוע Input_Features להתרחש.

המצולעים המשמשים לצבירת האירוע Input_Features על מנת לקבל ספירת אירועים עבור כל תכונת מצולע.

משטח צפיפות הפלט של תכונות קלט נקודה. פרמטר זה מופעל רק כאשר Input_Features הן נקודות ויש לך את הסיומת ArcGIS Analyst Spatial Analyst. משטח הפלט שנוצר יועבר למסכת ניתוח הרסטר שצוינה בהגדרות הסביבה שלך. אם לא צוינה מסיכת סריקה, שכבת הראסטר של הפלט תוצמד לגוף קמור של תכונות הקלט.


פרמטרים

מחלקת תכונות הנקודה או המצולע שעבורה יבוצע האשכול והניתוח החיצוני.

מחלקת תכונות הפלט לקבלת שדות התוצאה.

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

שיטת הצבירה לשימוש בכדי ליצור תכונות משוקללות לניתוח מנתוני נקודת אירוע.

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

מחלקת תכונות מצולע המגדירה היכן יתכן ותכונות קלט האירוע יתרחשו.

המצולעים שישמשו לצבירת תכונות קלט האירוע על מנת לקבל ספירת אירועים עבור כל תכונת מצולע.

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

  • מהיר (199 תמורות) —עם 199 תמורות, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.005 וכל שאר ערכי ה- pseudo האחרים יהיו אפילו מכפילים של ערך זה.
  • מאוזן (499 תמורות) - עם 499 תמורות, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.002 וכל שאר ה- pseudo-ערכים האחרים יהיו אפילו מכפילים של ערך זה.
  • חזק (999 תמורות) - עם תמורות 999, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.001 וכל שאר ה- pseudo-ערכים האחרים יהיו אפילו מכפילים של ערך זה.

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

ההיקף המרחבי של שכונת הניתוח. ערך זה קובע אילו תכונות מנותחות יחד על מנת להעריך אשכולות מקומיים.

מחלקת תכונות הנקודה או המצולע שעבורה יבוצע האשכול והניתוח החיצוני.

מחלקת תכונות הפלט לקבלת שדות התוצאה.

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

שיטת הצבירה בה ניתן להשתמש כדי ליצור תכונות משוקללות לניתוח מנתוני נקודת אירוע.

  • COUNT_INCIDENTS_WITHIN_FISHNET_POLYGONS - רשת מצולע רשת דייגים תחפה על נתוני נקודת האירוע ומספר האירועים בתוך כל מצולע ייספר. אם לא מופיע מצולע תוחם בפרמטר Bounding_Polygons_Defining_Where_Incidents_Are_Possible, רק תאים עם אירוע אחד לפחות ישמשו בניתוח אחרת, כל התאים בתוך המצולעים המגבילים ינותחו.
  • COUNT_INCIDENTS_WITHIN_HEXAGON_POLYGONS - רשת מצולע משושה תחפה על נתוני נקודת האירוע ומספר האירועים בתוך כל תא מצולע ייספר. אם לא מופיע מצולע תוחם בפרמטר Bounding_Polygons_Defining_Where_Incidents_Are_Possible, רק תאים עם אירוע אחד לפחות ישמשו בניתוח אחרת, כל התאים בתוך המצולעים המגבילים ינותחו.
  • COUNT_INCIDENTS_WITHIN_AGGREGATION_POLYGONS - אתה מספק מצולעי צבירה בכיסוי נתוני נקודת האירוע בפרמטר Polygons_For_Aggregating_Incidents_Into_Counts. האירועים בתוך כל מצולע נספרים.
  • SNAP_NEARBY_INCIDENTS_TO_CREATE_WEIGHTED_POINTS - אירועים קרובים נצברו יחד כדי ליצור נקודה משוקללת אחת. המשקל עבור כל נקודה הוא מספר האירועים המצטברים באותו מקום.

מחלקת תכונות מצולע המגדירה היכן יתכן האירוע Input_Features להתרחש.

המצולעים המשמשים לצבירת האירוע Input_Features על מנת לקבל ספירת אירועים עבור כל תכונת מצולע.

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

  • QUICK_199 - עם 199 תמורות, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.005 וכל שאר ה- pseudo-pseudo יהיו אפילו מכפילים של ערך זה.
  • BALANCED_499 - עם 499 תמורות, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.002 וכל שאר ה- pseudo p- ערכים יהיו אפילו מכפילים של ערך זה.
  • ROBUST_999 - עם תמורות של 999, ערך ה- pseudo הקטן ביותר האפשרי הוא 0.001 וכל שאר ה- pseudo-pseudo האחרים יהיו אפילו מכפילים של ערך זה.

גודל תאי הרשת המשמשים לצבירת Input_Features. כאשר מצטברים לרשת משושה, מרחק זה משמש כגובה לבניית מצולעי המשושה.

ההיקף המרחבי של שכונת הניתוח. ערך זה קובע אילו תכונות מנותחות יחד על מנת להעריך אשכולות מקומיים.

דוגמת קוד

סקריפט חלון פייתון הבא מדגים כיצד להשתמש בכלי OptimizedOutlierAnalysis.

התסריט העצמאי הבא של פייתון מדגים כיצד להשתמש בכלי OptimizedOutlierAnalysis.


תחביר

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

מחלקת תכונות מצולע הפלט.

מציין איזה סוג של גיאומטריה תוחמת מינימלית מייצגים מצולעי הפלט.

  • RECTANGLE_BY_AREA - המלבן של האזור הקטן ביותר שכולל תכונת קלט. זו ברירת המחדל.
  • RECTANGLE_BY_WIDTH - המלבן ברוחב הקטן ביותר שתוחם תכונת קלט.
  • CONVEX_HULL - מצולע הקמור הקטן ביותר שכולל תכונת קלט.
  • מעגל - המעגל הקטן ביותר שמקיף תכונת קלט.
  • ENVELOPE - המעטפה של תכונת קלט.
רישיון:

האפשרויות CONVEX_HULL, CIRCLE ו- ENVELOPE זמינות רק עם רישיון ArcGIS for Desktop מתקדם.

מציין כיצד יקובצו תכונות הקלט כל קבוצה תוחזק במצולע פלט אחד.

  • ללא - תכונות קלט לא יקובצו. זו ברירת המחדל. אפשרות זו אינה זמינה להזנת נקודות.
  • ALL - כל תכונות הקלט יטופלו כקבוצה אחת.
  • LIST - תכונות קלט יקובצו בהתאם לערכים המשותפים שלהם בשדה או בשדות שצוינו בפרמטר שדה הקבוצה.

השדה או השדות בתכונות הקלט שישמשו לקבוצת תכונות, כאשר LIST מוגדר כ- group_option. נדרש שדה קבוצתי אחד לפחות עבור אפשרות LIST. כל התכונות בעלות אותו ערך בשדה או בשדות שצוינו יטופלו כקבוצה.

מציין אם להוסיף את התכונות הגיאומטריות במחלקת תכונות הפלט או להשמיט אותן במחלקת תכונות הפלט.

  • NO_MBG_FIELDS —מגיש תכונות קלט כלשהן בכיתת תכונות הפלט. זו ברירת המחדל.
  • MBG_FIELDS - מוסיף את התכונות הגיאומטריות במחלקת תכונות הפלט.

חישוב תיבת התוחם של כדור הוא די טריוויאלי בהתחשב בפשטות הגיאומטריה של הכדור.

נניח שיש לנו את רדיוס הכדור המוגדר כערך סקלרי (צף או מספר שלם) $ r $, ומרכז הכדור מוגדר כווקטור $ overrightarrow c $ כך:

$ overrightarrow c = התחלx y z end $

אנו יכולים לחשב את וקטורי הקואורדינטות החבוליים $ overrightarrow $ ו- $ overrightarrow $ על ידי ביצוע הפעולות הבאות:

$ להתחיל overrightarrow & amp = התחל c_x - r c_y - r c_z - r end overrightarrow & amp = התחל c_x + r c_y + r c_z + r end סוֹף $

אם היינו מעדיפים, דרך אחרת לחשב את אותו הדבר היא להגדיר וקטור $ overrightarrow <>>> $ עבור ביצוע ההוספה הזו, שפשוט מייצגת את הקיזוז מהמרכז לפינה של תיבת התוחם:

$ text overrightarrow c = התחלx y z end טקסט overrightarrow <>>> = התחל r r r end, התחל overrightarrow & amp = overrightarrow c - overrightarrow <>>> overrightarrow & amp = overrightarrow c + overrightarrow <>>> סוף $


הפיכת מצטרפות גיאו-מרחבית לאינטראקטיבית בקנה מידה

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

עם זאת, הצטרפות, בהגדרה, יקרה. צירוף משלב את העמודות מטבלה אחת או יותר לטבלה חדשה באמצעות פרדיקט אחד או יותר להתאמת שורות. זה מלמד עבור מתכנתים לחשוב על פעולת JOIN שקולה מבחינה סמנטית ל- לולאה. בהתחשב בשאילתה הבאה, המשלבת את הרשומות מהטבלה t1 ושולחן t2 באמצעות עמודת הפרדיקט א בשולחן t1 שווה לטור ב בשולחן t2, אנחנו יכולים לכתוב פסאודוקוד ל לוּלָאָה כדלהלן:

לפעולה כזו יש מורכבות N * M, כאשר N הוא מספר הרשומות t1 ו- M הוא מספר הרשומות ב t2. עבור טבלאות קטנות, זה טריוויאלי (במיוחד על GPUs). עם זאת, עבור טבלאות גדולות או פרדיקות צירוף מורכבות, אנו חורגים במהירות את יכולת החישוב אפילו של מערכות השרת היחידות החזקות ביותר. אופטימיזציה של הצטרפות היא תחום נחקר של מחקר מסדי נתונים, וגישות ידועות רבות מקלות על בעיית "N בריבוע" המפורטת לעיל. גישה נפוצה אחת היא למנף מבנה נתוני טבלת חשיש כדי להפחית את מספר מבחני ההתאמה הנדרשים בין שתי הטבלאות. שיטה זו בונה טבלת חשיש מעל אחת הטבלאות, והלולאה מתוגברת באמצעות בדיקה לשולחן החשיש כדי להשיג את הסט הפוטנציאלי של שורות תואמות:

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

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

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

(שים לב שהצטרפות משמאל משמרת ציוצים ללא התאמה במערכי הנתונים של מיקודים, כלומר ציוץ ייכלל בצבע "NULL" אם אין לו מיקוד תואם, במקום לא נכלל)

כדי לקבוע אם ציוץ נמצא בתוך מיקוד נתון, עלינו לבדוק את נקודת המיקום של הציוץ מול כל מצולע מיקודים באופן ממצה. רוב האלגוריתמים דורשים בדיקה של כל קודקוד של מצולע המיקוד (ישנן מספר שיטות לעשות זאת אנו משתמשים בשיטת הפיתול) כנגד כל נקודה. בהנחה שיש לנו מיליון ציוצים ו -33,144 מיקודים, השוואה של כל נקודה לכל מצולע תביא ל 33 מיליארד השוואות. מכיוון שהמיקוד החציוני כולל 166 קודקודים, אנו מוסיפים אפסים נוספים עבור השוואה של 5,501,904,000,000 סה"כ (5.5 טריליון פעולות). זה לא מביא בחשבון את הפעולות הנדרשות לטעינת נתונים, בדיקת תנאי הגבול ועוד, כך שנוכל לראות בכך גבול תחתון. ל- GPU של Ampere האחרונים יש כמעט עשרה טרה-פלאפ, שמבצעת את הפעולה הנ"ל בכ -500 ms, אך אם אנו מגדילים את טבלת הציוצים ל 100M, אנו רואים זמן לחשב את העלייה ל -6 דקות. מרבית לקוחות OmniSci משתמשים בנתונים בטווח של 500 מיליון עד מיליארדים נמוכים, ורוב השאילתות ב- OmniSci מתבצעות באלפיות השנייה. לכן, עלינו להשתמש באופטימיזציה מסוימת כדי להפוך ג'וי ג'וינט לאינטראקטיבי.

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

אנו מגדירים חפיפה (תוֹאַר רִאשׁוֹן) או א חופפות ב להיות נכון אם תיבת האובייקט התוחמת א חופף את תיבת האובייקט התוחמת ב. שים לב שאולי יש שם טוב יותר למפעיל זה כ- Overlaps אנו נצמד לחפיפות להמשך מאמר זה לשם קיצור. לנקודה מסוימת אנו רואים בתיבה התוחמת להתמוטט עד לנקודה. אז אם א היא נקודה ו ב הוא אובייקט גיאו-מרחבי אחר, חפיפה מחזירה אמת אם נקודה א נמצא בתוך תיבת התוחם המקיפה את האובייקט ב. כעת נוכיח ש- ST_Contains נכון אם ורק אם חפיפה היא נכונה. נניח שיש לנו נקודה א ואובייקט גיאו-מרחבי ב ותיבה תוחמת b_box. נניח ST_Contains (ב,א) נכון (כלומר האובייקט הגיאו-מרחבי ב מכיל את הנקודה א) והניח חפיפות (ב,א) שקרי (כלומר א לא חופף ב). תיבת התוחם b_box מכיל ב לפי הגדרה. אז אם ב מכיל א, לאחר מכן א חייב להיות בתוך תיבת התוחם עבור ב. לָכֵן א חופפות ב. עם זאת, הנחנו שחפיפות (ב,א) היה שקר, אז יש לנו סתירה, ואם ST_Contains (ב,א) נכון, ואז חופפים (ב,א) חייב להיות גם נכון.

אנו יכולים להשתמש במאפיין זה כדי להחליף את הביטוי ST_Contains (ב,א) בשאילתה עם הפרדיקט הבינארי Overlaps (ב,א) AND ST_ מכיל (ב,א). לאחר מכן נבנה טבלת חשיש מעל הביטוי חפיפה (ב,א) והשתמש בטבלת hash כדי להפחית את מספר ההשוואות ב- join. לשם כך אנו זקוקים לפונקציית חשיש. שקול את התיבות התוחמות של האובייקטים הגיאו-מרחביים. אם ניקח את האיחוד של כל התיבות התוחמות, נהפוך אותו למלבן ואז מחלק את האזור הזה לפחים בודדים, כל אחד באותו גודל, נוכל ליצור פונקציה הממפה כל נקודה במרחב. א לפח. פונקציה אחת כזו מקצה מזהה שלם לכל סל, המחושב על ידי חלוקת קואורדינטות הנקודה לפי ממד הסל המקביל ולקבלת הרצפה. עקומות מילוי חלל הן אפשרות נוספת. בחרנו בפונקציית החשיש הפשוטה מכיוון שנתוני הקלט שלנו אינם ממוינים או מסודרים, ושאלות בדרך כלל מכוונות לדלי יחיד, ולא לטווח דליים. מאפייני יישוב הזיכרון של עקומות מילוי חלל הם אזור של חקירה עתידית. כדי לבנות טבלת hash לפונקציה זו, ניקח את תיבת התוחם עבור כל מצולע, נקבע את הסל (ים) שתיבת התוחמת חופפת ונכתוב מזהה עבור המצולע לכל סל.

כשמרכיבים את הכל, אנו משלבים את הביטוי החדש חפיפות (תוֹאַר רִאשׁוֹן) AND ST_ מכיל (תוֹאַר רִאשׁוֹן) עם שולחן החשיש מעל חפיפות (תוֹאַר רִאשׁוֹן). לנקודה נתונה אראשית, אנו בודקים את טבלת החשיש כדי לראות לאיזה סל נקודה שייכת באמצעות הפונקציה hash לנקודה. קראנו את רשימת מזהי המצולעים מהסל. פעולה זו מחשבת חפיפה לנקודה א וכל המצולעים ב (שימו לב שהמצב מעט חלש יותר, בכך שנקודה יכולה להיות באותו פח כמו מצולע, אך השניים לא יכלו לחפוף, אך זה מספיק לענייננו מכיוון שכל מצולע שלא בפח אינו יכול להכיל את הנקודה - - ראה איור 1). תהליך זה מגביל את המספר הכולל של ההשוואות עבור ST_ מכיל מצולעים בלבד אשר אולי מכילים את הנקודה הנתונה. אם האשפה תפוסה נמוכה, נוכל להפחית משמעותית את מספר ההשוואות הנדרש לכל נקודה. הפסאוד-קוד הבא ממחיש תהליך זה:

התחלנו בביטוי, ST_Contains (תוֹאַר רִאשׁוֹן), ושכתב את הביטוי לביטוי שווה ערך, חופף (תוֹאַר רִאשׁוֹן) AND ST_ מכיל (תוֹאַר רִאשׁוֹן). לאחר מכן נוכל להשתמש במסגרת hash join עם פונקציית hash וטבלת hash המתאימה להגבלת מרחב החיפוש של הביטוי ולשיפור הביצועים. אז איך נבחר בגדלי פחים מתאימים בבניית שולחן החשיש?

גודל טבלת Hash הוא פשרה בין גודל טבלת ה- hash למספר הרשומות בכל סל. ככל שפחות רשומות בכל סל, פחות עבודה שיש לנו לכל סל, פירוש הדבר ש- ST_ פחות מכיל פעולות בדוגמה שלנו לעיל. עם זאת, ככל שהפחים הולכים וקטנים, יותר פחים חייבים לכסות את אותו שטח, מה שמגדיל את זמן בניית שולחן החשיש וגודלו. האלגוריתם שלנו (ראה איור 2) מחפש טבלת חשיש עם תפוסת סל נמוכה, מוגבלת לגודל מרבי. אנו מבצעים פרמטרים של החיפוש מעל סף & quotbin, & quot; גודל הסל המינימלי שנאפשר בטבלת hash. המקלט מאותחל את גודל הסל על ידי איטרציה מעל כל תיבות התוחם שאנו רוצים להוסיף לטבלת החשיש שלנו ולקבוע את גודל תיבת התוחם בכל מימד אם גודל התיבה התוחם הוא פחות מסף הפח הנוכחי אך גדול מהזרם הוא גודל הפח שנבחר, אנו לוקחים זאת כגודל הפח החדש. על ידי הורדת סף גודל הפח, אנו יכולים לחפש באופן שיטתי בין גודל טבלת החשיש והן תפוסת הפח.

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

ביצענו מספר ניסויים כדי להדגים את תהליך חיפוש האלגוריתם והפשרה בין תפוסת סל לגודל טבלת חשיש. הניסויים שלמטה משתמשים בטבלה צד שמאל עם רשומות עם תיוג גיאוגרפי מממשק ה- API הציבורי של טוויטר (הטבלה & quottweets & quot). השתמשנו ב- Threadripper 2950X של AMD עם כפול GPU של NVIDIA RTX 2080. הציוצים הועמסו בגודל השבר הסטנדרטי (32 מיליון שורות לכל שבר), מפוצלים באופן שווה על פני שני המעבדים. לא הופעלו אופטימיזציות נוספות. השתמשנו בשלושה מחוזות של טבלאות מצולעים בארצות הברית (3,233 שורות עם 7,944,863 קודקודים סה"כ בכל המצולעים), מיקודים בארצות הברית (33,144 שורות עם 52,210,207 קודקודים סה"כ), וגושי מפקד בארצות הברית (220,740 שורות עם 67,581,813 קודקודים סה"כ. השאילתה הייתה צירוף שמאלי בין טבלת הציוצים לטבלת המצולעים הרלוונטית, כאשר הריצה הראשונה לא נכללה כדי למנוע את אחזור הדיסק הראשוני של הנתונים. השתמשנו במצטבר ספירה יחיד ללא מסננים בהקרנה. הנתונים עבור כל ניסוי הם באיורים שלהלן.

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

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

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

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

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

למרות שאנו בוחנים אופטימיזציות נוספות להגברת ההקבלה והביצועים של גישת החפיפה שלנו, זה כבר הראה תועלת עצומה להבאת צירופי גיאוגרפיים גדולים לרמות ביצועים אינטראקטיביות או כמעט אינטראקטיביות. על מכונה, עם 2 Nvidia RTX 3090 GPUs, חפיפות מצטרפות לביצועים מוגברים על פני הצטרפות לולאה בין 200 ל -1,200 X בדוגמאות שונות, ובמקרה הקיצוני ביותר מגדילה צירוף של ציוצים בארה"ב לקבוצות מפקד ארה"ב מ 11.3 אלף חיפושים לשנייה עם לולאה. הצטרף לחיפושים של 22.38 מיליון לשנייה עם חפיפות הצטרפות. לבסוף, אנו מאמינים כי קיימות אפשרויות מהירות נוספות. לדוגמא, ניסויים המנפים עקומות מילוי חלל על מנת להזמין ולבצע חשיש הנתונים מצביעים על הפוטנציאל להרוויח 3-4X נוספים בביצועים על ידי הגדלת היישוב המרחבי והקטנת סטיית הביצוע בשלב בדיקת ההצטרפות לחשיש, לכן הישאר מעודכן למידע נוסף החזית הזו.

נקודה בצירופי מצולע הם רק דוגמה אחת ליישום של הטכניקות שתוארו לעיל. מפעיל OVERLAPS הגנרי חל על שאילתות שונות, כולל שאילתות מרחביות וזמניות (או שילובים של השניים). In general, two broad applications emerge queries requiring an algorithm to construct the hash table and queries that dictate the construction of the hash table based on the predicate defining the OVERLAPS relationship in the query. We have implemented distance joins between geospatial points as an example of the latter type if a user requests all points within N units of each other, we can construct the hash table such that a simple search of neighboring bins is always guaranteed to return the points which might be within N units of each other. While we are in the early stages of productionizing these techniques, the point in polygon join is available in OmniSci as of version 5.6 across all product modalities, including desktop, OmniSci Free, and the Enterprise Edition.

Alex Baden is the Technical Director leading the Query Engine team at OmniSci. Prior to OmniSci, he was a graduate student at Johns Hopkins University, studying computer science and developing terabyte scale databases and visualization tools, optimized for range queries across three dimensional image datasets. He has contributed code to various open source projects across the big data landscape and has worked with organizations such as the Allen Institute for Brain Science to develop tools for the analysis of large and complex datasets. He holds a MSE in Computer Science from Johns Hopkins University and a BS in Mathematics from the University of Maryland.