Google Maps Platform (JavaScript) की मदद से, BigQuery में जगह की जानकारी का डेटा देखना और क्वेरी करना

1. खास जानकारी

Maps किसी डेटासेट में पैटर्न को विज़ुअलाइज़ करते समय बहुत असरदार टूल साबित हो सकता है जो किसी तरह से जगह से जुड़े होते हैं. यह संबंध किसी जगह का नाम, कोई खास अक्षांश और देशांतर वैल्यू या किसी ऐसे इलाके का नाम हो सकता है जिसकी कोई खास सीमा हो. जैसे: जनगणना क्षेत्र या पिन कोड.

इन डेटासेट के बहुत बड़े हो जाने पर, पारंपरिक टूल का इस्तेमाल करके उन पर क्वेरी करना और उन्हें विज़ुअलाइज़ करना मुश्किल हो सकता है. डेटा बनाने के लिए Google BigQuery का इस्तेमाल करके और Google Maps API से क्वेरी बनाने और आउटपुट को विज़ुअलाइज़ करने के लिए, आप बहुत कम सेट अप या कोडिंग की मदद से अपने डेटा में भौगोलिक पैटर्न तेज़ी से एक्सप्लोर कर सकते हैं. इसके अलावा, आपको बहुत बड़े डेटासेट सेव करने के लिए किसी सिस्टम को मैनेज करने की भी ज़रूरत नहीं होगी.

आप क्या बनाएंगे #39;

इस कोडलैब में आप कुछ क्वेरी लिखेंगे और चलाएंगे. इनमें, BigQuery का इस्तेमाल करके, बड़े पैमाने पर सार्वजनिक डेटासेट में जगह के हिसाब से अहम जानकारी देने के तरीके के बारे में बताया जाएगा. आप #39;Google Maps Platform API एपीआई का इस्तेमाल करके मैप लोड करने वाला वेब पेज भी बनाएंगे. इसके बाद, JavaScript के लिए Google API क्लाइंट लाइब्रेरी और BigQuery API का इस्तेमाल करके, बड़े पैमाने पर इस्तेमाल किए गए उन डेटासेट के लिए जगह की जानकारी से जुड़ी क्वेरी चलाएंगे.

आप इन चीज़ों के बारे में जानेंगे

  • SQL क्वेरी, उपयोगकर्ता के तय किए गए फ़ंक्शन और BigQuery API का इस्तेमाल करके, BigQuery की मदद से पेटा-स्केल की जगह से जुड़े लोकेशन डेटासेट की क्वेरी कुछ ही सेकंड में कैसे करें
  • किसी Google पेज को वेब पेज में जोड़ने और उस पर आकार बनाने में उपयोगकर्ताओं को चालू करने के लिए, Google Maps Platform का इस्तेमाल कैसे करें
  • Google Maps पर बड़े डेटासेट की क्वेरी को विज़ुअलाइज़ करने का तरीका, जैसा कि नीचे दी गई इमेज में दिखाया गया है. यह एंपायर स्टेट बिल्डिंग के आस-पास के ब्लॉक से शुरू हुए सफ़र से जुड़ी, 2016 में टैक्सी ड्रॉप की लोकेशन का सघनता दिखाता है.

09-05-2017 को सुबह 11:12 बजे स्क्रीन शॉट की सुविधा

आपको इनकी ज़रूरत होगी

  • एचटीएमएल, सीएसएस, JavaScript, SQL, और Chrome DevTools की बुनियादी जानकारी
  • एक आधुनिक वेब ब्राउज़र, जैसे कि Chrome, Firefox, Safari या Edge के नए वर्शन.
  • आपकी पसंद का टेक्स्ट एडिटर या आईडीई

टेक्नोलॉजी

BigQuery

BigQuery, बहुत बड़े डेटासेट के लिए, Google और #39; की डेटा ऐनलिटिक्स सेवा है. इसमें RESTful API मौजूद है और यह SQL में लिखी गई क्वेरी के साथ काम करती है. अगर आपके पास अक्षांश और देशांतर की वैल्यू वाला डेटा है, तो उसका इस्तेमाल जगह के हिसाब से क्वेरी करने के लिए किया जा सकता है. इसका फ़ायदा यह है कि आप कोई भी सर्वर या डेटाबेस इन्फ़्रास्ट्रक्चर मैनेज किए बिना, पैटर्न देखने के लिए बहुत बड़े डेटासेट देख सकते हैं. आप कुछ ही सेकंड में अपने सवालों के जवाब पा सकते हैं. इससे कोई फ़र्क़ नहीं पड़ता है कि BigQuery' की क्षमता बढ़ाने और मैनेज किए जाने वाले इन्फ़्रास्ट्रक्चर की मदद से आपकी टेबल कितनी बड़ी हो गई हैं.

Google Maps Platform

Google Maps Platform, Google के मैप, जगह, और रास्ते के डेटा का प्रोग्रामैटिक ऐक्सेस देता है. फ़िलहाल, 20 लाख से ज़्यादा वेबसाइटें और ऐप्लिकेशन अपने उपयोगकर्ताओं को एम्बेड किए गए मैप और जगह के हिसाब से क्वेरी उपलब्ध कराने के लिए इसका इस्तेमाल करते हैं.

Google Maps Platform JavaScript API ड्रॉइंग लेयर की मदद से आप मैप पर आकार बना सकते हैं. इन्हें BigQuery टेबल के लिए क्वेरी चलाने के लिए, इनपुट में बदला जा सकता है. इन टेबल में कॉलम में अक्षांश और देशांतर के मान सेव होते हैं.

शुरू करने के लिए, आपको Google Cloud Platform प्रोजेक्ट की ज़रूरत होगी जिसमें BigQuery और Maps एपीआई चालू हों.

2. तैयारी

Google खाता

अगर आपके पास पहले से कोई Google खाता (Gmail या Google Apps) नहीं है, तो आपको एक खाता बनाना होगा.

प्रोजेक्ट बनाना

Google Cloud Platform Console (console.cloud.google.com) में साइन इन करें और एक नया प्रोजेक्ट बनाएं. आपकी स्क्रीन के सबसे ऊपर, प्रोजेक्ट ड्रॉप-डाउन मेन्यू दिखेगा:

f2a353c3301dc649.png

इस प्रोजेक्ट के ड्रॉप-डाउन मेन्यू पर क्लिक करने के बाद, आपको एक मेन्यू आइटम मिलेगा. इसकी मदद से आप नया प्रोजेक्ट बना सकते हैं:

56a42dfa7ac27a35.png

