שיטות מומלצות לשימוש ב-Street View Static API

ממשקי ה-API הסטטיים לאינטרנט של הפלטפורמה של מפות Google הם אוסף של ממשקי HTTP, שיוצרים תמונות להטמעה ישירות בדף האינטרנט.

שירותי האינטרנט של Google Maps Platform הם אוסף של ממשקי HTTP שמספקים נתונים גיאוגרפיים לאפליקציות המפות שלכם.

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

‫Street View Static API פועל כמו Web API סטטי, ושירות המטא-נתונים פועל כמו שירות אינטרנט. למידע נוסף על שירות המטא-נתונים, ראו מטא-נתונים של תמונות Street View.

מה זה API סטטי לאינטרנט?

ממשקי ה-API הסטטיים לאינטרנט של Google Maps Platform מאפשרים להטמיע תמונה של מפות Google בדף האינטרנט בלי צורך ב-JavaScript או בטעינת דפים דינמית. ממשקי ה-API הסטטיים לאינטרנט יוצרים תמונה על סמך פרמטרים של כתובות URL שנשלחים באמצעות בקשת HTTPS רגילה.

בקשת Street View Static API אופיינית נראית כך:

  https://www.googleapis.com/streetview/z/x/y?parameters

מה זה שירות אינטרנט?

שירותי האינטרנט של Google Maps Platform הם ממשק לבקשת נתונים של Maps API משירותים חיצוניים, ולשימוש בנתונים האלה באפליקציות של מפות Google. השירותים האלה מיועדים לשימוש בשילוב עם מפה, בהתאם להגבלות הרישיון בתנאים ובהגבלות של Google Maps Platform.

שירותי האינטרנט של Maps API משתמשים בבקשות HTTP או HTTPS לכתובות URL ספציפיות, ומעבירים פרמטרים של כתובות URL או נתוני POST בפורמט JSON כארגומנטים לשירותים. בדרך כלל, השירותים האלה מחזירים נתונים בגוף התגובה כ-JSON, כדי שהאפליקציה תוכל לנתח או לעבד אותם.

בקשת מטא-נתונים של Street View Static API נראית כך:

https://maps.googleapis.com/maps/api/streetview/parameters

גישה ל-SSL ול-TLS

חובה להשתמש ב-HTTPS בכל הבקשות לפלטפורמה של מפות Google שכוללות מפתחות API או נתוני משתמשים. יכול להיות שבקשות שנשלחות דרך HTTP ומכילות מידע רגיש יידחו.

יצירת כתובת URL תקינה

יכול להיות שאתם חושבים שכתובת URL "תקינה" היא דבר מובן מאליו, אבל זה לא בדיוק המצב. לדוגמה, כתובת URL שמזינים בסרגל הכתובות בדפדפן יכולה להכיל תווים מיוחדים (כמו "上海+中國"). הדפדפן צריך לתרגם את התווים האלה באופן פנימי לקידוד אחר לפני השליחה. באותו אופן, כל קוד שיוצר או מקבל קלט ב-UTF-8 עשוי להתייחס לכתובות URL עם תווים ב-UTF-8 כ "תקינות", אבל גם צריך לתרגם את התווים האלה לפני שליחה שלהם לשרת אינטרנט. התהליך הזה נקרא קידוד כתובת URL או קידוד באחוזים.

תווים מיוחדים

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

סיכום של תווים חוקיים בכתובות URL
הגדרהתוויםשימוש בכתובות URL
אלפאנומרי a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 מחרוזות טקסט, שימוש בסכימה (http), יציאה (8080) וכו'.
לא שמור - _ . ~ מחרוזות טקסט
בוצעה הזמנה ! * ' ( ) ; : @ & = + $ , / ? % # [ ] תווי בקרה או מחרוזות טקסט

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

  • התווים שאתם רוצים לטפל בהם לא נמצאים בקבוצה שלמעלה. לדוגמה, תווים בשפות זרות כמו 上海+中國 צריכים להיות מקודדים באמצעות התווים שלמעלה. לפי המוסכמה המקובלת, רווחים (שאסור להשתמש בהם בכתובות URL) מיוצגים לעיתים קרובות גם באמצעות התו פלוס '+'.
  • תווים שקיימים בקבוצה שלמעלה כתווים שמורים, אבל צריך להשתמש בהם באופן מילולי. לדוגמה, התו ? משמש בכתובות URL כדי לציין את תחילת מחרוזת השאילתה. אם רוצים להשתמש במחרוזת "? and the Mysterions", צריך לקודד את התו '?'.

