การส่งออกไปยัง BigQuery

ภาพรวม

สถาปัตยกรรมการประมวลผลของ Earth Engine ได้รับการเพิ่มประสิทธิภาพเพื่อให้การประมวลผลรูปภาพ (แบบพิกเซล) รวดเร็วและปรับขนาดได้ BigQuery ได้รับการเพิ่มประสิทธิภาพในลักษณะเดียวกันสำหรับการประมวลผลข้อมูลแบบตาราง (เวกเตอร์) ที่ปรับขนาดได้ และมีฟีเจอร์มากมายที่ทำงานร่วมกับ Earth Engine ได้เป็นอย่างดี

ตัวอย่างเวิร์กโฟลว์มีดังนี้

  • การเข้าร่วม BigQuery ขนาดใหญ่กับข้อมูลที่สร้างขึ้นใน Earth Engine
  • การกำกับเนื้อหาข้อมูลเวกเตอร์ด้วยสถิติที่มาจากภาพเพื่อประมวลผลเพิ่มเติมใน BigQuery
  • การส่งออกข้อมูลจาก Earth Engine ไปยังตาราง BigQuery ที่เพิ่มข้อมูลได้เป็นระยะๆ

หากมี Use Case อื่นๆ ที่น่าสนใจ เรายินดีรับฟัง

ข้อมูลเบื้องต้นเกี่ยวกับ BigQuery

Earth Engine จะเขียนลงในตาราง BigQuery และตารางทั้งหมดจะอยู่ในชุดข้อมูล งานส่งออกจะดำเนินการไม่สำเร็จหากไม่มีชุดข้อมูลที่ระบุใน BigQuery ดูข้อมูลเพิ่มเติมได้ที่ข้อมูลเบื้องต้นเกี่ยวกับชุดข้อมูล BigQuery

การสร้างชุดข้อมูล

ชุดข้อมูลมีตัวเลือกเวลาสร้างหลายรายการ ได้แก่ ชื่อ ภูมิภาคของพื้นที่เก็บข้อมูล และลักษณะการหมดอายุ (พร้อมกับตัวเลือกขั้นสูงอื่นๆ อีกหลายรายการ)

การสร้างชุดข้อมูลมีหลายวิธี แต่วิธีเริ่มต้นใช้งานที่ง่ายที่สุดคือผ่านคอนโซล Cloud โดยทำดังนี้

  1. ไปที่หน้า BigQuery ในคอนโซล Cloud
  2. คลิก "เปิดใช้" เพื่อเปิดใช้ API หากได้รับข้อความแจ้ง
  3. จากแท็บ "พื้นที่ทํางาน SQL" ให้คลิกเมนู 3 จุด () ข้างโปรเจ็กต์
  4. เลือกตัวเลือก "สร้างชุดข้อมูล"
  5. ทำตามคู่มือการกําหนดค่า

ดูตัวเลือกทั้งหมดในการสร้างและกําหนดค่าชุดข้อมูลได้ที่เอกสารประกอบของ BigQuery

สิทธิ์

นอกเหนือจากบทบาทและสิทธิ์มาตรฐานที่จําเป็นสําหรับใช้ Earth Engine ผู้เรียกยังต้องมีสิทธิ์ BigQuery ที่ถูกต้องในโปรเจ็กต์หรือชุดข้อมูลที่อยู่ในระบบคลาวด์ด้วย

  • bigquery.tables.get
  • bigquery.tables.create
  • bigquery.tables.updateData
  • bigquery.tables.delete
  • bigquery.jobs.create

ชุดค่าผสมของบทบาท Identity and Access Management (IAM) ที่กําหนดไว้ล่วงหน้าต่อไปนี้มีสิทธิ์ที่จําเป็น

  • bigquery.dataEditor และ bigquery.jobUser
  • bigquery.dataOwner และ bigquery.jobUser
  • bigquery.user
  • bigquery.admin

ราคา