"कोटेशन" नाम वाले बॉक्स में, अपने नए प्रोजेक्ट के लिए कोई नाम डालें (उदाहरण के लिए, "BigQuery कोडलैब":

कोडलैब - प्रोजेक्ट बनाना (1).png

आपके लिए एक प्रोजेक्ट आईडी जनरेट हो जाएगा. प्रोजेक्ट आईडी, Google Cloud के सभी प्रोजेक्ट का एक यूनीक नाम होता है. अपना प्रोजेक्ट आईडी याद रखें, क्योंकि आप इसका इस्तेमाल बाद में करेंगे. ऊपर दिया गया नाम पहले ही ले लिया गया है और यह आपके लिए काम नहीं करेगा. जहां भी आपको इस कोडलैब में अपना_PROJECT_ID दिखे, वहां अपना प्रोजेक्ट आईडी डालें.

बिलिंग चालू करें

BigQuery के लिए साइन अप करने के लिए, पिछले चरण में चुने गए या बनाए गए प्रोजेक्ट का इस्तेमाल करें. इस प्रोजेक्ट के लिए बिलिंग चालू होनी चाहिए. बिलिंग की सुविधा चालू होने के बाद, आप BigQuery API चालू कर सकते हैं.

आप बिलिंग कैसे चालू करते हैं, यह इस बात पर निर्भर करता है कि आप नया प्रोजेक्ट बना रहे हैं या किसी मौजूदा प्रोजेक्ट के लिए बिलिंग की सुविधा फिर से चालू कर रहे हैं.

Google, आपको Google Cloud Platform के 300 डॉलर तक के इस्तेमाल के लिए 12 महीने तक मुफ़्त में आज़माने की सुविधा देता है. इस कोडलैब का इस्तेमाल आप इस कोडलैब के लिए कर सकते हैं. ज़्यादा जानकारी के लिए, https://cloud.google.com/free/ पर जाएं.

नए प्रोजेक्ट

जब आप कोई नया प्रोजेक्ट बनाते हैं, तो आपको यह चुनने के लिए कहा जाता है कि आप अपने किन बिलिंग खातों को प्रोजेक्ट से लिंक करना चाहते हैं. अगर आपके पास सिर्फ़ एक बिलिंग खाता है, तो वह खाता अपने-आप आपके प्रोजेक्ट से लिंक हो जाता है.

अगर आपके पास बिलिंग खाता नहीं है, तो आपको एक Google खाता बनाना होगा. साथ ही, Google Cloud Platform की कई सुविधाओं का इस्तेमाल करने से पहले, अपने प्रोजेक्ट के लिए बिलिंग की सुविधा चालू करनी होगी. नया बिलिंग खाता बनाने और अपने प्रोजेक्ट के लिए बिलिंग चालू करने के लिए, नया बिलिंग खाता बनाएं में दिए गए निर्देशों का पालन करें.

मौजूदा प्रोजेक्ट

अगर आपके पास कोई ऐसा प्रोजेक्ट है जिसके लिए बिलिंग को कुछ समय के लिए बंद किया गया है, तो आप बिलिंग को फिर से चालू कर सकते हैं:

  1. Cloud Platform कंसोल पर जाएं.
  2. प्रोजेक्ट सूची से वह प्रोजेक्ट चुनें जिसके लिए आप बिलिंग की सुविधा फिर से चालू करना चाहते हैं.
  3. कंसोल के बाईं ओर मौजूद मेन्यू खोलें और बिलिंग बिलिंग चुनें. आपको बिलिंग खाता चुनने के लिए कहा जाता है.
  4. खाता सेट करें पर क्लिक करें.

नया बिलिंग खाता बनाएं

नया बिलिंग खाता बनाने के लिए:

  1. Cloud Platform कंसोल पर जाएं और साइन इन करें या अगर आपके पास पहले से कोई खाता नहीं है, तो साइन अप करें.
  2. कंसोल के बाईं ओर मौजूद मेन्यू खोलें और बिलिंग बिलिंग चुनें
  3. नया बिलिंग खाता बटन पर क्लिक करें. (ध्यान दें कि अगर यह आपका पहला बिलिंग खाता नहीं है, तो पहले आपको पेज के सबसे ऊपर मौजूद अपने मौजूदा बिलिंग खाते के नाम पर क्लिक करके, और फिर बिलिंग खातों को मैनेज करें पर क्लिक करके बिलिंग खाता सूची खोलनी होगी.)
  4. बिलिंग खाते का नाम डालें और अपनी बिलिंग जानकारी डालें. आपको जो विकल्प दिखेंगे वे आपके बिलिंग पते के लिए चुने गए देश के हिसाब से तय होंगे. ध्यान रखें कि अमेरिका के खातों के लिए, खाता बनने के बाद टैक्स की स्थिति नहीं बदली जा सकती.
  5. बिलिंग सबमिट करें और चालू करें पर क्लिक करें.

डिफ़ॉल्ट रूप से, बिलिंग खाता बनाने वाला व्यक्ति, खाते का बिलिंग एडमिन होता है.

बैंक खातों की पुष्टि करने और पैसे चुकाने के दूसरे तरीके जोड़ने के बारे में जानकारी के लिए, पैसे चुकाने का तरीका जोड़ना, हटाना या अपडेट करना देखें.

BigQuery API चालू करना

अपने प्रोजेक्ट में BigQuery API चालू करने के लिए, कंसोल में BigQuery API पेज मार्केटप्लेस पर जाएं और नीले रंग के “चालू करें #39; बटन पर क्लिक करें.

3. BigQuery में जगह की जानकारी का डेटा क्वेरी करना

BigQuery में अक्षांश, देशांतर वैल्यू के तौर पर सेव की गई जगह की जानकारी के डेटा के बारे में क्वेरी करने के तीन तरीके हैं.

  • आयता सवालों में: क्वेरी के तौर पर पसंद का इलाका बताएं, जो कम से कम और ज़्यादा से ज़्यादा अक्षांश और देशांतर रेंज के अंदर सभी पंक्तियां चुनता है.
  • दायरे की क्वेरी: हेवरसिन फ़ॉर्मूला और गणित के फ़ंक्शन का इस्तेमाल करके, पृथ्वी के आकार का मॉडल बनाने के लिए, पॉइंट के आस-पास सर्कल का हिसाब लगाकर दिलचस्पी का इलाका बताएं.
  • पॉलीगॉन क्वेरी: पसंद के मुताबिक आकार तय करें और पॉइंट-इन-पॉलीगॉन लॉजिक को दिखाने के लिए उपयोगकर्ता परिभाषित फ़ंक्शन का इस्तेमाल करें, ताकि जांच की जा सके कि हर पंक्ति और #39; अक्षांश और देशांतर आकार के अंदर हैं या नहीं.

शुरू करने के लिए, Google Cloud Platform कंसोल के बिग क्वेरी सेक्शन में क्वेरी एडिटर का इस्तेमाल करके NYC टैक्सी डेटा के ख़िलाफ़ इन क्वेरी को चलाएं.

स्टैंडर्ड एसक्यूएल बनाम लेगसी एसक्यूएल

BigQuery, SQL के दो वर्शन के साथ काम करता है: लेगसी एसक्यूएल और स्टैंडर्ड एसक्यूएल. बाद वाला वर्शन 2011 का एएनएसआई स्टैंडर्ड है. इस ट्यूटोरियल के उद्देश्यों के लिए, हम स्टैंडर्ड एसक्यूएल का इस्तेमाल करेंगे, क्योंकि इसमें स्टैंडर्ड का बेहतर तरीके से पालन किया जाता है.

अगर आप BigQuery एडिटर में लेगसी एसक्यूएल लागू करना चाहते हैं, तो आप यह तरीका अपना सकते हैं:

  1. #ज़्यादा' बटन पर क्लिक करें
  2. ड्रॉपडाउन मेन्यू से, "क्वेरी की सेटिंग' चुनें
  3. {0}SQL बोली' के अंतर्गत, "लेगसी' रेडियो बटन चुनें
  4. 'सेव करें#39' बटन पर क्लिक करें

आयत क्वेरी

आयताकार क्वेरी को BigQuery में बनाना बहुत आसान है. आपको बस एक WHERE क्लॉज़ जोड़ना होगा, जो उन नतीजों को सीमित करता हो जो अक्षांश और देशांतर के लिए कम से कम और ज़्यादा से ज़्यादा वैल्यू के बीच मौजूद होते हैं.

BigQuery कंसोल में नीचे दिया गया उदाहरण आज़माएं. यह उन आयताकार इलाके में राइड के लिए औसत यात्रा के कुछ आंकड़ों के लिए क्वेरी करती है जिनमें मिडटाउन और लोअर मैनहैटन शामिल हैं. आप दो जगहों पर कोशिश कर सकते हैं. JFK हवाई अड्डे पर शुरू होने वाली राइड पर क्वेरी चलाने के लिए, दूसरे WHERE क्लॉज़ को टिप्पणी से हटाएं.

SELECT 
ROUND(AVG(tip_amount),2) as avg_tip, 
ROUND(AVG(fare_amount),2) as avg_fare, 
ROUND(AVG(trip_distance),2) as avg_distance, 
ROUND(AVG(tip_proportion),2) as avg_tip_pc, 
ROUND(AVG(fare_per_mile),2) as avg_fare_mile FROM

(SELECT 

pickup_latitude, pickup_longitude, tip_amount, fare_amount, trip_distance, (tip_amount / fare_amount)*100.0 as tip_proportion, fare_amount / trip_distance as fare_per_mile

FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`

WHERE trip_distance > 0.01 AND fare_amount <100 AND payment_type = "1" AND fare_amount > 0
)

--Manhattan
WHERE pickup_latitude < 40.7679 AND pickup_latitude > 40.7000 AND pickup_longitude < -73.97 and pickup_longitude > -74.01

--JFK
--WHERE pickup_latitude < 40.654626 AND pickup_latitude > 40.639547 AND pickup_longitude < -73.771497 and pickup_longitude > -73.793755

दो क्वेरी के नतीजों से पता चलता है कि दोनों जगहों से यात्रा के लिए औसत दूरी, किराये, और पिक अप के बीच का अंतर काफ़ी ज़्यादा है.

मैनहैटन

avg_Tip

avg_fare

avg_distance

avg_Tip_pc

avg_फ़ेयर_मील

2.52

12.03

9.97

22.39

5.97

JFK

avg_Tip

avg_fare

avg_distance

avg_Tip_pc

avg_फ़ेयर_मील

9.22

48.49

41.19

22.48

4.36

दायरे की क्वेरी

अगर आप गणित के बारे में कुछ जानते हैं, तो SQL में दायरे वाली क्वेरी भी आसानी से बनाई जा सकती हैं. BigQuery's के लेगसी एसक्यूएल कागणित का फ़ंक्शन आप हैवरसिन फ़ॉर्मूला का इस्तेमाल करके SQL क्वेरी बना सकते हैं. यह फ़ॉर्मूला पृथ्वी पर मौजूद गोल आकार वाली जगह या गोल आकार वाली कैप का अनुमान लगाता है.

यहां एक सर्कल क्वेरी के लिए BigQuery SQL का उदाहरण दिया गया है, जिसका केंद्र 40.73943, -73.99585 है, जिसकी त्रिज्या 0.1 कि॰मी॰ है.

यह एक डिग्री दिखाने वाली दूरी का अनुमान लगाने के लिए, 111.045 किलोमीटर के स्थिर मान का इस्तेमाल करता है.

यह http://www.plumislandmedia.net/mysql/evenrsine-mysql-roundest-loc/ पर मिले उदाहरण के आधार पर है:

SELECT pickup_latitude, pickup_longitude, 
    (111.045 * DEGREES( 
      ACOS( 
        COS( RADIANS(40.73943) ) * 
        COS( RADIANS( pickup_latitude ) ) * 
        COS( 
          RADIANS( -73.99585 ) - 
          RADIANS( pickup_longitude ) 
        ) + 
        SIN( RADIANS(40.73943) ) * 
        SIN( RADIANS( pickup_latitude ) ) 
      ) 
     ) 
    ) AS distance FROM `project.dataset.tableName` 
    HAVING distance < 0.1 

हेवर्सिन फ़ॉर्मूला के लिए एसक्यूएल मुश्किल लगता है, लेकिन आपको BigQuery के लिए अपने सर्कल सेंटर कोऑर्डिनेट, त्रिज्या और प्रोजेक्ट, डेटासेट और टेबल नामों को प्लग इन करना होगा.

यहां एक उदाहरण क्वेरी दी गई है जिसमें एंपायर स्टेट बिल्डिंग से करीब 100 मीटर के दायरे में पिक अप के लिए, यात्रा के कुछ औसत आंकड़े का हिसाब लगाया जाता है. नतीजे देखने के लिए, इसे कॉपी करें और BigQuery के वेब कंसोल में चिपकाएं. ब्रॉंक्स में जगह जैसे दूसरे इलाकों के साथ तुलना करने के लिए, अक्षांश और देशांतर बदलें.

#standardSQL
CREATE TEMPORARY FUNCTION Degrees(radians FLOAT64) RETURNS FLOAT64 AS
(
  (radians*180)/(22/7)
);

CREATE TEMPORARY FUNCTION Radians(degrees FLOAT64) AS (
  (degrees*(22/7))/180
);

CREATE TEMPORARY FUNCTION DistanceKm(lat FLOAT64, lon FLOAT64, lat1 FLOAT64, lon1 FLOAT64) AS (
     Degrees( 
      ACOS( 
        COS( Radians(lat1) ) * 
        COS( Radians(lat) ) *  
        COS( Radians(lon1 ) -  
        Radians( lon ) ) +  
        SIN( Radians(lat1) ) *  
        SIN( Radians( lat ) ) 
        ) 
    ) * 111.045
);

SELECT 

ROUND(AVG(tip_amount),2) as avg_tip,
ROUND(AVG(fare_amount),2) as avg_fare,
ROUND(AVG(trip_distance),2) as avg_distance,
ROUND(AVG(tip_proportion), 2) as avg_tip_pc,
ROUND(AVG(fare_per_mile),2) as avg_fare_mile

FROM

-- EMPIRE STATE BLDG 40.748459, -73.985731
-- BRONX 40.895597, -73.856085

(SELECT pickup_latitude, pickup_longitude, tip_amount, fare_amount, trip_distance, tip_amount/fare_amount*100 as tip_proportion, fare_amount / trip_distance as fare_per_mile, DistanceKm(pickup_latitude, pickup_longitude, 40.748459, -73.985731)


FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`

WHERE 
  DistanceKm(pickup_latitude, pickup_longitude, 40.748459, -73.985731) < 0.1
  AND fare_amount > 0 and trip_distance > 0
  )
WHERE fare_amount < 100

क्वेरी के नतीजे नीचे दिए गए हैं. यह देखा जा सकता है कि औसत सलाह, किराये, यात्रा की दूरी, किराये के सुझाव के अनुपात के हिसाब से, और मील प्रति मील के औसत किराया में बड़े अंतर हैं.

साम्राज्य स्टेट बिल्डिंग:

avg_Tip

avg_fare

avg_distance

avg_Tip_pc

avg_फ़ेयर_मील

1.17

11.8

45.28

10.53

6.42

धर्मशाला स्टेडियम

avg_Tip

avg_fare

avg_distance

avg_Tip_pc

avg_फ़ेयर_मील

0.52

17.63

4.75

4.74

10.9

पॉलीगॉन क्वेरी

SQL, आयतों और सर्कल के अलावा, किसी दूसरे साइज़ का इस्तेमाल करके, क्वेरी करने की सुविधा नहीं देता. BigQuery में कोई नेटिव ज्यामिति डेटा टाइप या स्थानीय इंडेक्स नहीं होता है. इसलिए, पॉलीगॉन के आकार का इस्तेमाल करके क्वेरी चलाने के लिए, आपको SQL की आसान क्वेरी के लिए अलग तरीके की ज़रूरत होती है. JavaScript में एक ज्यामिति फ़ंक्शन को परिभाषित करना और उसे BigQuery में उपयोगकर्ता परिभाषित फ़ंक्शन (UDF) के रूप में निष्पादित करना एक तरीका है.

कई ज्यामिति कार्रवाइयों को JavaScript में लिखा जा सकता है, ताकि अक्षांश और देशांतर वैल्यू वाली BigQuery टेबल के लिए एक कार्रवाई करना और उसे पूरा करना आसान हो. आपको कस्टम पॉलीगॉन, UDF के ज़रिए पास करना होगा और हर लाइन के लिए टेस्ट करना होगा. इससे सिर्फ़ वे लाइनें दिखेंगी जहां पॉलीगॉन के अंदर अक्षांश और देशांतर आएंगे. BigQuery रेफ़रंस में, UDF के बारे में ज़्यादा जानें.

पॉइंट इन पॉलीगॉन एल्गोरिदम

JavaScript में कोई पॉइंट, पॉलीगॉन में आता है या नहीं, इसका हिसाब लगाने के कई तरीके हैं. यहां एक सबसे मशहूर इंप्लीमेंटेशन का C है जो कि रे-ट्रेसिंग एल्गोरिदम का इस्तेमाल करता है. इससे यह पता चलता है कि कोई पॉइंट पॉलीगॉन के अंदर है या बाहर. साथ ही, यह भी पता चलता है कि अनगिनत लंबी लाइन आकार की सीमा से कितनी बार पार होती है. इसमें कोड की कुछ ही लाइनों की ज़रूरत होती है:

function pointInPoly(nvert, vertx, verty, testx, testy){
  var i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
                (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
      c = !c;
  }
  return c;
}

JavaScript पर पोर्ट करना

इस एल्गोरिदम का JavaScript वर्शन कुछ ऐसा दिखता है:

/* This function includes a port of C code to calculate point in polygon
* see http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html for license
*/

function pointInPoly(polygon, point){
    // Convert a JSON poly into two arrays and a vertex count.
    let vertx = [],
        verty = [],
        nvert = 0,
        testx = point[0],
        testy = point[1];
    for (let coord of polygon){
      vertx[nvert] = coord[0];
      verty[nvert] = coord[1];
      nvert ++;
    }

        
    // The rest of this function is the ported implementation.
    for (let i = 0, let j = nvert - 1; i < nvert; j = i++) {
      if ( ((verty[i] > testy) != (verty[j] > testy)) &&
         (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]) )
        c = !c;
    }
    return c;
}