כל התווים שצריך לקודד בקידוד URL מקודדים באמצעות התו '%' וערך הקסדצימלי של שני תווים שתואם לתו UTF-8 שלהם. לדוגמה, 上海+中國 ב-UTF-8 יותאם לקידודי התווים שמתאימים לכתובות URL באופן הבא: %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. המחרוזת ? and the Mysterians תותאם לקידודי התווים שמתאימים לכתובות URL באופן הבא: %3F+and+the+Mysterians או %3F%20and%20the%20Mysterians.

תווים נפוצים שצריך לקודד

אלה כמה תווים נפוצים שצריך לקודד:

דמות לא בטוחה ערך מקודד
רווח %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

לפעמים קשה להמיר כתובת URL שמקבלים מקלט של משתמש. לדוגמה, משתמש יכול להזין כתובת כמו "5th&Main St."‎ באופן כללי, צריך לבנות את כתובת ה-URL מהחלקים שלה, ולהתייחס לכל קלט של משתמש כתווים מילוליים.

בנוסף, כתובות ה-URL מוגבלות ל-16,384 תווים בכל ממשקי ה-API הסטטיים לאינטרנט ובכל שירותי האינטרנט של Google Maps Platform. ברוב השירותים, מגבלת התווים הזו לא תהיה רלוונטית. עם זאת, שימו לב שלשירותים מסוימים יש כמה פרמטרים שיכולים להוביל לכתובות URL ארוכות.

שימוש הוגן ב-Google APIs

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

השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

במקרים נדירים, יכול להיות שתהיה בעיה בבקשה. יכול להיות שתקבלו קוד תגובת HTTP מסוג 4xx או 5xx, או שחיבור ה-TCP ייכשל בין הלקוח לבין השרת של Google. בדרך כלל כדאי לנסות שוב לשלוח את הבקשה, כי יכול להיות שהבקשה הבאה תצליח גם אם הבקשה המקורית נכשלה. עם זאת, חשוב לא לשלוח בקשות חוזרות ונשנות לשרתים של Google. הלולאה הזו יכולה להעמיס על הרשת בין הלקוח לבין Google, ולגרום לבעיות אצל הרבה גורמים.

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

לדוגמה, נניח שאפליקציה שולחת את הבקשה הזו ל-Time Zone API:

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY

בדוגמה הבאה ב-Python אפשר לראות איך לשלוח את הבקשה עם השהיה מעריכית לפני ניסיון חוזר (exponential backoff):

import json
import time
import urllib.error
import urllib.parse
import urllib.request

# The maps_key defined in the following code isn't a valid Google Maps API key.
# You need to get your own API key.
# See https://developers.google.com/maps/documentation/timezone/get-api-key
API_KEY = "YOUR_KEY_HERE"
TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json"


def timezone(lat, lng, timestamp):

    # Join the parts of the URL together into one string.
    params = urllib.parse.urlencode(
        {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,}
    )
    url = f"{TIMEZONE_BASE_URL}?{params}"

    current_delay = 0.1  # Set the initial retry delay to 100ms.
    max_delay = 5  # Set the maximum retry delay to 5 seconds.

    while True:
        try:
            # Get the API response.
            response = urllib.request.urlopen(url)
        except urllib.error.URLError:
            pass  # Fall through to the retry loop.
        else:
            # If the request didn't produce an IOError, parse the result.
            result = json.load(response)

            if result["status"] == "OK":
                return result["timeZoneId"]
            elif result["status"] != "UNKNOWN_ERROR":
                # Many API errors can't be fixed by a retry, such as
                # INVALID_REQUEST or ZERO_RESULTS. Don't retry these requests.
                raise Exception(result["error_message"])

        if current_delay > max_delay:
            raise Exception("Too many retry attempts.")

        print("Waiting", current_delay, "seconds before retrying.")

        time.sleep(current_delay)
        current_delay *= 2  # Increase the delay on each retry.


if __name__ == "__main__":
    tz = timezone(39.6034810, -119.6822510, 1331161200)
    print(f"Timezone: {tz}")

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

בקשות מסונכרנות

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

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

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

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

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

עיבוד התשובות

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

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

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

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