BigQuery เป็นบริการของ Google Cloud แบบชําระเงิน คุณจึงต้องชําระเงินสําหรับการใช้งาน BigQuery รวมถึงพื้นที่เก็บข้อมูลและการวิเคราะห์ข้อมูล Earth Engine ที่คุณส่งออกไปยัง BigQuery

ดูรายละเอียดเกี่ยวกับราคาสำหรับฟีเจอร์การส่งออกไปยัง BigQuery ของ Earth Engine ได้ที่ส่วนราคาด้านล่าง

ส่งออกการกำหนดค่า

ไวยากรณ์

  Export.table.toBigQuery({
    'collection': myFeatureCollection,
    'table': 'myproject.mydataset.mytable',
    'description': 'put_my_data_in_bigquery',
    'append': true,
    'overwrite': false
  });
  task = ee.batch.Export.table.toBigQuery(
      collection=myFeatureCollection,
      table='myproject.mydataset.mytable',
      description='put_my_data_in_bigquery',
      append=True,
      overwrite=False)
  task.start()

ข้อกําหนดสคีมาอัตโนมัติหรือด้วยตนเอง

หากไม่มีตารางใน BigQuery Earth Engine จะพยายามระบุสคีมาโดยใช้พร็อพเพอร์ตี้ของ ee.Feature รายการแรกในคอลเล็กชัน นี่เป็นค่าประมาณที่ดีที่สุด และคุณอาจสร้างคอลเล็กชันที่สคีมาของฟีเจอร์แรกแตกต่างจากสคีมาของฟีเจอร์อื่นๆ ได้

หากต้องการสคีมาเฉพาะในตาราง BigQuery ให้กําหนดค่าโดยสร้างตารางว่างที่มีสคีมาเป้าหมาย

ชื่อพร็อพเพอร์ตี้

พร็อพเพอร์ตี้ในฟีเจอร์ Earth Engine สอดคล้องกับคอลัมน์ใน BigQuery Earth Engine ใช้ชื่อ "geo" เพื่อเขียนเรขาคณิต ee.Feature (ตัวเลือก ".geo") ไปยัง BigQuery

โปรดตรวจสอบว่าออบเจ็กต์ ee.Feature ของคุณมีพร็อพเพอร์ตี้ที่เป็นชื่อคอลัมน์ที่ถูกต้องและไม่มีชื่อเป็น "geo" (เนื่องจากชื่อนี้ใช้สำหรับเรขาคณิตขององค์ประกอบซึ่งไม่มีชื่อใน Earth Engine) เพื่อหลีกเลี่ยงการต้องเปลี่ยนชื่อ

อักขระที่ไม่ถูกต้องในชื่อพร็อพเพอร์ตี้ทําให้การส่งออกไม่สําเร็จเนื่องจากข้อจํากัดของชื่อคอลัมน์ BigQuery

การแปลงประเภท

ระบบจะแปลงข้อมูล Earth Engine (ค่าของพร็อพเพอร์ตี้ ee.Feature) เป็นประเภท BigQuery ที่เทียบเท่าเมื่อเป็นไปได้ โปรดทราบว่าสคีมาตารางจะควบคุมความสามารถในการมีหรือไม่มีค่า ไม่ใช่ประเภท

ประเภท Earth Engine ประเภท BigQuery หมายเหตุ
ee.String STRING
ee.Number FLOAT หรือ INTEGER
ee.Geometry GEOGRAPHY
ee.Date TIMESTAMP
ee.ByteString BYTES
ee.Array STRUCT<ARRAY<INT64>, ARRAY<INT64|FLOAT64>> ดูส่วนอาร์เรย์
ee.* ประเภทอื่นๆ ไม่รองรับ [not_supported] ดูส่วนค่า JSON

อาร์เรย์

Earth Engine จะส่งออก ee.Array หลายมิติข้อมูลเป็น STRUCT<ARRAY<INT64> dimensions, ARRAY<INT64|FLOAT64> values> ซึ่งคล้ายกับรูปแบบที่ฟังก์ชัน ML.DECODE_IMAGE ของ BigQuery ใช้