BigQuery में स्टैंडर्ड एसक्यूएल का इस्तेमाल करते समय, यूडीएफ़ तरीके के लिए सिर्फ़ एक स्टेटमेंट की ज़रूरत होती है, लेकिन यूडीएफ़ को स्टेटमेंट में एक अस्थायी फ़ंक्शन के तौर पर परिभाषित किया जाना चाहिए. यहां एक उदाहरण दिया गया है. नीचे SQL क्वेरी को क्वेरी एडिटर विंडो में चिपकाएं.

CREATE TEMPORARY FUNCTION pointInPolygon(latitude FLOAT64, longitude FLOAT64)
RETURNS BOOL LANGUAGE js AS """
  let polygon=[[-73.98925602436066,40.743249676056955],[-73.98836016654968,40.74280666503313],[-73.98915946483612,40.741676770346295],[-73.98967981338501,40.74191656974406]];

  let vertx = [],
    verty = [],
    nvert = 0,
    testx = longitude,
    testy = latitude,
    c = false,
    j = nvert - 1;

  for (let coord of polygon){
    vertx[nvert] = coord[0];
    verty[nvert] = coord[1];
    nvert ++;
  }

  // The rest of this function is the ported implementation.
  for (let i = 0; i < nvert; j = i++) {
    if ( ((verty[i] > testy) != (verty[j] > testy)) &&
 (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]) ) {
      c = !c;
    }
  }

  return c;
""";

