التوقعات

تم تصميم Earth Engine بحيث لا تقلق كثيرًا بشأن إسقاطات الخرائط عند إجراء العمليات الحسابية. كما هو الحال مع النطاق، يتم تحديد الإسقاط الذي يتم فيه إجراء العمليات الحسابية على أساس "السحب". على وجه التحديد، يتم طلب المدخلات في ناتج الإسقاط. يمكن تحديد الإخراج من مَعلمة دالة (مثل crs)، أو من عنصرَي رمز "محرر الرموز" وخريطة geemap (التي تستخدم إسقاط maps mercator (EPSG:3857))، أو من خلال طلب reproject(). عند عرض الصور في "محرر الرموز" أو geemap، يتم طلب الإدخالات في maps mercator. فكِّر في العملية البسيطة التالية على صورة MODIS التي تستخدم أسلوب تصويب جيوبولتي:

// The input image has a SR-ORG:6974 (sinusoidal) projection.
var image = ee.Image('MODIS/061/MOD13A1/2014_05_09').select(0);

// Normalize the image and add it to the map.
var rescaled = image.unitScale(-2000, 10000);
var visParams = {min: 0.15, max: 0.7};
Map.addLayer(rescaled, visParams, 'Rescaled');

اطّلِع على صفحة بيئة Python للحصول على معلومات عن واجهة برمجة التطبيقات Python API واستخدام IDE geemap لتطوير التطبيقات التفاعلي.

import ee
import geemap.core as geemap
# The input image has a SR-ORG:6974 (sinusoidal) projection.
image = ee.Image('MODIS/061/MOD13A1/2014_05_09').select(0)

# Normalize the image and add it to the map.
rescaled = image.unitScale(-2000, 10000)
vis_params = {'min': 0.15, 'max': 0.7}
m = geemap.Map()
m.add_layer(rescaled, vis_params, 'Rescaled')
m

يظهر ترتيب العمليات في نموذج التعليمات البرمجية هذا في الشكل 1. يُرجى ملاحظة أنّ إسقاط الإدخال يتم تحديده حسب الإخراج، وتحديدًا إسقاط Mercator للخرائط لعرض الخريطة في "محرر الرموز". يتم نشر هذا الإسقاط مرة أخرى من خلال تسلسل العمليات على النحو التالي: يتم طلب الإدخالات في خرائط Mercator، بمقياس يحدّده مستوى التكبير في الخريطة.

projection
الشكل 1. مخطّط بياني للعمليات المقابلة لعرض صورة MODIS في خريطة "أداة تعديل الرموز" يتم تحديد التوقّعات (على يمين مخطّط العملية) لكل عملية من خلال الإخراج. تشير الخطوط المنحنية إلى تدفق المعلومات إلى إعادة الإسقاط: على وجه التحديد، الإسقاط والنطاق الناتجَين.

في Earth Engine، يتم تحديد الإسقاطات من خلال نظام مرجعي للإحداثيات (CRS أو مَعلمة crs في العديد من الطرق). يمكنك التحقّق من عرض الصورة من خلال طلب projection() عليها:

var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318').select(0);
print('Projection, crs, and crs_transform:', image.projection());
print('Scale in meters:', image.projection().nominalScale());

اطّلِع على صفحة بيئة Python للحصول على معلومات عن واجهة برمجة التطبيقات Python API واستخدام IDE geemap لتطوير التطبيقات التفاعلي.

import ee
import geemap.core as geemap
image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318').select(0)
display('Projection, crs, and crs_transform:', image.projection())
display('Scale in meters:', image.projection().nominalScale())

يُرجى العِلم أنّه من خلال استدعاء nominalScale() على ee.Projection الذي تم إرجاعه من خلال projection()، يمكنك تحديد الدقة الأصلية للصورة. الدقة الأصلية هي مقياس البكسل الاسمي بالمتر لأقل مستوى من هرم الصور. بما أنّ كلّ نطاق من النطاقات في الصورة يمكن أن يكون له مقياس و/أو إسقاط مختلفان، إذا استدعيت projection() في صورة تتضمّن نطاقًا واحدًا على الأقلّ لا يتضمّن الإسقاط نفسه مثل النطاقات الأخرى، قد يظهر لك خطأ مثل:

الإسقاط التلقائي

ما لم تكن بحاجة إلى إجراء عملية الحساب في إسقاط معيّن، ليس هناك بشكل عام حاجة إلى تحديد إسقاط. ولن تطلب منك أداة Earth Engine تحديد إسقاط و/أو مقياس إلا في حال كانت النتائج غير واضحة. يمكن أن ينتج الالتباس عن تصغير ImageCollection يحتوي على صور بطرق إسقاط مختلفة (أي إنشاء تركيبة). إذا كانت الصورة عبارة عن تركيبة أو فسيفساء من صور الإدخال التي تتضمّن إسقاطات مختلفة، سيتم استخدام إسقاط التلقائي، وهو WGS84 بمقياس درجة واحدة. على سبيل المثال:

var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');
var mosaic = collection.filterDate('2018-01-01', '2019-01-01').mosaic();
print(mosaic.projection());

اطّلِع على صفحة بيئة Python للحصول على معلومات عن واجهة برمجة التطبيقات Python API واستخدام IDE geemap لتطوير التطبيقات التفاعلي.

import ee
import geemap.core as geemap
collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
mosaic = collection.filterDate('2018-01-01', '2019-01-01').mosaic()
display(mosaic.projection())

إذا حاولت استخدام صورة مثل هذه في عملية حسابية، قد تظهر لك رسالة خطأ مثل:

