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

גוגל השיקה לא מזמן API חדש שמאפשר אוטומציה בעבודה עם גוגל דוקס.
ה-API החדש מתממשק אל מול שפות מגוונות כמו Java, PHP, Go, Node.js, פיית׳ון ועוד, כך שניתן להתממשק בקלות אל מול שירותים קיימים שאתם משתמשים בהם. 

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

על מנת להתחיל לעבוד עם ה API יש לבצע כמה פעולות מקדימות (כדאי להעזר במדריך של גוגל)

  1. צריך לאפשר את העבודה עם ה API ולהוריד קובץ json עם הגדרות חיבור (יש הדרכה במדריך בקישור למעלה)
  2. התקנת סיפריית פייתון לעבודה מול ה API :
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

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

לצורך הדוגמה יש לי גליון עם שמות של תחנות רכבת בלונדון ואני רוצה לבדוק מול ה API של TFL את מיקום התחנה ובאיזה איזור היא נמצאת (לצורך הדוגמה נעשה שימוש ב API שלא דורש שם משתמש וכו')

לכל גליון יש מזהה יחודי שנמצא בכתובת ה URL של הגליון ובו נשתמש כדי לגשת לגליון.

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

ייבוא ספריות רלוונטיות ל QGIS

from PyQt5.QtCore import QCoreApplication,QVariant
from qgis.core import (QgsProcessing,
QgsFeatureSink,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsFields,QgsField,QgsWkbTypes, QgsGeometry, QgsPointXY,QgsFeature,QgsProcessingParameterExtent,QgsCoordinateReferenceSystem)

ייבוא ספריות רלוונטיות ל Google API נצטרך כנראה להתקין את הספריות יש במדריך הסבר איך להתקין)

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import requests
import ast

הגדרת פונקציה לתשאול ה API של TFL

def zones(s):
url = f"https://api.tfl.gov.uk/StopPoint/Search/{s}"
querystring = {"modesFilter":"","oysterOnly":"false","maxResults":"25"}
headers = {'cache-control': "no-cache"}
response = requests.request("GET", url, headers=headers, params=querystring)
ts=response.text
try:
zone=ast.literal_eval(ts)
return zone
except:
return ""

נגדיר את שאר ההגדרות של Python Processing שם של הסקריפט , קבוצה, טקסט עזרה, משתנים וכו' (לפי המדריך שצרפתי למעלה)

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

def processAlgorithm(self, parameters, context, feedback):

נגדיר את השדות בשכבה

fields = QgsFields() fields.append(QgsField('stopName', QVariant.String, ", 50, )) fields.append(QgsField('Zone', QVariant.String, ", 50, ))

נגדיר את השכבה הזמנית

(sink, dest_id) = self.parameterAsSink(
parameters,
self.OUTPUT,
context,
fields,
QgsWkbTypes.Point,
crs=QgsCoordinateReferenceSystem("EPSG:4326"))

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

SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
spreadsheet_id = '1BJpG6C0zt5_sWJ….'
range_name = 'Sheet1!A2:H' with open("token.pickle", 'rb') as token:
creds = pickle.load(token)
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()

נקרא את הנתונים בגליון

result = sheet.values().get(spreadsheetId=spreadsheet_id,range=range_name).execute()
values = result.get('values', [])

ונתחיל לרוץ בלולאה על כל אחת מהתחנות בגליון, נשלח בקשה לAPI של TFL ואת התוצאה נצרף לשכבה

for v in values:
stop=zones(v[0])
lat=stop['matches'][0]["lat"]
lon=stop['matches'][0]["lon"]
f = QgsFeature()
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(lon,lat)))
f.setAttributes([v[0],stop['matches'][0]['zone']])
sink.addFeature(f, QgsFeatureSink.FastInsert)

return {self.OUTPUT: dest_id}

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

ניתן כמובן להרחיב את העקרון לאינסוף שימושים בהצלחה!

אולי גם זה יעניין אותך?

השארת תגובה