עבודה עם נתונים גיאו-מרחביים ב-Bigtable
בדף הזה מוסבר איך לאחסן נתונים גיאו-מרחביים ב-Bigtable ולבצע עליהם שאילתות באמצעות פונקציות גיאוגרפיות של GoogleSQL. נתונים גיאו-מרחביים כוללים ייצוגים גיאומטריים של פני השטח של כדור הארץ בצורה של נקודות, קווים ופוליגונים. אפשר לקבץ את הישויות האלה לאוספים כדי לעקוב אחרי מיקומים, מסלולים או אזורים אחרים שמעניינים אתכם.
פעולות בסיסיות
הפונקציות הייעודיות של GoogleSQL למיקום גיאוגרפי מאפשרות ל-Bigtable לבצע אופטימיזציה של ביצועי מסד הנתונים לחישובים גיאוספציאליים ולזמני שאילתות. בדוגמאות לשימוש הבסיסי, אנחנו משתמשים בטבלת tourist_points_of_interest עם קבוצת עמודות אחת בשם poi_data.
| poi_data | |||
|---|---|---|---|
| row key | name | location | |
| p1 | מגדל אייפל | POINT(2.2945 48.8584) |
כתיבת נתונים גיאוגרפיים
כדי לכתוב נתונים גיאו-מרחביים בעמודות Bigtable, צריך לספק ייצוגים של ישויות גיאוגרפיות בפורמטים GeoJSON או Well-Known Text (WKT). Bigtable שומר את נתוני הבסיס כבייטים גולמיים, כך שאפשר לספק כל שילוב של ישויות בעמודה אחת (למשל Points, LineStrings, Polygons, MultiPoints, MultiLineStrings או MultiPolygons). סוג הישות הגיאוספציאלית שאתם מספקים חשוב בזמן השאילתה, כי צריך להשתמש בפונקציית הגיאוגרפיה המתאימה כדי לפרש את הנתונים.
לדוגמה, כדי להוסיף אטרקציות לטבלה tourist_points_of_interest, אפשר להשתמש בכלי cbt CLI באופן הבא:
- עם WKT:
cbt set tourist_points_of_interest p2 poi_data:name='Louvre Museum' cbt set tourist_points_of_interest p2 poi_data:location='POINT(2.3376 48.8611)' cbt set tourist_points_of_interest p3 poi_data:name='Place Charles de Gaulle' cbt set tourist_points_of_interest p3 poi_data:location='POLYGON(2.2941 48.8733, 2.2941 48.8742, 2.2957 48.8742, 2.2958 48.8732, 2.2941 48.8733)'
- עם GeoJSON:
cbt set tourist_points_of_interest p2 poi_data:name='Louvre Museum' cbt set tourist_points_of_interest p2 poi_data:location='{"type": "Point", "coordinates": [2.3376, 48.8611]}' cbt set tourist_points_of_interest p3 poi_data:name='Place Charles de Gaulle' cbt set tourist_points_of_interest p3 poi_data:location='{"type": "Polygon", "coordinates": [[ [2.2941, 48.8733], [2.2941, 48.8742], [2.2957, 48.8742], [2.2958, 48.8732], [2.2941, 48.8733] ]] }'
שאילתת נתונים גיאוגרפיים
אפשר להריץ שאילתות בטבלה tourist_points_of_interest באמצעות GoogleSQL ב-Bigtable Studio ולסנן את התוצאות באמצעות פונקציות גיאוגרפיות.
לדוגמה, כדי למצוא את כל האטרקציות התיירותיות ברדיוס של 1,500 מטרים מכיכר טרוקדרו, אפשר להשתמש בפונקציה ST_DWITHIN:
SELECT _key, poi_data['name'], poi_data['location']
FROM points_of_interest
WHERE ST_DWITHIN(CAST(poi_data['location'] AS STRING), ST_GEOGPOINT(2.2874, 48.86322), 1500);
התוצאה תהיה דומה לתוצאה הבאה:

בעמודה location מוצג הייצוג המקורי של הנתונים שסופקו בפעולת הכתיבה, אבל Bigtable מאחסן אותם כבייטים.
בדוגמה הזו, למרות ש-Place Charles de Gaulle מוגדר כפוליגון שמתפרש על שטח גדול יותר מהמגבלה של 1,500 מטר, הוא נכלל בתוצאות השאילתה.
הסיבה לכך היא שהפונקציה ST_DWITHIN מחזירה את הערך True אם נקודה כלשהי שכלולה בישות גיאו-מרחבית נמצאת בטווח המרחק הצפוי.
שימוש מתקדם
בקטעים הבאים מוסבר איך להשתמש בפונקציות גיאוגרפיות בתרחישים מורכבים כמו ניתוח של גדרות וירטואליות. בקטע אופטימיזציה של שאילתות מוסבר איך להשתמש בתצוגות חומריות מתמשכות כדי לשפר את הביצועים.
כדי להמחיש שימושים מתקדמים בפונקציות גיאוגרפיות ב-Bigtable, נניח שאתם חוקרים שעוקבים אחרי ההתנהגות של פינגווינים קיסריים שחיים בצד הדרומי של האי סנואו היל.
הציוד שלכם מספק מאות פינגים של מיקום לכל פינגווין,
לכן אתם יוצרים את הטבלה penguin_movements כדי לאחסן אותם:
| penguin_details | |||
|---|---|---|---|
| row key | penguin_id | חותמת זמן | location |
| ping#123 | pen_01 | 2025-12-06 08:15:22+00 | POINT(-57.51 -64.42) |
| ping#124 | pen_01 | 2025-12-06 10:22:05+00 | POINT(-57.55 -64.43) |
| ping#125 | pen_01 | 2025-12-07 12:35:45+00 | POINT(-57.58 -64.41) |
| ping#126 | pen_02 | 2025-12-12 06:05:11+00 | POINT(-57.49 -64.39) |
דוגמה: איך מוצאים מי חצה את הגדר הגיאוגרפית
במהלך המחקר, אתם צופים בהתנהגות של פינגווינים באזור האכלה ספציפי. אזורים שמוגדרים באמצעות גבולות וירטואליים נקראים בדרך כלל גדרות וירטואליות. אפשר להתייחס לאזור ההאכלה כאזור מגודר וירטואלית.
אתם רוצים לדעת אם פינגווינים ביקרו באזור ההאכלה ב-3 בדצמבר 2025. כדי לענות על השאלה, משתמשים בפונקציה ST_CONTAINS, כך:
SELECT
penguin_details['penguin_id'],
penguin_details['location'],
penguin_details['timestamp']
FROM
penguin_movements
WHERE
penguin_details['timestamp'] >= '2025-12-03 00:00:00 UTC'
AND penguin_details['timestamp'] < '2025-12-04 00:00:00 UTC'
-- The feeding ground boundary is defined with a WKT POLYGON entity