بشكل عام، لا تكون التجميعات على نطاق درجة واحدة مطلوبة أو مقصودة، لذا تقدّم أداة Earth Engine هذا التذكير الودي لتقديم مواصفات كاملة للناتج.

غالبًا ما يجد المستخدمون هذا السلوك مربكًا ويقلّقهم بشأن معلومات التوقع "المفقودة"، ولكن لا يتم احتساب البكسلات في الواقع إلى أن يتمّ استخدامها (مزيد من المعلومات)، وفي هذه المرحلة، يكون هناك دائمًا توقع للإخراج يصاحب الطلب الذي يحدّد كيفية احتساب المركب.

في الغالبية العظمى من حالات الاستخدام، لا يشكّل عدم توفّر إسقاط مشكلة، بل هو في الواقع تحسين قيّم، لأنّه يسمح بمعاينة النتائج في أي مستوى تكبير أو تصغير بدون الحاجة إلى الانتظار حتى تكتمل عملية احتساب الدقة الكاملة. ولكن هذا يعني أنّ الناتج يمكن أن يظهر بشكل مختلف عند استخدام مستويات تكبير أو تصغير مختلفة.

إذا لم تكن صورة العرض المحسّنة كافية، يمكن فرض إجراء العمليات الحسابية في تصوُّر معيّن من خلال إعادة إسقاط الإخراج كما هو موضّح في القسم التالي.

إعادة الإسقاط

يمكنك فرض تنفيذ العمليات في إسقاط معيّن باستخدام الأسلوب reproject(). يؤدي استخدام reproject() إلى طلب المدخلات في الإسقاط المحدّد في طلب reproject(). سيتم إجراء العمليات الحسابية في الرمز البرمجي قبل استدعاء reproject() في التوقّع المحدّد. على سبيل المثال، لفرض إنشاء تركيبة في إسقاط معيّن:

// Some projection that is suitable for your area of interest.
var proj = ee.Projection(...);
var output = collection.reduce(...).reproject(proj);

اطّلِع على صفحة بيئة Python للحصول على معلومات عن واجهة برمجة التطبيقات Python API واستخدام IDE geemap لتطوير التطبيقات التفاعلي.

import ee
import geemap.core as geemap
# Some projection that is suitable for your area of interest.
proj = ee.Projection(...)
output = collection.reduce(...).reproject(proj)

تشمل بعض الحالات التي تتطلّب إسقاطًا ثابتًا ما يلي:

هناك عدة أسباب تدفعك إلى تجنُّب استخدام reproject() ما لم يكن ذلك ضروريًا. لنفترض مثلاً أنّك أعدت إنشاء عرض لشيء ما وأضفته إلى الخريطة. إذا كان المقياس الذي حدّدته في طلب reproject() أصغر بكثير من مستوى التكبير في الخريطة، سيطلب Earth Engine جميع المدخلات على مقياس صغير جدًا، على نطاق مكاني واسع جدًا. وقد يؤدي ذلك إلى طلب عدد كبير جدًا من البيانات في آنٍ واحد، ما يؤدي إلى حدوث خطأ.

إذا كانت النتيجة النهائية بنظام إسقاط مختلف عن النظام المحدّد في reproject()، سيؤدي ذلك إلى إجراء إعادة إسقاط أخرى. وهذا هو سبب آخر للحذر من استخدام reproject() في الرمز. راجِع المثال التالي الذي يفرض إعادة إسقاط صورة MODIS أولاً إلى WGS84، ثم إعادة إسقاطها إلى إسقاط Mercator للخرائط لعرضها في خريطة "محرر الرموز":

// The input image has a SR-ORG:6974 (sinusoidal) projection.
var image = ee.Image('MODIS/061/MOD13A1/2014_05_09').select(0);

// Operations *before* the reproject call will be done in the projection
// specified by reproject().  The output results in another reprojection.
var reprojected = image
    .unitScale(-2000, 10000)
    .reproject('EPSG:4326', null, 500);
Map.addLayer(reprojected, {min: 0.15, max: 0.7}, 'Reprojected');

اطّلِع على صفحة بيئة Python للحصول على معلومات عن واجهة برمجة التطبيقات Python API واستخدام IDE geemap لتطوير التطبيقات التفاعلي.

import ee
import geemap.core as geemap
# The input image has a SR-ORG:6974 (sinusoidal) projection.
image = ee.Image('MODIS/061/MOD13A1/2014_05_09').select(0)

# Operations *before* the reproject call will be done in the projection
# specified by reproject(). The output results in another reprojection.
reprojected = image.unitScale(-2000, 10000).reproject('EPSG:4326', None, 500)
m = geemap.Map()
m.add_layer(reprojected, {'min': 0.15, 'max': 0.7}, 'Reprojected')
m

يوضِّح الشكل 2 مخطّط تدفق العمليات المقابلة لهذا المثال البسيط على إعادة الاصطفاف. يُرجى العِلم أنّ عملية إعادة الإسقاط الأولى صريحة، كما هو محدّد في دعوة reproject(). عملية إعادة الإسقاط الثانية ضمنية، وتجريها أداة Earth Engine تلقائيًا لعرض النتيجة على الخريطة. يُرجى ملاحظة أنّه تتم أيضًا إعادة توجيه المعلومات حول الإسقاط الذي سيتم استخدامه من الطلب إلى الإدخال.

إعادة الإسقاط
الشكل 2: مخطّط بياني للعمليات المقابلة لإعادة إسقاط صورة MODIS في خريطة "محرر الرموز" تشير الخطوط المنحنية إلى تدفق المعلومات إلى عمليات إعادة الإسقاط: على وجه التحديد، الإسقاط الناتج والمقياس.