อาร์เรย์แรกในโครงสร้าง dimensions มีมิติข้อมูลของอาร์เรย์ Earth Engine ซึ่งก็คือ d1 ถึง dn

อาร์เรย์ที่ 2 ในโครงสร้าง values มีค่าทั้งหมดในอาร์เรย์มิติหลายรายการ ซึ่งผสานเป็นอาร์เรย์ BigQuery รายการเดียว จํานวนค่าทั้งหมดในอาร์เรย์ที่ผสานคือ ni=1di และค่าที่ดัชนี (ii,,in) ในอาร์เรย์ Earth Engine เดิมจะสอดคล้องกับค่าที่ดัชนีต่อไปนี้ในอาร์เรย์ที่ผสาน

nj=1(ijnk=j+1dk)

สําหรับกรณีทั่วไป นิพจน์การจัดทําดัชนีสําหรับอาร์เรย์ values มีดังนี้

ขนาดอาร์เรย์ มิติข้อมูล นิพจน์การจัดทําดัชนี
1 มิติ d1 [i1]
2 มิติ d1, d2 [(i1 * d2) + i2]
3 มิติ d1, d2, d3 [(i1 * d2 * d3) + (i2 * d3) + i3]

ตัวอย่างเช่น ลองดู2x3x4อาร์เรย์ Earth Engine ต่อไปนี้

    ee.Array([
      [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12]
      ],
      [
        [13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]
      ]
    ]);

อาร์เรย์นี้จะแปลเป็น STRUCT ของ BigQuery ที่มีองค์ประกอบ dimensions เป็นอาร์เรย์ [2, 3, 4] และองค์ประกอบ values เป็นอาร์เรย์แบบแบน [1, 2, 3, 4, 5, 6, 7, 8, ..., 21, 22, 23, 24] ดัชนีในอาร์เรย์ที่ผสานจะคํานวณได้ดังนี้ [(i1 * 12) + (i2 * 4) + i3]

ค่า JSON

หากต้องการรองรับ Structured Data ที่สมบูรณ์ยิ่งขึ้นภายในเซลล์ คุณสามารถเข้ารหัสค่า Earth Engine เป็นออบเจ็กต์ JSON ได้ BigQuery รองรับการดำเนินการ SQL กับข้อมูลที่เข้ารหัส JSON ซึ่งช่วยให้สามารถค้นหาที่ "มองเข้าไปใน" ค่า JSON ที่เข้ารหัสซึ่งคุณสร้างใน Earth Engine

var states = ee.FeatureCollection('TIGER/2018/States');
var mod11a1 = ee.ImageCollection('MODIS/061/MOD11A1');

// Find the max day and night temperatures per pixel for a given time.
var maxTemp = mod11a1
    .select(['LST_Day_1km', 'LST_Night_1km'])
    .filterDate('2023-05-15', '2023-05-25')
    .max();

// Annotate each state with its max day/night temperatures.
var annotatedStates = states.map(function (e) {
  var dict = maxTemp.reduceRegion({
    reducer: ee.Reducer.max(),
    geometry: e.geometry(),
    scale: 10 * 1000,  // 10 km
  });
  // Convert the dictionary to JSON and add it as a property.
  return e.set('maxTemp', ee.String.encodeJSON(dict));
});

Export.table.toBigQuery(annotatedStates);

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap
states = ee.FeatureCollection('TIGER/2018/States')
mod11a1 = ee.ImageCollection('MODIS/061/MOD11A1')

# Find the max day and night temperatures per pixel for a given time.
max_temp = (
    mod11a1.select(['LST_Day_1km', 'LST_Night_1km'])
    .filterDate('2023-05-15', '2023-05-25')
    .max()
)


def get_max_temp_for_state(e):
  max_temp_dict = max_temp.reduceRegion(
      reducer=ee.Reducer.max(),
      geometry=e.geometry(),
      scale=10 * 1000,  # 10 km
  )
  # Convert the dictionary to JSON and add it as a property.
  return e.set('maxTemp', ee.String.encodeJSON(max_temp_dict))