SELECT pickup_latitude, pickup_longitude, dropoff_latitude, dropoff_longitude, pickup_datetime
FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2016`
WHERE pointInPolygon(pickup_latitude, pickup_longitude) = TRUE
AND (pickup_datetime BETWEEN CAST("2016-01-01 00:00:01" AS DATETIME) AND CAST("2016-02-28 23:59:59" AS DATETIME))
LIMIT 1000

बधाई हो!

अब आपने BigQuery का इस्तेमाल करके तीन तरह की स्थान-संबंधी क्वेरी चलाई हैं. जैसा कि आपने देखा है कि जगह की जानकारी से, इस डेटासेट के लिए क्वेरी के नतीजे के डेटा में बड़ा अंतर आता है. हालांकि, जब तक आप यह अनुमान नहीं लगा पाते कि आपकी क्वेरी कहां चलाएं, तब तक आप SQL क्वेरी का इस्तेमाल करके, किसी खास जगह के हिसाब से पैटर्न पता नहीं लगा सकते.

अगर हम सिर्फ़ मैप पर ही डेटा देख सकें और अपनी पसंद के इलाके तय करके डेटा एक्सप्लोर कर सकें! Google Maps API की मदद से आप ऐसा कर सकते हैं. सबसे पहले, आपको मैप एपीआई को चालू करना होगा, अपने लोकल मशीन पर चलने वाले एक आसान वेब पेज को सेट अप करना होगा, और अपने वेब पेज से क्वेरी भेजने के लिए BigQuery API का इस्तेमाल करना शुरू करना होगा.

4. Google Maps API के साथ काम करना

कुछ सरल स्थान-संबंधी क्वेरी चलाकर, अगला चरण पैटर्न को देखने के लिए आउटपुट को विज़ुअलाइज़ करना है. ऐसा करने के लिए, आप Maps एपीआई को चालू करेंगे. ऐसा वेब पेज बनाएंगे जो मैप से BigQuery को क्वेरी भेजता हो. इसके बाद, मैप पर नतीजे दिखाता है.

मैप JavaScript API चालू करना

इस कोडलैब के लिए, आपको अपने प्रोजेक्ट में Google Maps Platform's Maps JavaScript API चालू करना होगा. ऐसा करने के लिए, निम्नलिखित करें:

  1. Google Cloud Platform कंसोल में, मार्केटप्लेस पर जाएं
  2. मार्केटप्लेस में, {0}Maps JavaScript API' खोजें
  3. खोज के नतीजों में Maps JavaScript API के लिए टाइल पर क्लिक करें
  4. #चालू करें बटन पर क्लिक करें

एपीआई कुंजी जनरेट करना

Google Maps Platform पर अनुरोध करने के लिए, आपको एपीआई कुंजी जनरेट करनी होगी और उसे सभी अनुरोधों के साथ भेजना होगा. एपीआई कुंजी जनरेट करने के लिए, ये काम करें:

  1. Google Cloud Platform कंसोल में, बाएं नेविगेशन को खोलने के लिए हैमबर्गर मेन्यू पर क्लिक करें
  2. ‘एपीआई और सेवा' > ‘क्रेडेंशियल' चुनें
  3. [क्रेडेंशियल बनाएं' बटन पर क्लिक करें. इसके बाद, “एपीआई कुंजी' चुनें
  4. नई API (एपीआई) कुंजी कॉपी करें

कोड डाउनलोड करें और वेब सर्वर सेट अप करें

इस कोडलैब के सभी कोड डाउनलोड करने के लिए, नीचे दिए गए बटन पर क्लिक करें:

डाउनलोड की गई zip फ़ाइल को अनपैक करें. यह रूट फ़ोल्डर (bigquery) को अनपैक करेगा, जिसमें इस कोडलैब के हर कदम में एक फ़ोल्डर शामिल होगा. साथ ही, इसमें वे सभी संसाधन भी होंगे जिनकी आपको ज़रूरत होगी.

stepN फ़ोल्डर में इस कोडलैब के हर चरण की ज़रूरत के मुताबिक खत्म होने की स्थिति होती है. रेफ़रंस के लिए, ये पेज देख सकते हैं. हम work नाम वाली डायरेक्ट्री में, कोडिंग का काम करते रहेंगे.

लोकल वेब सर्वर सेट अप करना

हालांकि, आप अपने वेब सर्वर का इस्तेमाल मुफ़्त में कर सकते हैं, लेकिन इस कोडलैब को Chrome वेब सर्वर के साथ अच्छी तरह से काम करने के लिए डिज़ाइन किया गया है. अगर आपने अभी तक उस ऐप्लिकेशन को इंस्टॉल नहीं किया है, तो आप उसे Chrome वेब स्टोर से इंस्टॉल कर सकते हैं.

इंस्टॉल हो जाने के बाद, ऐप्लिकेशन में ऐसा करें:

  1. Chrome खोलें
  2. सबसे ऊपर पता बार में, chrome://apps लिखें
  3. Enter दबाएं.
  4. खुलने वाली विंडो में, वेब सर्वर आइकन पर क्लिक करें. आप किसी ऐप्लिकेशन को सामान्य या पिन किए गए टैब, पूरी स्क्रीन या नई विंडो में खोलने के लिए, उस पर दायां क्लिक भी कर सकते हैं.a3ed00e79b8bfee7.pngइसके बाद, आपको यह डायलॉग दिखेगा, जो आपको अपना स्थानीय वेब सर्वर कॉन्फ़िगर करने देता है: 81b6151c3f60c948.png
  5. फ़ोल्डर चुनें#39; और वह स्थान चुनें जहां आपने कोडलैब नमूना फ़ाइलें डाउनलोड की हैं
  6. "विकल्प' सेक्शन में, 'अपने-आप index.html&#39 दिखाएं; के आगे बने बॉक्स पर सही का निशान लगाएं: 17f4913500faa86f.png
  7. टॉगल को वेब सर्वर पर लेबल करें: STARTED' बाईं ओर और फिर दाईं ओर वापस आएं और फिर वेब सर्वर को रीस्टार्ट करें

a5d554d0d4a91851.png

5. मैप और ड्रॉइंग के टूल लोड हो रहे हैं

एक मूलभूत मैप पेज बनाएं

एक ऐसे आसान एचटीएमएल पेज से शुरू करें जो Maps JavaScript API और JavaScript की कुछ लाइनों का इस्तेमाल करके Google Maps लोड करता है. Google Maps Platform's सरल मैप नमूना का कोड, शुरुआत करने के लिए एक बेहतरीन जगह है. इसे यहां कॉपी किया गया है. आप इसे अपनी पसंद के टेक्स्ट एडिटर या आईडीई में कॉपी करके चिपका सकते हैं. आप चाहें, तो डाउनलोड किए गए रेपो से index.html खोलकर भी ऐसा कर सकते हैं.

  1. रेपो की अपनी स्थानीय कॉपी में work फ़ोल्डर में index.html कॉपी करें
  2. रेपो की स्थानीय कॉपी में, img/ फ़ोल्डर को काम/ फ़ोल्डर में कॉपी करें
  3. काम/index.html को अपने टेक्स्ट एडिटर या आईडीई में खोलें
  4. YOUR_API_KEY को उस API (एपीआई) कुंजी से बदलें जो आपने पहले बनाई थी
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
    async defer></script>
  1. अपने ब्राउज़र में, localhost:<port>/work को खोलें. यहां port आपके स्थानीय वेब सर्वर कॉन्फ़िगरेशन में दिया गया पोर्ट नंबर है. डिफ़ॉल्ट पोर्ट 8887 है. आपको अपना पहला मैप दिखाई देगा.

अगर आपको ब्राउज़र में गड़बड़ी का मैसेज मिलता है, तो देखें कि आपकी एपीआई कुंजी सही है या नहीं. साथ ही, देखें कि आपका स्थानीय वेब सर्वर चालू है या नहीं.

डिफ़ॉल्ट जगह और ज़ूम का लेवल बदलना

जगह और ज़ूम का लेवल सेट करने वाला कोड, index.html की 28 & 28 लाइनों पर है. फ़िलहाल, यह सिडनी, ऑस्ट्रेलिया पर आधारित है:

<script>
      let map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8
        });
      }
</script>

यह ट्यूटोरियल न्यूयॉर्क के लिए BigQuery यात्रा का डेटा के साथ काम करता है, इसलिए इसके बाद आपको मैप शुरू करने का कोड बदलकर न्यूयॉर्क शहर में किसी ऐसी जगह पर सेट करना होगा जो सही ज़ूम लेवल पर हो - 13 या 14 अच्छा परफ़ॉर्म कर सकें.

ऐसा करने के लिए, मैप पर एंपायर स्टेट बिल्डिंग पर मैप को सेंटर में लाने और ज़ूम लेवल को 14 पर सेट करने के लिए ऊपर दिए गए कोड ब्लॉक को अपडेट करें:

<script>
      let map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 40.7484405, lng: -73.9878531},
          zoom: 14
        });
      }
</script>

इसके बाद, नतीजे देखने के लिए, अपने ब्राउज़र में मैप को फिर से लोड करें.

ड्रॉइंग और विज़ुअलाइज़ेशन लाइब्रेरी लोड करना

अपने मैप में ड्रॉइंग की क्षमताएं जोड़ने के लिए, आप एक ऐसी स्क्रिप्ट पैरामीटर बदलेंगे जो मैप JavaScript API को लोड करती है. इसके लिए, आपको एक वैकल्पिक पैरामीटर जोड़ना होगा, जो Google Maps Platform को ड्रॉइंग लाइब्रेरी चालू करने के लिए कहता है.

यह कोडलैब HeatmapLayer का भी इस्तेमाल करता है, इसलिए आप भी विज़ुअलाइज़ेशन लाइब्रेरी का अनुरोध करने के लिए स्क्रिप्ट को अपडेट कर सकते हैं. ऐसा करने के लिए, libraries पैरामीटर जोड़ें. साथ ही, visualization और drawing लाइब्रेरी को कॉमा लगाकर अलग की गई वैल्यू के तौर पर बताएं, जैसे कि libraries=visualization,drawing

यह कुछ ऐसा दिखना चाहिए:

<script src='http://maps.googleapis.com/maps/api/js?libraries=visualization,drawing&callback=initMap&key=YOUR_API_KEY' async defer></script>

आरेखण मैनेजर जोड़ें

क्वेरी में इनपुट के तौर पर उपयोगकर्ता के बनाए गए आकारों का इस्तेमाल करने के लिए, Circle, Rectangle, और Polygon टूल को चालू करके, अपने मैप में DrawingManager जोड़ें.

सभी DrawingManager सेट अप कोड को नए फ़ंक्शन में रखना अच्छा रहता है, इसलिए index.html की अपनी कॉपी में, यह करें:

  1. DrawingManager बनाने के लिए, नीचे दिए गए कोड के साथ setUpDrawingTools() नाम का फ़ंक्शन जोड़ें. साथ ही, पेज में मैप ऑब्जेक्ट के बारे में बताने के लिए, इसकी map प्रॉपर्टी सेट करें.

google.maps.drawing.DrawingManager(options) को दिए गए विकल्प डिफ़ॉल्ट आकार ड्रॉइंग के प्रकार और बनाए गए आकार के लिए डिसप्ले विकल्प सेट करते हैं. क्वेरी के रूप में भेजने के लिए मैप के क्षेत्रों को चुनने के लिए, आकारों की अपारदर्शिता शून्य होनी चाहिए. उपलब्ध विकल्पों के बारे में ज़्यादा जानकारी के लिए, ड्रॉइंग मैनेजर के विकल्प देखें.

function setUpDrawingTools() {
  // Initialize drawing manager
  drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.CIRCLE,
    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_LEFT,
      drawingModes: [
        google.maps.drawing.OverlayType.CIRCLE,
        google.maps.drawing.OverlayType.POLYGON,
        google.maps.drawing.OverlayType.RECTANGLE
      ]
    },
    circleOptions: {
      fillOpacity: 0
    },
    polygonOptions: {
      fillOpacity: 0
    },
    rectangleOptions: {
      fillOpacity: 0
    }
  });
  drawingManager.setMap(map);
}
  1. मैप ऑब्जेक्ट बनने के बाद अपने initMap() फ़ंक्शन में setUpDrawingTools() को कॉल करें
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 40.744593, lng: -73.990370}, // Manhattan, New York.
    zoom: 12
  });

  setUpDrawingTools();
}
  1. index.html को फिर से लोड करें और देखें कि ड्रॉइंग टूल दिख रहे हैं या नहीं. यह भी जांचें कि आप उनका इस्तेमाल सर्कल, आयतों, और पॉलीगॉन के आकारों को बनाने के लिए कर सकते हैं.

आप सर्कल और आयतों को बनाने के लिए, उन्हें क्लिक करके खींच और छोड़ सकते हैं. हालांकि, हर कोने के लिए क्लिक करके पॉलीगॉन बनाना चाहिए. इसके बाद, आकार पूरा करने के लिए दो बार क्लिक करना होगा.

ड्रॉइंग ड्रॉइंग इवेंट मैनेज करना

जब कोई उपयोगकर्ता आकार बनाना पूरा कर लेता है, तो आपको इवेंट को हैंडल करने के लिए कुछ कोड की ज़रूरत होती है. यह ठीक उसी तरह होता है जैसे SQL क्वेरी बनाने के लिए, बनाए गए आकार के निर्देशांक की ज़रूरत होती है.

हम इसके लिए बाद में कोड जोड़ेंगे, लेकिन अभी हम rectanglecomplete, circlecomplete, और polygoncomplete इवेंट को हैंडल करने के लिए तीन खाली इवेंट हैंडलर का इस्तेमाल कर सकते हैं. हैंडलर को इस स्टेज पर कोई भी कोड चलाने की ज़रूरत नहीं होती.

setUpDrawingTools() फ़ंक्शन में सबसे नीचे इन्हें जोड़ें:

drawingManager.addListener('rectanglecomplete', rectangle => {
    // We will add code here in a later step.
});
drawingManager.addListener('circlecomplete', circle => {
  // We will add code here in a later step.
});

drawingManager.addListener('polygoncomplete', polygon => {
  // We will add code here in a later step.
});

आप step2 फ़ोल्डर में, रेपो की अपनी स्थानीय कॉपी में इस कोड का काम करने वाला उदाहरण देख सकते हैं: step2/map.html.

6. BigQuery क्लाइंट एपीआई का इस्तेमाल करना

Google BigQuery क्लाइंट एपीआई की मदद से आप अनुरोधों को बनाने, जवाबों को पार्स करने, और पुष्टि करने के लिए ज़रूरी छोटे-मोटे बदलाव वाले कोड लिखने से बच सकते हैं. यह कोडलैब, JavaScript के लिए Google API क्लाइंट लाइब्रेरी की मदद से, BigQuery API का इस्तेमाल करता है. ऐसा इसलिए, क्योंकि हम ब्राउज़र पर आधारित ऐप्लिकेशन डेवलप करेंगे.

इसके बाद, आप इस एपीआई को वेब पेज में लोड करने के लिए कोड जोड़ेंगे. साथ ही, BigQuery के साथ इंटरैक्ट करने के लिए इसका इस्तेमाल करेंगे.

JavaScript के लिए Google Client API जोड़ें

आप BigQuery के लिए क्वेरी चलाने के लिए, JavaScript के लिए Google क्लाइंट एपीआई का इस्तेमाल करेंगे. एपीआई की अपनी index.html की कॉपी (अपने work फ़ोल्डर में) में इस तरह के <script> टैग का इस्तेमाल करके, एपीआई लोड करें. टैग को मैप टैग लोड करने वाले <script> टैग के ठीक नीचे रखें:

<script src='https://apis.google.com/js/client.js'></script>

Google Client API लोड करने के बाद, उपयोगकर्ता को BigQuery में मौजूद डेटा ऐक्सेस करने की अनुमति दें. ऐसा करने के लिए, आप OAuth 2.0 का इस्तेमाल कर सकते हैं. सबसे पहले, आपको अपने Google Cloud Console के प्रोजेक्ट में कुछ क्रेडेंशियल सेट अप करने होंगे.

OAuth 2.0 क्रेडेंशियल बनाएं

  1. Google Cloud Console में, नेविगेशन मेन्यू से, एपीआई और सेवाएं; > क्रेडेंशियल चुनें.

अपने क्रेडेंशियल सेट अप करने से पहले, आपको अनुमति देने वाली स्क्रीन के लिए कुछ कॉन्फ़िगरेशन जोड़ना होगा. यह कॉन्फ़िगरेशन तब दिखेगा, जब आपके ऐप्लिकेशन का असली उपयोगकर्ता यह जानकारी देगा कि वह आपके ऐप्लिकेशन को BigQuery की डेटा ऐक्सेस करने की अनुमति देता है या नहीं.

ऐसा करने के लिए, OAuth सहमति वाली स्क्रीन टैब पर क्लिक करें. 2. आपको इस टोकन के दायरे में Big Query API को जोड़ना होगा. Google API के दायरे में, दायरा जोड़ें बटन पर क्लिक करें. 3. सूची से, ../auth/bigquery स्कोप के साथ Big Query API एंट्री के बगल में मौजूद बॉक्स को चुनें. 4. जोड़ें क्लिक करें. 5. {0}ऐप्लिकेशन का नाम' फ़ील्ड में कोई नाम डालें. 6. अपनी सेटिंग सेव करने के लिए सेव करें पर क्लिक करें. 7. इसके बाद, आप अपना OAuth क्लाइंट आईडी बनाएंगे. ऐसा करने के लिए, क्रेडेंशियल बनाएं पर क्लिक करें:

4D18a965fc760e39.png

  1. ड्रॉपडाउन मेन्यू में, OAuth Client-ID पर क्लिक करें. 1f8b36a1c27c75f0.png
  2. ऐप्लिकेशन टाइप में जाकर, वेब ऐप्लिकेशन चुनें.
  3. ऐप्लिकेशन नाम के फ़ील्ड में, अपने प्रोजेक्ट का नाम लिखें. उदाहरण के लिए, "BigQuery और Maps&कोटेशन;.
  4. 'अनुमति वाले JavaScript ऑरिजिन' फ़ील्ड में, पाबंदियों में पोर्ट नंबर के साथ-साथ, लोकल होस्ट का यूआरएल डालें. उदाहरण के लिए: http://localhost:8887
  1. बनाएं बटन पर क्लिक करें.

एक पॉप-अप में आपको क्लाइंट आईडी और क्लाइंट सीक्रेट दिखाया जाता है. BigQuery के ख़िलाफ़ पुष्टि करने के लिए आपको क्लाइंट आईडी की ज़रूरत होगी. इसे कॉपी करें और clientId में मौजूद नए ग्लोबल JavaScript वैरिएबल के तौर पर work/index.html में चिपकाएं.

let clientId = 'YOUR_CLIENT_ID';

7. पुष्टि करना और अनुमति देना

मैप शुरू करने से पहले, आपके वेब पेज को उपयोगकर्ता को BigQuery ऐक्सेस करने की अनुमति देनी होगी. इस उदाहरण में, हम OAuth 2.0 का इस्तेमाल करते हैं, जैसा कि JavaScript क्लाइंट एपीआई दस्तावेज़ के अनुमति देने का सेक्शन में बताया गया है. क्वेरी भेजने के लिए, आपको OAuth क्लाइंट आईडी और अपने प्रोजेक्ट आईडी का इस्तेमाल करना होगा.

जब वेब पेज में Google क्लाइंट एपीआई लोड होता है, तो आपको नीचे दिए गए काम करने होंगे:

  • उपयोगकर्ता को अनुमति दें.
  • अगर अनुमति हो, तो BigQuery API लोड करें.
  • मैप लोड करें और उसे शुरू करें.

तैयार एचटीएमएल पेज कैसा दिखेगा, इसके उदाहरण के लिए step3/map.html देखें.

उपयोगकर्ता को अनुमति दें

ऐप्लिकेशन के असली उपयोगकर्ता को ऐप्लिकेशन को, BigQuery में डेटा ऐक्सेस करने की अनुमति देनी होगी. ऐसा करने के लिए, JavaScript के लिए Google Client API, OAuth लॉजिक को मैनेज करता है.

असल दुनिया के ऐप्लिकेशन में आपके पास अनुमति देने के चरण को जोड़ने के बारे में कई विकल्प होते हैं.

उदाहरण के लिए, आप बटन जैसे किसी यूआई एलिमेंट से authorize() को कॉल कर सकते हैं या पेज लोड होने के बाद ऐसा कर सकते हैं. JavaScript के लिए Google Client API के लोड हो जाने के बाद, हमने gapi.load()तरीका में कॉलबैक फ़ंक्शन का इस्तेमाल करके उपयोगकर्ता को अनुमति देने का विकल्प चुना है.

क्लाइंट के लिए लाइब्रेरी और पुष्टि करने वाले मॉड्यूल, दोनों को लोड करने के लिए, JavaScript के लिए Google क्लाइंट एपीआई को लोड करने वाले <script> टैग के तुरंत बाद कुछ कोड लिखें, ताकि हम उपयोगकर्ता की सीधे पुष्टि कर सकें.

<script src='https://apis.google.com/js/client.js'></script>
<script type='text/javascript'>
  gapi.load('client:auth', authorize);
</script>

अनुमति देने पर, BigQuery API लोड करें

उपयोगकर्ता की अनुमति के बाद, BigQuery API को लोड करें.

सबसे पहले, पिछले चरण में जोड़े गए clientId वैरिएबल के साथ gapi.auth.authorize() को कॉल करें. रिस्पॉन्स को handleAuthResult नाम के कॉलबैक फ़ंक्शन में मैनेज करें.

immediate पैरामीटर से यह कंट्रोल किया जाता है कि उपयोगकर्ता को पॉप-अप दिखाया जाएगा या नहीं. अगर उपयोगकर्ता को पहले से ही अनुमति मिल गई है, तो अनुमति पॉप-अप को रोकने के लिए true पर सेट करें.

अपने पेज पर handleAuthResult() नाम का एक फ़ंक्शन जोड़ें. फ़ंक्शन को authresult पैरामीटर की ज़रूरत होगी, जो आपको इस बात के आधार पर लॉजिक के फ़्लो को कंट्रोल करने देता है कि उपयोगकर्ता को अनुमति मिली या नहीं.

अगर उपयोगकर्ता को अनुमति मिल गई है, तो BigQuery API को लोड करने के लिए, loadApi नाम का फ़ंक्शन भी जोड़ें.

handleAuthResult() फ़ंक्शन में loadApi() को कॉल करने के लिए handleAuthResult() फ़ंक्शन में तर्क जोड़ें, अगर कोई authResult ऑब्जेक्ट फ़ंक्शन में पास किया गया है और अगर ऑब्जेक्ट's error प्रॉपर्टी का मान false है.

gapi.client.load() तरीके का इस्तेमाल करके, BigQuery API को लोड करने के लिए loadApi() फ़ंक्शन में कोड जोड़ें.

let clientId = 'your-client-id-here';
let scopes = 'https://www.googleapis.com/auth/bigquery';

// Check if the user is authorized.
function authorize(event) {
  gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
  return false;
}

// If authorized, load BigQuery API
function handleAuthResult(authResult) {
  if (authResult && !authResult.error) {
    loadApi();
    return;
  }
  console.error('Not authorized.')  
}

// Load BigQuery client API
function loadApi(){
  gapi.client.load('bigquery', 'v2');
}

मैप लोड करें

आखिरी चरण, मैप को शुरू करना है. ऐसा करने के लिए, आपको लॉजिक के क्रम को थोड़ा बदलना होगा. यह तब शुरू होता है, जब Maps API JavaScript लोड हो जाती है.

ऐसा करने के लिए, आप gapi.client ऑब्जेक्ट के load() तरीके के बाद, then() तरीके से initMap() फ़ंक्शन को कॉल कर सकते हैं.

// Load BigQuery client API
function loadApi(){
  gapi.client.load('bigquery', 'v2').then(
   () => initMap()
  );
}

8. BigQuery API के सिद्धांत

BigQuery API कॉल आम तौर पर कुछ सेकंड में ही शुरू हो जाते हैं, लेकिन हो सकता है कि तुरंत जवाब न दें. लंबे समय तक चलने वाली नौकरियों की स्थिति जानने और काम पूरा होने पर ही नतीजे पाने के लिए, आपको BigQuery में पोल कराने की ज़रूरत होती है.

इस चरण के लिए पूरा कोड step4/map.html पर मौजूद है.

अनुरोध भेजा जा रहा है

एपीआई का इस्तेमाल करके क्वेरी भेजने के लिए, work/index.html में JavaScript फ़ंक्शन जोड़ें. साथ ही, BigQuery डेटासेट और क्वेरी से जुड़ी टेबल वाले प्रोजेक्ट के मान स्टोर करने के लिए, कुछ वैरिएबल जोड़ें. साथ ही, किसी ऐसे शुल्क की बिलिंग करने वाला प्रोजेक्ट आईडी भी जोड़ें.

let datasetId = 'your_dataset_id';
let billingProjectId = 'your_project_id';
let publicProjectId = 'bigquery-public-data';

function sendQuery(queryString){
  let request = gapi.client.bigquery.jobs.query({
      'query': queryString,
      'timeoutMs': 30000,
      'datasetId': datasetId,
      'projectId': billingProjectId,
      'useLegacySql':false
  });
  request.execute(response => {
      //code to handle the query response goes here.
  });
}

नौकरी की स्थिति देखना

नीचे दिए गए checkJobStatus फ़ंक्शन से किसी नौकरी की स्थिति की समय-समय पर जांच करने का तरीका भी पता चलता है. इसके लिए, get एपीआई के तरीके और मूल क्वेरी अनुरोध के ज़रिए दिए गए jobId का इस्तेमाल किया जाता है. यहां एक उदाहरण दिया गया है जो हर 500 मिलीसेकंड पर काम पूरा होने तक चलता है.

let jobCheckTimer;

function checkJobStatus(jobId){
  let request = gapi.client.bigquery.jobs.get({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response =>{
    if (response.status.errorResult){
      // Handle any errors.
      console.log(response.status.error);
      return;
    }

    if (response.status.state == 'DONE'){
      // Get the results.
      clearTimeout(jobCheckTimer);
      getQueryResults(jobId);
      return;
    }
    // Not finished, check again in a moment.
    jobCheckTimer = setTimeout(checkJobStatus, 500, [jobId]);    
  });
}

request.execute() कॉल में, checkJobStatus() तरीके को कॉलबैक के तौर पर कॉल करने के लिए, sendQuery तरीके में बदलाव करें. checkJobStatus को जॉब आईडी दें. यह रिस्पॉन्स ऑब्जेक्ट के तौर पर jobReference.jobId के तौर पर दिखता है.

function sendQuery(queryString){
  let request = gapi.client.bigquery.jobs.query({
      'query': queryString,
      'timeoutMs': 30000,
      'datasetId': datasetId,
      'projectId': billingProjectId,
      'useLegacySql':false
  });
  request.execute(response => checkJobStatus(response.jobReference.jobId));
}

क्वेरी के नतीजे पाना

क्वेरी खत्म होने के बाद उसके नतीजे पाने के लिए, jobs.getQueryResults एपीआई कॉल का इस्तेमाल करें. अपने पेज पर getQueryResults() नाम का एक फ़ंक्शन जोड़ें, जो jobId का पैरामीटर स्वीकार करता है:

function getQueryResults(jobId){
  let request = gapi.client.bigquery.jobs.getQueryResults({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response => {
    // Do something with the results.
  })
}

9. BigQuery API से जगह की जानकारी के डेटा की क्वेरी करना

BigQuery में डेटा के लिए स्थानीय क्वेरी चलाने के लिए, SQL का इस्तेमाल करने के तीन तरीके हैं:

BigQuery के लेगसी एसक्यूएल रेफ़रंस के मैथमैटिकल फ़ंक्शन सेक्शन में, बाउंडिंग बॉक्स और रेडियस क्वेरी के उदाहरण दिए गए हैं. ये सेक्शन, बेहतर उदाहरण और #39; में दिए गए हैं.

बाउंडिंग बॉक्स और दायरे की क्वेरी के लिए, आप BigQuery एपीआई query तरीके को कॉल कर सकते हैं. हर क्वेरी के लिए SQL बनाएं और उसे पिछले चरण में बनाए गए sendQuery फ़ंक्शन पर भेजें.

इस चरण के लिए कोड का एक काम करने वाला उदाहरण step4/map.html में है.

आयत क्वेरी

मैप पर BigQuery डेटा दिखाने का सबसे आसान तरीका, उन सभी पंक्तियों का अनुरोध करना है जहां अक्षांश और देशांतर आयताकार में आते हैं. इसके लिए, तुलना में कम या ज़्यादा का इस्तेमाल किया जाता है. यह मौजूदा मैप व्यू या मैप पर ड्रॉ किया गया आकार हो सकता है.

उपयोगकर्ता के बनाए गए आकार का इस्तेमाल करने के लिए, index.html में मौजूद कोड बदलें, ताकि आयत के पूरा होने पर ड्रॉइंग इवेंट को हैंडल किया जा सके. इस उदाहरण में, कोड आयताकार ऑब्जेक्ट पर getBounds() का इस्तेमाल करता है, ताकि ऑब्जेक्ट को मैप कोऑर्डिनेट में रेक्टैंगल की सीमा दिखाई जा सके और यह rectangleQuery नाम के फ़ंक्शन को पास करता है:

drawingManager.addListener('rectanglecomplete', rectangle => rectangleQuery(rectangle.getBounds()));

rectangleQuery फ़ंक्शन को बस सबसे ऊपर दाईं ओर (उत्तर-पूर्व) और निचली बाईं ओर (दक्षिण पश्चिम) निर्देशांकों का इस्तेमाल करके, आपकी BigQuery टेबल की हर पंक्ति से कम/से ज़्यादा/ज़्यादा बनाना होगा. यहां एक उदाहरण दिया गया है, जिसमें 'pickup_latitude' और 'pickup_longitude' नाम के कॉलम वाली टेबल की क्वेरी की गई है. इस कॉलम में जगह की जानकारी को स्टोर किया जाता है.

BigQuery टेबल के बारे में जानकारी देना

BigQuery API का इस्तेमाल करके किसी टेबल की क्वेरी करने के लिए, आपको अपनी SQL क्वेरी में टेबल का नाम पूरी तरह क्वालिफ़ाइड फ़ॉर्म में देना होगा. स्टैंडर्ड एसक्यूएल में फ़ॉर्मैट project.dataset.tablename है. लेगसी SQL में's project.dataset.tablename.

न्यूयॉर्क शहर के लिए टैक्सी की कई टेबल उपलब्ध हैं. उन्हें देखने के लिए, BigQuery वेब कंसोल पर जाएं और &सार्वजनिक डेटासेट&utt;मेन्यू आइटम को बड़ा करें. new_york नाम का डेटासेट ढूंढकर टेबल को बड़ा करें. यैलो टैक्सी की टेबल चुनें: bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2016).

प्रोजेक्ट आईडी बताना

एपीआई कॉल में, आपको बिलिंग से जुड़े कामों के लिए अपने Google Cloud Platform प्रोजेक्ट का नाम डालना होगा. इस कोडलैब में, यह वही प्रोजेक्ट नहीं है जिसमें टेबल है. अगर आप किसी ऐसी टेबल के साथ काम कर रहे हैं जिसे आपने अपने प्रोजेक्ट में डेटा अपलोड करके बनाया था, तो यह प्रोजेक्ट आईडी वही होगा जो आपके SQL स्टेटमेंट में था.

पब्लिक डेटासेट प्रोजेक्ट के रेफ़रंस रखने के लिए अपने कोड में JavaScript वैरिएबल जोड़ें. इस प्रोजेक्ट में वह टेबल होती है जिसकी आप क्वेरी कर रहे हैं. साथ ही, टेबल के नाम और डेटासेट के नाम को भी शामिल करें. आपको अपने बिलिंग प्रोजेक्ट आईडी के बारे में बताने के लिए, एक अलग वैरिएबल की ज़रूरत है.

index.html की अपनी कॉपी में, billingProjectId, publicProjectId, datasetId और tableName नाम के ग्लोबल JavaScript वैरिएबल जोड़ें.

BigQuery सार्वजनिक डेटासेट प्रोजेक्ट से मिली जानकारी के साथ, 'publicProjectId', 'datasetId', और 'tableName' वैरिएबल की शुरुआत करें. billingProjectId को अपने प्रोजेक्ट आईडी से शुरू करें (यह वह प्रोजेक्ट है जिसे आपने &कोटेशन में बनाया था; इसे सेट अप के लिए पहले सेट अप किया जा रहा है).

let billingProjectId = 'YOUR_PROJECT_ID';
let publicProjectId = 'bigquery-public-data';
let datasetId = 'new_york_taxi_trips';
let tableName = 'tlc_yellow_trips_2016';

अब SQL जनरेट करने और अपने पिछले चरण में बनाए गए sendQuery फ़ंक्शन का इस्तेमाल करके BigQuery को क्वेरी भेजने के लिए, अपने कोड में दो फ़ंक्शन जोड़ें.

पहले फ़ंक्शन को rectangleSQL() कॉल करना चाहिए और दो तर्कों को स्वीकार करना होगा, मैप निर्देशांक में आयत के कोनों को दिखाने वाले google.Maps.LatLng ऑब्जेक्ट का एक जोड़ा.

दूसरे फ़ंक्शन को rectangleQuery() कहा जाना चाहिए. यह क्वेरी टेक्स्ट को sendQuery फ़ंक्शन को पास करता है.

let billingProjectId = 'YOUR_PROJECT_ID';
let publicProjectId = 'bigquery-public-data';
let datasetId = 'new_york';
let tableName = 'tlc_yellow_trips_2016';

function rectangleQuery(latLngBounds){
  let queryString = rectangleSQL(latLngBounds.getNorthEast(), latLngBounds.getSouthWest());
  sendQuery(queryString);
}

function rectangleSQL(ne, sw){
  let queryString = 'SELECT pickup_latitude, pickup_longitude '
  queryString +=  'FROM `' + publicProjectId +'.' + datasetId + '.' + tableName + '`'
  queryString += ' WHERE pickup_latitude > ' + sw.lat();
  queryString += ' AND pickup_latitude < ' + ne.lat();
  queryString += ' AND pickup_longitude > ' + sw.lng();
  queryString += ' AND pickup_longitude < ' + ne.lng();
  return queryString;
}

इस समय, आपके पास BigQuery में उन क्वेरी के लिए क्वेरी भेजने के लिए काफ़ी कोड है जिनमें उपयोगकर्ता ने एक आयत बनाया है. सर्कल और फ़्रीहैंड आकार के लिए क्वेरी के दूसरे तरीके जोड़ने से पहले, आइए देखें कि क्वेरी से मिलने वाले डेटा को किस तरह हैंडल किया जाए.

10. जवाब को विज़ुअलाइज़ करना

BigQuery टेबल बहुत बड़ी हो सकती हैं—डेटा का साइज़ बहुत बड़ा है—और यह हर सेकंड लाखों पंक्तियों तक बढ़ सकता है. इसलिए, यह ज़रूरी है कि लौटाए गए डेटा को सीमित तौर पर दिखाया जाए, ताकि उसे मैप पर बनाया जा सके. बहुत बड़े नतीजे सेट (हज़ारों या इससे ज़्यादा पंक्तियों) में हर पंक्ति की जगह बनाने से, मैप नहीं पढ़ा जा सकेगा. SQL क्वेरी और मैप, दोनों में जगहों को इकट्ठा करने के कई तरीके हैं. साथ ही, आप क्वेरी के नतीजे को सीमित कर सकते हैं.

इस चरण के लिए पूरा कोड, step5/map.html पर मौजूद है.

अपने वेब पेज पर ट्रांसफ़र किए गए डेटा की संख्या को इस कोडलैब के लिए सही साइज़ तक बनाए रखने के लिए, rectangleSQL() फ़ंक्शन में बदलाव करें. इसके बाद, 1,0000 लाइनों तक रिस्पॉन्स को सीमित करने वाला स्टेटमेंट जोड़ें. नीचे दिए गए उदाहरण में, recordLimit नाम के ग्लोबल वैरिएबल के बारे में बताया गया है, ताकि सभी क्वेरी फ़ंक्शन एक ही वैल्यू का इस्तेमाल कर सकें.

let recordLimit = 10000;
function rectangleSQL(ne, sw){
  var queryString = 'SELECT pickup_latitude, pickup_longitude '
  queryString +=  'FROM `' + publicProjectId +'.' + datasetId + '.' + tableName + '`'
  queryString += ' WHERE pickup_latitude > ' + sw.lat();
  queryString += ' AND pickup_latitude < ' + ne.lat();
  queryString += ' AND pickup_longitude > ' + sw.lng();
  queryString += ' AND pickup_longitude < ' + ne.lng();
  queryString += ' LIMIT ' + recordLimit;
  return queryString;
}

जगहों की सघनता देखने के लिए, आप हीटमैप का इस्तेमाल कर सकते हैं. इस काम के लिए, Maps JavaScript API में HeatmapLayer क्लास मौजूद है. हीटमैप लेयर अक्षांश, देशांतर निर्देशांकों की एक श्रेणी लेता है, ताकि क्वेरी से मिली पंक्तियों को हीटमैप में बदलना आसान हो जाए.

getQueryResults फ़ंक्शन में, response.result.rows श्रेणी को doHeatMap() नाम के नए JavaScript फ़ंक्शन में पास करें, जिससे हीटमैप बन जाएगा.

हर लाइन में f प्रॉपर्टी होगी, जो कॉलम की एक श्रेणी है. हर कॉलम में, v प्रॉपर्टी वाली वैल्यू होगी.

आपके कोड को हर लाइन में, कॉलम के लूप में जाकर, वैल्यू को निकालना होगा.

SQL क्वेरी में, आपने टैक्सी पिक अप के सिर्फ़ अक्षांश और देशांतर वैल्यू के बारे में पूछा है, इसलिए जवाब में सिर्फ़ दो कॉलम होंगे.

जब आप गर्मियों की श्रेणी असाइन कर देते हैं, तब हीटमैप लेयर पर setMap() को कॉल करना न भूलें. ऐसा करने पर, यह मैप पर दिखेगा.

यहां उदाहरण देखें:

function getQueryResults(jobId){
  let request = gapi.client.bigquery.jobs.getQueryResults({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response => doHeatMap(response.result.rows))
}

let heatmap;

function doHeatMap(rows){
  let heatmapData = [];
  if (heatmap != null){
    heatmap.setMap(null);
  }
  for (let i = 0; i < rows.length; i++) {
      let f = rows[i].f;
      let coords = { lat: parseFloat(f[0].v), lng: parseFloat(f[1].v) };
      let latLng = new google.maps.LatLng(coords);
      heatmapData.push(latLng);
  }
  heatmap = new google.maps.visualization.HeatmapLayer({
      data: heatmapData
  });
  heatmap.setMap(map);
}

इस समय, आप ये काम कर सकते हैं:

  • पेज खोलें और BigQuery के इस्तेमाल की अनुमति दें
  • न्यूयॉर्क में कहीं पर भी आयत बनाएं
  • इसके बाद, दिखने वाले क्वेरी के नतीजे देखें, जिन्हें हीटमैप के तौर पर दिखाया गया है.

यहां उदाहरण के तौर पर, 2016 के एनवाईसी यलो टैक्सी के डेटा से जुड़े आयत क्वेरी का इस्तेमाल किया गया है, जिसे हीटमैप के तौर पर दिखाया गया है. यहां जुलाई में शनिवार को एम्पायर स्टेट बिल्डिंग के आस-पास पिक अप का वितरण दिखाया गया है:

7b1face0e7c71c78.png

11. किसी पॉइंट के आस-पास के दायरे के हिसाब से क्वेरी करना

खास दायरे की क्वेरी काफ़ी मिलती-जुलती हैं. BigQuery' के लेगसी एसक्यूएल मैथ फ़ंक्शन का इस्तेमाल करके, आप हवरिन फ़ॉर्मूला का इस्तेमाल करके SQL क्वेरी बना सकते हैं. यह फ़ॉर्मूला धरती के

रेक्टैंगल के लिए एक जैसी तकनीक इस्तेमाल करके, OverlayComplete इवेंट को हैंडल किया जा सकता है. इससे उपयोगकर्ता को बनाई गई सर्कल के बीचो-बीच और दायरे को पाया जा सकता है. साथ ही, क्वेरी के लिए उसी तरह SQL बनाया जा सकता है.

इस चरण के लिए, कोड के काम करने वाले उदाहरण को step6/map.html के तौर पर कोड स्टोर करने की जगह में शामिल किया गया है.

drawingManager.addListener('circlecomplete', circle => circleQuery(circle));

index.html की अपनी कॉपी में, दो नए खाली फ़ंक्शन जोड़ें: circleQuery() और haversineSQL().

इसके बाद, circlecomplete इवेंट हैंडलर जोड़ें, जो circleQuery(). नाम के एक नए फ़ंक्शन को सेंटर और रेडियस पास करता है

circleQuery() फ़ंक्शन, haversineSQL() को कॉल करके क्वेरी का एसक्यूएल बनाएगा. इसके बाद, नीचे दिए गए उदाहरण कोड के मुताबिक, sendQuery() फ़ंक्शन को कॉल करके क्वेरी भेजेगा.

function circleQuery(circle){
  let queryString = haversineSQL(circle.getCenter(), circle.radius);
  sendQuery(queryString);
}

// Calculate a circular area on the surface of a sphere based on a center and radius.
function haversineSQL(center, radius){
  let queryString;
  let centerLat = center.lat();
  let centerLng = center.lng();
  let kmPerDegree = 111.045;

  queryString = 'CREATE TEMPORARY FUNCTION Degrees(radians FLOAT64) RETURNS FLOAT64 LANGUAGE js AS ';
  queryString += '""" ';
  queryString += 'return (radians*180)/(22/7);';
  queryString += '"""; ';

  queryString += 'CREATE TEMPORARY FUNCTION Radians(degrees FLOAT64) RETURNS FLOAT64 LANGUAGE js AS';
  queryString += '""" ';
  queryString += 'return (degrees*(22/7))/180;';
  queryString += '"""; ';

  queryString += 'SELECT pickup_latitude, pickup_longitude '
  queryString += 'FROM `' + publicProjectId +'.' + datasetId + '.' + tableName + '` ';
  queryString += 'WHERE '
  queryString += '(' + kmPerDegree + ' * DEGREES( ACOS( COS( RADIANS('
  queryString += centerLat;
  queryString += ') ) * COS( RADIANS( pickup_latitude ) ) * COS( RADIANS( ' + centerLng + ' ) - RADIANS('
  queryString += ' pickup_longitude ';
  queryString += ') ) + SIN( RADIANS('
  queryString += centerLat;
  queryString += ') ) * SIN( RADIANS( pickup_latitude ) ) ) ) ) ';

  queryString += ' < ' + radius/1000;
  queryString += ' LIMIT ' + recordLimit;
  return queryString;
}

इसे आज़माएं!

ऊपर दिया गया कोड जोड़ें और मैप के किसी क्षेत्र को चुनने के लिए, {0}Circle' टूल को आज़माएं. नतीजे कुछ इस तरह दिखना चाहिए:

845418166b7cc7a3.png

12. आर्बिट्ररी आकार की क्वेरी करना

रीकैप: SQL आयतों और सर्कल के अलावा, किसी दूसरे आकार के आकार का इस्तेमाल करके क्वेरी करने की सुविधा नहीं देता. BigQuery में कोई नेटिव ज्यामिति डेटा टाइप नहीं होता. इसलिए, पॉलीगॉन के साइज़ का इस्तेमाल करके क्वेरी चलाने के लिए, आपको SQL की आसान क्वेरी के लिए अलग तरीके की ज़रूरत होती है.

इसके लिए, उपयोगकर्ता के परिभाषित किए गए फ़ंक्शन (UDF) का इस्तेमाल किया जा सकता है. यह एक बहुत ही असरदार BigQuery सुविधा है. यूडीएफ़, SQL क्वेरी में JavaScript कोड का इस्तेमाल करता है.

इस चरण के लिए काम करने वाला कोड step7/map.html में मौजूद है.

BigQuery API में यूडीएफ़

यूडीएफ़ के लिए BigQuery API का तरीका, वेब कंसोल से थोड़ा अलग है: आपको और #39; jobs.insert method को कॉल करना होगा.

एपीआई के ज़रिए स्टैंडर्ड SQL क्वेरी के लिए, उपयोगकर्ता के तय किए गए फ़ंक्शन का इस्तेमाल करने के लिए सिर्फ़ एक SQL स्टेटमेंट की ज़रूरत होती है. useLegacySql की वैल्यू false पर सेट होनी चाहिए. नीचे दिया गया JavaScript उदाहरण, एक फ़ंक्शन दिखाता है जो नई नौकरी शामिल करने का अनुरोध ऑब्जेक्ट बनाता और भेजता है. इस मामले में, उपयोगकर्ता के तय किए गए फ़ंक्शन वाली क्वेरी है.

इस काम का एक उदाहरण step7/map.html है.

function polygonQuery(polygon) {
  let request = gapi.client.bigquery.jobs.insert({
    'projectId' : billingProjectId,
      'resource' : {
        'configuration':
          {
            'query':
            {
              'query': polygonSql(polygon),
              'useLegacySql': false
            }
          }
      }
  });
  request.execute(response => checkJobStatus(response.jobReference.jobId));
}

SQL क्वेरी इस तरह बनाई जाती है:

function polygonSql(poly){
  let queryString = 'CREATE TEMPORARY FUNCTION pointInPolygon(latitude FLOAT64, longitude FLOAT64) ';
  queryString += 'RETURNS BOOL LANGUAGE js AS """ ';
  queryString += 'var polygon=' + JSON.stringify(poly) + ';';
  queryString += 'var vertx = [];';
  queryString += 'var verty = [];';
  queryString += 'var nvert = 0;';
  queryString += 'var testx = longitude;';
  queryString += 'var testy = latitude;';
  queryString += 'for(coord in polygon){';
  queryString += '  vertx[nvert] = polygon[coord][0];';
  queryString += '  verty[nvert] = polygon[coord][1];';
  queryString += '  nvert ++;';
  queryString += '}';
  queryString += 'var i, j, c = 0;';
  queryString += 'for (i = 0, j = nvert-1; i < nvert; j = i++) {';
  queryString += '  if ( ((verty[i]>testy) != (verty[j]>testy)) &&(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ){';
  queryString += '    c = !c;';
  queryString += '  }';
  queryString += '}';
  queryString += 'return c;';
  queryString += '"""; ';
  queryString += 'SELECT pickup_latitude, pickup_longitude, dropoff_latitude, dropoff_longitude, pickup_datetime ';
  queryString += 'FROM `' + publicProjectId + '.' + datasetId + '.' + tableName + '` ';
  queryString += 'WHERE pointInPolygon(pickup_latitude, pickup_longitude) = TRUE ';
  queryString += 'LIMIT ' + recordLimit;
  return queryString;
}

यहाँ दो चीज़ें चल रही हैं. सबसे पहले, कोड एक CREATE TEMPORARY FUNCTION स्टेटमेंट बना रहा है, जो JavaScript कोड को एनकैप्सुल करता है, ताकि दिया गया पॉइंट पॉलीगॉन में होने पर काम कर सके. पॉलीगॉन निर्देशांक x,y निर्देशांक निर्देशांक की JavaScript शृंखला को स्ट्रिंग में बदलने के लिए JSON.stringify(poly) विधि कॉल का उपयोग करके डाले जाते हैं. पॉलीगॉन ऑब्जेक्ट, SQL बनाने वाले फ़ंक्शन के आर्ग्युमेंट के तौर पर पास किया जाता है.

दूसरा, मुख्य SQL का SELECT स्टेटमेंट बनाता है. इस उदाहरण में, UDF को WHERE एक्सप्रेशन में कॉल किया जाता है.

Maps API के साथ इंटिग्रेट करना

Maps API ड्रॉइंग लाइब्रेरी के साथ इसका इस्तेमाल करने के लिए, हमें उपयोगकर्ता से बनाए गए पॉलीगॉन को सेव करना होगा और इसे SQL क्वेरी के यूडीएफ़ हिस्से में पास करना होगा.

सबसे पहले, हमें polygoncomplete ड्रॉइंग इवेंट को हैंडल करना होगा, ताकि देशांतर और अक्षांश पेयर की श्रेणी के रूप में आकार के निर्देशांक मिल सकें:

drawingManager.addListener('polygoncomplete', polygon => {
  let path = polygon.getPaths().getAt(0);
  let queryPolygon = path.map(element => {
    return [element.lng(), element.lat()];
  });
  polygonQuery(queryPolygon);
});

इसके बाद, polygonQuery फ़ंक्शन एक स्ट्रिंग के रूप में UDF JavaScript फ़ंक्शन को बना सकता है. साथ ही, SQL स्टेटमेंट भी बना सकता है, जो UDF फ़ंक्शन को कॉल करेगा.

इसके काम करने का एक उदाहरण देखने के लिए,77/map.html देखें.

आउटपुट का उदाहरण

यहां BigQuery में 2016 न्यूयॉर्क टीएलसी येलो टैक्सी डेटा से पिक अप क्वेरी करने के एक उदाहरण का उदाहरण दिया गया है. इसमें फ़्रीहैंड पॉलीगॉन का इस्तेमाल किया गया है. इसमें चुने गए डेटा को हीटमैप के तौर पर तैयार किया गया है.

09-05-2017 को सुबह 10.00.48 बजे के लिए स्क्रीन शॉट

13. इसे और आगे ले जाना

डेटा के अन्य पहलुओं को देखने के लिए, इस कोडलैब को बढ़ाने के तरीकों के लिए यहां कुछ सुझाव दिए गए हैं. आप कोड रिपॉज़िटरी में step8/map.html पर इन आइडिया का एक काम करने वाला उदाहरण देख सकते हैं.

मैपिंग ड्रॉप ऑफ़

अब तक हमने #39.7 कार से पिक अप करने की जगहें ही मैप की हैं. dropoff_latitude और dropoff_longitude कॉलम का अनुरोध करके और हीटमैप कोड में बदलाव करके उन्हें दिखाने के लिए, आप किसी खास जगह पर शुरू होने वाली टैक्सी से जुड़ी मंज़िलों की मंज़िल देख सकते हैं.

उदाहरण के लिए, आइए देखें कि टैक्सी, जब एंपायर स्टेट बिल्डिंग के आस-पास पिक अप का अनुरोध करते हैं, तब लोग कहां जाते हैं.

पिक अप की जगह के साथ-साथ इन कॉलम का अनुरोध करने के लिए, polygonSql() में SQL स्टेटमेंट का कोड बदलें.

function polygonSql(poly){
  let queryString = 'CREATE TEMPORARY FUNCTION pointInPolygon(latitude FLOAT64, longitude FLOAT64) ';
  queryString += 'RETURNS BOOL LANGUAGE js AS """ ';
  queryString += 'var polygon=' + JSON.stringify(poly) + ';';
  queryString += 'var vertx = [];';
  queryString += 'var verty = [];';
  queryString += 'var nvert = 0;';
  queryString += 'var testx = longitude;';
  queryString += 'var testy = latitude;';
  queryString += 'for(coord in polygon){';
  queryString += '  vertx[nvert] = polygon[coord][0];';
  queryString += '  verty[nvert] = polygon[coord][1];';
  queryString += '  nvert ++;';
  queryString += '}';
  queryString += 'var i, j, c = 0;';
  queryString += 'for (i = 0, j = nvert-1; i < nvert; j = i++) {';
  queryString += '  if ( ((verty[i]>testy) != (verty[j]>testy)) &&(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ){';
  queryString += '    c = !c;';
  queryString += '  }';
  queryString += '}';
  queryString += 'return c;';
  queryString += '"""; ';

  queryString += 'SELECT pickup_latitude, pickup_longitude, dropoff_latitude, dropoff_longitude, pickup_datetime ';
  queryString += 'FROM `' + publicProjectId + '.' + datasetId + '.' + tableName + '` ';
  queryString += 'WHERE pointInPolygon(pickup_latitude, pickup_longitude) = TRUE ';
  queryString += 'LIMIT ' + recordLimit;
  return queryString;
}

इसके बाद, doHeatMap फ़ंक्शन ड्रॉपऑफ़ वैल्यू का इस्तेमाल कर सकता है. नतीजे वाले ऑब्जेक्ट में एक स्कीमा होता है, जिसकी मदद से श्रेणी में इन कॉलम की जगह की जानकारी देखी जा सकती है. इस मामले में वे इंडेक्स में दूसरे और तीसरे नंबर पर होंगे. कोड को और ज़्यादा मैनेज करने लायक बनाने के लिए, इन इंडेक्स को वैरिएबल से पढ़ा जा सकता है. ध्यान दें कि हीटमैप का maxIntensity, हर पिक्सल के लिए 20 ड्रॉप ऑफ़ की संख्या को ज़्यादा से ज़्यादा के रूप में दिखाने के लिए सेट किया गया है.

कुछ वैरिएबल जोड़ें, ताकि आप हीटमैप डेटा के लिए इस्तेमाल किए जाने वाले कॉलम बदल सकें.

// Show query results as a Heatmap.
function doHeatMap(rows){
  let latCol = 2;
  let lngCol = 3;
  let heatmapData = [];
  if (heatmap!=null){
    heatmap.setMap(null);
  }
  for (let i = 0; i < rows.length; i++) {
      let f = rows[i].f;
      let coords = { lat: parseFloat(f[latCol].v), lng: parseFloat(f[lngCol].v) };
      let latLng = new google.maps.LatLng(coords);
      heatmapData.push(latLng);
  }
  heatmap = new google.maps.visualization.HeatmapLayer({
      data: heatmapData,
      maxIntensity: 20
  });
  heatmap.setMap(map);
}

यहां एक हीटमैप दिया गया है, जिसमें 2016 में एंपायर स्टेट बिल्डिंग के आस-पास सभी पिकअप की संख्या में अंतर की जानकारी दी गई थी. आपको खास तौर पर Times Square के आस-पास, मिडटाउन डेस्टिनेशन की बड़ी संख्या (लाल रंग के ब्लॉक) दिख सकते हैं. इसके अलावा, इस ज़ूम लेवल पर न दिखाई जाने वाली 23वीं स्ट्रीट और 14वीं स्ट्रीट के बीच पांचवीं ऐवेन्यू पर ला ग्वार्डिया और JFK हवाई अड्डे हैं. साथ ही, वर्ल्ड ट्रेड सेंटर और बैटरी पार्क भी हैं.

09-05-2017 को सुबह 10.40.01 पर स्क्रीन शॉट मिला.png

बेसमैप को बेहतर बनाना

जब आप Maps JavaScript API का इस्तेमाल करके Google Maps बनाते हैं, तो आप JSON ऑब्जेक्ट का इस्तेमाल करके मैप की स्टाइल सेट कर सकते हैं. डेटा विज़ुअलाइज़ेशन के लिए, मैप में रंगों को म्यूट करना उपयोगी हो सकता है. आप mapstyle.withgoogle.com पर Google Maps API स्टाइलिंग विज़र्ड का इस्तेमाल करके, मैप स्टाइल बना सकते हैं और उन्हें आज़मा सकते हैं.

आप किसी मैप ऑब्जेक्ट को शुरू करते समय या उसके बाद बाद में मैप शैली सेट कर सकते हैं. यहां #39; initMap() फ़ंक्शन में अपनी पसंद के मुताबिक स्टाइल जोड़ने का तरीका बताया गया है:

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: 40.744593, lng: -73.990370}, // Manhattan, New York.
  zoom: 12,
  styles: [
    {
        "elementType": "geometry",
          "stylers": [
            {
              "color": "#f5f5f5"
            }
          ]
        },
        {
          "elementType": "labels.icon",
            "stylers": [
              {
                "visibility": "on"
              }
            ]
        },
        {
          "featureType": "water",
            "elementType": "labels.text.fill",
              "stylers": [
                {
                  "color": "#9e9e9e"
                }
              ]
        }
      ]
    });
  setUpDrawingTools();
}

नीचे दिए गए सैंपल स्टाइल में ग्रेस्केल मैप है, जिसमें पसंद की जगह के लेबल हैं.

[
  {
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#f5f5f5"
      }
    ]
  },
  {
    "elementType": "labels.icon",
    "stylers": [
      {
        "visibility": "on"
      }
    ]
  },
  {
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#616161"
      }
    ]
  },
  {
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#f5f5f5"
      }
    ]
  },
  {
    "featureType": "administrative.land_parcel",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#bdbdbd"
      }
    ]
  },
  {
    "featureType": "poi",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#eeeeee"
      }
    ]
  },
  {
    "featureType": "poi",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#757575"
      }
    ]
  },
  {
    "featureType": "poi.park",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#e5e5e5"
      }
    ]
  },
  {
    "featureType": "poi.park",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#9e9e9e"
      }
    ]
  },
  {
    "featureType": "road",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#ffffff"
      }
    ]
  },
  {
    "featureType": "road.arterial",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#757575"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#dadada"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#616161"
      }
    ]
  },
  {
    "featureType": "road.local",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#9e9e9e"
      }
    ]
  },
  {
    "featureType": "transit.line",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#e5e5e5"
      }
    ]
  },
  {
    "featureType": "transit.station",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#eeeeee"
      }
    ]
  },
  {
    "featureType": "water",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#c9c9c9"
      }
    ]
  },
  {
    "featureType": "water",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#9e9e9e"
      }
    ]
  }
]

उपयोगकर्ता का सुझाव, शिकायत या राय देना

आम तौर पर, BigQuery कुछ ही सेकंड में जवाब देता है. हालांकि, कभी-कभी उपयोगकर्ता को यह दिखाना ज़रूरी होता है कि क्वेरी चालू होने पर कोई गड़बड़ी हो रही है.

अपने वेब पेज पर कुछ यूज़र इंटरफ़ेस (यूआई) जोड़ें, जो checkJobStatus() फ़ंक्शन का जवाब दिखाते हैं. साथ ही, एक ऐनिमेटेड ग्राफ़िक जोड़ते हैं, जो यह बताता है कि क्वेरी चल रही है.

इस जानकारी में, क्वेरी की अवधि, लौटाए गए डेटा की संख्या, और प्रोसेस किया गया डेटा शामिल होता है.

पेज के लिए <div> बनाने के लिए, मैप के बाद कुछ एचटीएमएल जोड़ें. यह पैनल क्वेरी के नतीजे की संख्या, क्वेरी होने में लगा समय, और प्रोसेस किए गए डेटा की मात्रा दिखाएगा.

<div id="menu">
    <div id="stats">
        <h3>Statistics:</h3>
        <table>
            <tr>
                <td>Total Locations:</td><td id="rowCount"> - </td>
            </tr>
            <tr>
                <td>Query Execution:</td><td id="duration"> - </td>
            </tr>
            <tr>
                <td>Data Processed:</td><td id="bytes"> - </td>
            </tr>
        </table>
    </div>
</div>

इस पैनल के दिखने और उसके पोज़िशन को सीएसएस कंट्रोल करती है. मैप के टाइप बटन और ड्रॉइंग टूलबार के नीचे, सबसे ऊपर बाएं कोने में पैनल को रखने के लिए, सीएसएस को जोड़ें, जैसा कि नीचे दिए गए स्निपेट में है.

#menu {
  position: absolute; 
  background: rgba(255, 255, 255, 0.8); 
  z-index: 1000; 
  top: 50px; 
  left: 10px; 
  padding: 15px;
}
#menu h1 {
  margin: 0 0 10px 0;
  font-size: 1.75em;
}
#menu div {
  margin: 5px 0px;
}

ऐनिमेट किए गए ग्राफ़िक को पेज पर जोड़ा जा सकता है, लेकिन ज़रूरी होने तक उसे छिपाया जा सकता है. साथ ही, BigQuery काम चलने के दौरान इसे दिखाने के लिए कुछ JavaScript और सीएसएस कोड भी इस्तेमाल किए जा सकते हैं.

ऐनिमेट किया गया ग्राफ़िक दिखाने के लिए कुछ एचटीएमएल जोड़ें. कोड रिपॉज़िटरी के img फ़ोल्डर में loader.gif नाम की इमेज फ़ाइल है.

<img id="spinner" src="img/loader.gif">

इमेज को सही जगह पर लाने के लिए कुछ सीएसएस जोड़ें और ज़रूरत पड़ने तक इसे डिफ़ॉल्ट रूप से छिपाएं.

#spinner {
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -32px; 
  margin-top: -32px; 
  opacity: 0; 
  z-index: -1000;
}

आखिर में, स्थिति पैनल को अपडेट करने के लिए JavaScript जोड़ें और क्वेरी के चालू होने पर ग्राफ़िक दिखाएं या छिपाएं. response ऑब्जेक्ट का इस्तेमाल, पैनल को अपडेट करने के लिए किया जा सकता है. यह, इस बात पर निर्भर करता है कि कौनसी जानकारी उपलब्ध है.

किसी मौजूदा नौकरी की जांच करते समय, response.statistics प्रॉपर्टी का इस्तेमाल किया जा सकता है. काम पूरा होने के बाद, आप response.totalRows और response.totalBytesProcessed प्रॉपर्टी को ऐक्सेस कर सकते हैं. जैसा कि नीचे दिए गए कोड के सैंपल में दिखाया गया है, इससे उपयोगकर्ता को मिलीसेकंड को सेकंड में और बाइट को गीगाबाइट में बदलने में मदद मिलती है.

function updateStatus(response){
  if(response.statistics){
    let durationMs = response.statistics.endTime - response.statistics.startTime;
    let durationS = durationMs/1000;
    let suffix = (durationS ==1) ? '':'s';
    let durationTd = document.getElementById("duration");
    durationTd.innerHTML = durationS + ' second' + suffix;
  }
  if(response.totalRows){
    let rowsTd = document.getElementById("rowCount");
    rowsTd.innerHTML = response.totalRows;
  }
  if(response.totalBytesProcessed){
    let bytesTd = document.getElementById("bytes");
    bytesTd.innerHTML = (response.totalBytesProcessed/1073741824) + ' GB';
  }
}

checkJobStatus() कॉल के जवाब आने और क्वेरी के नतीजे मिलने पर इस तरीके को कॉल करें. उदाहरण के लिए:

// Poll a job to see if it has finished executing.
function checkJobStatus(jobId){
  let request = gapi.client.bigquery.jobs.get({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response => {
    //Show progress to the user
    updateStatus(response);

    if (response.status.errorResult){
      // Handle any errors.
      console.log(response.status.error);
      return;
    }
    if (response.status.state == 'DONE'){
      // Get the results.
      clearTimeout(jobCheckTimer);
      getQueryResults(jobId);
      return;
    }
    // Not finished, check again in a moment.
    jobCheckTimer = setTimeout(checkJobStatus, 500, [jobId]); 
  });
}

// When a BigQuery job has completed, fetch the results.
function getQueryResults(jobId){
  let request = gapi.client.bigquery.jobs.getQueryResults({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response => {
    doHeatMap(response.result.rows);
    updateStatus(response);
  })
}

ऐनिमेट किए गए ग्राफ़िक को टॉगल करने के लिए, कोई फ़ंक्शन जोड़ें जिससे वह दिखाई दे. यह फ़ंक्शन इसे भेजे गए किसी भी एचटीएमएल डीओएम एलिमेंट की अपारदर्शिता को टॉगल करेगा.

function fadeToggle(obj){
    if(obj.style.opacity==1){
        obj.style.opacity = 0;
        setTimeout(() => {obj.style.zIndex = -1000;}, 1000);
    } else {
        obj.style.zIndex = 1000;
        obj.style.opacity = 1;
    }
}

आखिर में, क्वेरी प्रोसेस करने से पहले और क्वेरी का नतीजा BigQuery से वापस आने के बाद, इस तरीके को कॉल करें.

जब उपयोगकर्ता आयत बनाने की प्रक्रिया पूरी कर लेता है, तब यह कोड fadeToggle फ़ंक्शन को कॉल करता है.

drawingManager.addListener('rectanglecomplete', rectangle => {
  //show an animation to indicate that something is happening.
  fadeToggle(document.getElementById('spinner'));
  rectangleQuery(rectangle.getBounds());
});

क्वेरी का जवाब मिलने पर, ऐनिमेशन वाले ग्राफ़िक को छिपाने के लिए, fadeToggle() को फिर से कॉल करें.

// When a BigQuery job has completed, fetch the results.
function getQueryResults(jobId){
  let request = gapi.client.bigquery.jobs.getQueryResults({
    'projectId': billingProjectId,
    'jobId': jobId
  });
  request.execute(response => {
    doHeatMap(response.result.rows);
    //hide the animation.
    fadeToggle(document.getElementById('spinner'));
    updateStatus(response);
  })
}

पेज कुछ ऐसा दिखना चाहिए.

10-05-2017 का दोपहर 2:32.19 पर स्क्रीन शॉट है.png

step8/map.html में पूरा उदाहरण देखें.

14. इन बातों का ध्यान रखें

बहुत ज़्यादा मार्कर

अगर आप बहुत बड़ी टेबल के साथ काम कर रहे हैं, तो आपकी क्वेरी, मैप पर बेहतर तरीके से दिखने के लिए कई लाइनें दिखा सकती है. नतीजों को सीमित करने के लिए, WHERE क्लॉज़ या LIMIT स्टेटमेंट जोड़ें.

कई मार्कर बनाने पर, मैप को पढ़ा नहीं जा सकेगा. आप सघनता दिखाने के लिए HeatmapLayer या हर क्लस्टर में एक सिंबल का इस्तेमाल करके डेटा पॉइंट कहां हैं, यह दिखाने के लिए क्लस्टर मार्कर का इस्तेमाल कर सकते हैं. ज़्यादा जानकारी के लिए, मार्कर क्लस्टरिंग ट्यूटोरियल देखें.

क्वेरी का ऑप्टिमाइज़ेशन करना

BigQuery हर क्वेरी के साथ पूरी टेबल को स्कैन करेगा. BigQuery कोटा के इस्तेमाल को ऑप्टिमाइज़ करने के लिए, सिर्फ़ अपनी क्वेरी में ज़रूरी कॉलम चुनें.

अगर आप अक्षांश और देशांतर को स्ट्रिंग के बजाय फ़्लोट के रूप में स्टोर करते हैं, तो क्वेरी ज़्यादा तेज़ होंगी.

दिलचस्प नतीजे एक्सपोर्ट करें

यहां दिए गए उदाहरणों में BigQuery टेबल के लिए असली उपयोगकर्ता की पुष्टि होना ज़रूरी है. यह उपयोगकर्ता के इस्तेमाल के हर उदाहरण पर सही होता है. जब आपको कुछ दिलचस्प पैटर्न मिल गए हैं, तो BigQuery से नतीजे एक्सपोर्ट करके और Google Maps डेटा लेयर का इस्तेमाल करके, एक स्टैटिक डेटासेट बनाकर ज़्यादा लोगों के साथ इसे शेयर करना आसान हो सकता है.

Google Maps Platform सेवा की शर्तों को ध्यान में रखें. Google Maps Platform की कीमत के बारे में ज़्यादा जानने के लिए, ऑनलाइन दस्तावेज़ देखें.

ज़्यादा डेटा के साथ खेलें!

BigQuery में ऐसे कई सार्वजनिक डेटासेट हैं जिनमें अक्षांश और देशांतर के कॉलम हैं. उदाहरण के लिए, 2009-2016 का NYC टैक्सी डेटासेट, Uber और Lyft NYC यात्रा का डेटा, और GDELT डेटासेट.

15. बधाई हो!

हमें उम्मीद है कि इससे आप BigQuery टेबल के लिए कुछ भौगोलिक क्वेरी के साथ तेज़ी से काम कर पाएंगे, ताकि आप Google Maps पर पैटर्न को डिस्कवर करके उन्हें देख सकें. मैपिंग मुबारक हो!

आगे क्या करना है?

अगर आप Google Maps Platform या BigQuery के बारे में ज़्यादा जानना चाहते हैं, तो ये सुझाव देखें.

Google की बिना सर्वर वाली, पेटाबाइट के साइज़ की डेटा वेयरहाउस सेवा के बारे में ज़्यादा जानने के लिए, BigQuery क्या है देखें.

BigQuery API का इस्तेमाल करके एक आसान ऐप्लिकेशन बनाने के तरीके के बारे में जानें.

Google मैप पर आकार बनाने के लिए उपयोगकर्ता इंटरैक्शन चालू करने के बारे में ज़्यादा जानकारी के लिए ड्रॉइंग लाइब्रेरी के लिए डेवलपर गाइड देखें.

Google मैप पर डेटा को विज़ुअलाइज़ करने के दूसरे तरीकों पर नज़र डालें.

Google API (एपीआई) के लिए शुरुआती निर्देश देखें. इससे, आपको दूसरे एपीआई को ऐक्सेस करने के लिए क्लाइंट एपीआई के इस्तेमाल से जुड़ी बुनियादी बातों को समझने में मदद मिलेगी.