# Annotate each state with its max day/night temperatures.
annotated_states = states.map(get_max_temp_for_state)

task = ee.batch.Export.table.toBigQuery(
    collection=annotated_states, table='myproject.mydataset.mytable'
)
task.start()

การแปลงเรขาคณิต

BigQuery รองรับการฉายภาพที่แตกต่างกันอย่างจำกัด ดังนั้นเรขาคณิตทั้งหมดของ Earth Engine จึงได้รับการเปลี่ยนรูปแบบเป็นเรขาคณิตเชิงเรขา EPSG:4326 โดยใช้ความคลาดเคลื่อน 1 เมตร

หากต้องการควบคุมกระบวนการเปลี่ยนรูปแบบนี้อย่างละเอียดยิ่งขึ้น คุณสามารถแมปองค์ประกอบและเปลี่ยนรูปแบบเรขาคณิตด้วยตนเองได้ เช่น

var transformedCollection = originalCollection.map(function transformGeo(e) {
  var myErrorMargin = 10 * 1000;  // meters
  return e.setGeometry(e.geometry(myErrorMargin, 'EPSG:4326', true));
});

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap
def transform_geo(e):
  my_error_margin = 10 * 1000  # meters
  return e.setGeometry(e.geometry(my_error_margin, 'EPSG:4326', True))


transformed_collection = original_collection.map(transform_geo)

ประสิทธิภาพ

ประสิทธิภาพของ Earth Engine

การคํานวณของ Earth Engine มักเป็นคอขวดสําหรับการดําเนินการ Export ด้วยเหตุนี้ คุณจึงต้องจัดระเบียบการประมวลผลเพื่อให้เกิดการทำงานแบบขนานสูงสุด การคํานวณใดๆ ที่ฝังอยู่ในการประมวลผลแบบอนุกรม (เช่น ee.FeatureCollection.iterate()) อาจทําให้การส่งออกทํางานช้าหรือดำเนินการไม่สำเร็จ

ประสิทธิภาพใน BigQuery

การจัดโครงสร้างและการจัดกลุ่มข้อมูลอย่างถูกต้องเป็นวิธีที่ดีที่สุดในการช่วยให้การค้นหาใน BigQuery มีประสิทธิภาพ หากไม่มีตารางอยู่ใน BigQuery อยู่แล้ว ระบบจะจัดกลุ่มตารางที่ส่งออกจาก Earth Engine ตามเรขาคณิตขององค์ประกอบ (หากมี) การคลัสเตอร์ตามฟิลด์ภูมิศาสตร์เป็นวิธีที่พบได้บ่อยมากสําหรับข้อมูลเชิงพื้นที่ ซึ่งจะช่วยปรับปรุงประสิทธิภาพและลดต้นทุนสําหรับการค้นหาที่ใช้ตัวกรองเชิงพื้นที่ ซึ่งมักใช้กับการดำเนินการ BigQuery เช่น

WHERE ST_DWithin(<table_column>, <constant_geography>, <distance>)
WHERE ST_Intersects(<table_column>, <constant_geography>)

โดยทั่วไปแล้ว การเพิ่มการคลัสเตอร์ลงในตารางที่ไม่ได้จัดกลุ่มจะไม่ก่อให้เกิดอันตรายใดๆ แม้ว่าอาจเพิ่มเวลาในการโหลดข้อมูลลงในตารางเล็กน้อย ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพการค้นหาได้ที่เอกสารประกอบของ BigQuery

โปรดทราบว่าการตั้งค่าการคลัสเตอร์จะมีผลกับข้อมูลใหม่ที่เขียนลงในตารางเท่านั้น

สาธิต: การใช้ reduceRegions

ในบางกรณี คุณอาจใช้ reduceRegions เพื่อให้ได้การทำงานแบบขนานมากที่สุดจากโครงสร้างพื้นฐานการประมวลผลของ Earth Engine ตัวอย่างนี้สาธิตวิธีใช้การเรียก reduceRegions น้อยลง (ไม่กี่ร้อยรายการ) แทนการเรียก reduceRegion หลายหมื่นรายการ (แนวทางทั่วไปในการแมปฟังก์ชันกับคอลเล็กชัน)

var lucas = ee.FeatureCollection('JRC/LUCAS_HARMO/COPERNICUS_POLYGONS/V1/2018');
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');

// Fetch the unique date values from the dataset.
var dates = lucas.aggregate_array('survey_date')
    .distinct()
    .map(function (date) {
      return ee.Date.parse('dd/MM/yy', date);
    });

// For each date, annotate the LUCAS samples with the Sentinel-2 band values for
// a two-week window.
function getLucasSamplesForDate(date) {
  date = ee.Date(date);
  var imageForDate = s2
    .filterDate(
      date.advance(-1, 'week'),
      date.advance(1, 'week'))
    .select('B.*');
  var median = imageForDate.median();
  var lucasForDate = lucas.filter(
    ee.Filter.equals('survey_date', date.format('dd/MM/yy')));
  var sample = median.reduceRegions({
    collection: lucasForDate,
    reducer: ee.Reducer.mean(),
    scale: 10,
    tileScale: 8,
  });
  return sample;
}

// Flatten the collection.
var withSamples =
    ee.FeatureCollection(dates.map(getLucasSamplesForDate))
      .flatten();

Export.table.toBigQuery({
  collection: withSamples,
  description: 'lucas_s2_annotated'
});

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap
lucas = ee.FeatureCollection('JRC/LUCAS_HARMO/COPERNICUS_POLYGONS/V1/2018')
s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')

# Fetch the unique date values from the dataset.
dates = (
    lucas.aggregate_array('survey_date')
    .distinct()
    .map(lambda date: ee.Date.parse('dd/MM/yy', date))
)


# For each date, annotate the LUCAS samples with the Sentinel-2 band values for
# a two-week window.
def get_lucas_samples_for_date(date):
  date = ee.Date(date)
  image_for_date = s2.filterDate(
      date.advance(-1, 'week'), date.advance(1, 'week')
  ).select('B.*')
  median = image_for_date.median()
  lucas_for_date = lucas.filter(
      ee.Filter.equals('survey_date', date.format('dd/MM/yy'))
  )
  sample = median.reduceRegions(
      collection=lucas_for_date,
      reducer=ee.Reducer.mean(),
      scale=10,
      tileScale=8,
  )
  return sample


# Flatten the collection.
with_samples = ee.FeatureCollection(
    dates.map(get_lucas_samples_for_date)
).flatten()

task = ee.batch.Export.table.toBigQuery(
    collection=with_samples,
    table='myproject.mydataset.mytable',
    description='lucas_s2_annotated',
)
task.start()

การประมวลผลแบบขนานของงาน

เมื่อใช้ตัวเลือก {append: true} หลายงานจะเขียนข้อมูลลงในตาราง BigQuery ได้พร้อมกัน นี่เป็นกลไกในการเขียนข้อมูลที่มีอัตราผ่านข้อมูลสูงขึ้น แต่ความซับซ้อนก็เพิ่มขึ้นด้วย (การจัดการคิวงาน การลองอีกครั้ง ฯลฯ)

ความแตกต่างด้านประสิทธิภาพระหว่างพารามิเตอร์ append กับ overwrite

โปรดทราบว่าการเขียนทับจะช้ากว่าการต่อท้าย เนื่องจาก BigQuery ต้องประมวลผลข้อมูลใหม่ก่อนที่จะเขียนทับข้อมูลเก่า การตั้งค่าพารามิเตอร์ {overwrite: true} เมื่อส่งออกไปยังตาราง BigQuery ที่มีอยู่จะทริกเกอร์กระบวนการเขียนทับอย่างปลอดภัย ดังนี้

  1. ตารางชั่วคราว: ระบบจะส่งออกข้อมูลไปยังตารางชั่วคราวใหม่ภายในชุดข้อมูลปลายทาง
  2. การเขียนทับแบบอะตอม: ระบบจะคัดลอกเนื้อหาของตารางชั่วคราวไปยังตารางปลายทางสุดท้าย ซึ่งจะแทนที่ข้อมูลที่มีอยู่ในธุรกรรมแบบอะตอมรายการเดียว
  3. ล้างข้อมูล: ลบตารางชั่วคราว

วิธีนี้ช่วยให้มั่นใจได้ว่าข้อผิดพลาดระหว่างการส่งออกจะไม่ทำให้ข้อมูลที่มีอยู่เสียหาย สําหรับตารางขนาดเล็ก โดยปกติความล่าช้าจะอยู่ที่ 2-3 นาที

ทางเลือกที่มีประสิทธิภาพสูง

สำหรับเวิร์กโฟลว์ที่ต้องใช้อัตราข้อมูลที่สูงมาก ให้พิจารณาใช้ GeoBeam เพื่อย้ายข้อมูลจาก Earth Engine ไปยัง BigQuery การดำเนินการนี้ต้องใช้การกำหนดค่าและโครงสร้างพื้นฐานเพิ่มเติม เราจึงขอแนะนำให้เริ่มต้นด้วยฟังก์ชันการทำงานของ Earth Engine ในตัว

ราคา

การส่งออกไปยัง BigQuery เป็นกระบวนการแบบเป็นกลุ่มซึ่งใช้เวลา EECU แบบเป็นกลุ่ม หากคุณใช้ Earth Engine เชิงพาณิชย์หรือเพื่อดำเนินการ ระบบจะเรียกเก็บเงินจากคุณสำหรับเวลา EECU ที่งานใช้ไปเมื่อส่งออกข้อมูลไปยัง BigQuery คุณสามารถตรวจสอบการใช้งานทั้งหมดได้ด้วยเครื่องมือตรวจสอบเดียวกันกับที่ใช้กับส่วนที่เหลือของ Earth Engine

บัญชีสำหรับการเรียกเก็บเงินใน Cloud

หากต้องการเขียนข้อมูลไปยัง BigQuery โปรเจ็กต์ที่อยู่ในระบบคลาวด์ที่เกี่ยวข้องต้องเปิดใช้บัญชีการเรียกเก็บเงิน ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าบัญชีสำหรับการเรียกเก็บเงินได้ที่เอกสารบัญชีสำหรับการเรียกเก็บเงินใน Cloud

ขาออก

ระบบจะเรียกเก็บค่าใช้จ่ายขาเข้าและขาออกทั้งหมดเป็นการรับส่งข้อมูลเครือข่ายมาตรฐาน

Earth Engine โฮสต์ในสหรัฐอเมริกาเท่านั้น แต่ชุดข้อมูล BigQuery โฮสต์ได้ในภูมิภาคอื่นๆ อีกหลายแห่ง การเขียนข้อมูลจาก Earth Engine ไปยัง BigQuery อาจทำให้เกิดปริมาณการใช้งานเครือข่ายจำนวนมาก ทั้งนี้ขึ้นอยู่กับภูมิภาคและปริมาณข้อมูลที่เกี่ยวข้อง

ปัญหาที่ทราบ

การวางแนวสําหรับรูปหลายเหลี่ยมขนาดใหญ่

ฟังก์ชัน BigQuery Export จะพลิกกลับรูปหลายเหลี่ยมที่ใหญ่กว่าครึ่งวงกลมโดยกลับการวางแนว (เปลี่ยนรูปหลายเหลี่ยมเป็นรูปเชิงเรขาคณิตที่เติมเต็มกัน) ในบางกรณี รูปหลายเหลี่ยมที่ใหญ่กว่าครึ่งวงกลมอาจโหลดไม่สำเร็จ

หากจําเป็น คุณสามารถแก้ไขรูปหลายเหลี่ยมที่กลับด้านใน BigQuery ได้โดยกลับด้านอีกครั้งโดยใช้นิพจน์ BigQuery ST_Difference(ST_GeogFromText('fullglobe'), geo)

ดูข้อมูลเพิ่มเติมได้ที่ที่นี่