انتقال فئة المياه

ترصد طبقة انتقال المياه التغييرات بين ثلاث فئات من حالات وجود المياه (غير مائية وموسمية ودائمة)، بالإضافة إلى فئتَين إضافيتَين للمياه المؤقتة (المؤقتة الدائمة والمؤقتة الموسمية).

سيتناول هذا القسم من الدليل التوجيهي ما يلي:

  1. وإضافة طبقة خريطة لتصوّر انتقال المياه
  2. إنشاء دالة اختزال مجمّعة لجمع مساحة كل فئة انتقال ضمن منطقة محددة،
  3. إنشاء رسم بياني يلخّص المساحة حسب فئة الانتقال

العرض المرئي الأساسي

في قسم "قائمة مواد العرض" (Asset List) من النص البرمجي، أضِف العبارة التالية التي تنشئ عنصر صورة بنطاق واحد باسم transition:

أداة تعديل الرموز (JavaScript)

var transition = gsw.select('transition');

تحتوي صور GSW على بيانات وصفية حول أرقام وأسماء فئات الانتقال، ولوحة ألوان تلقائية لتصميم فئات الانتقال. عند إضافة طبقة الانتقال إلى الخريطة، سيتم استخدام معلَمات العرض هذه تلقائيًا.

في أسفل قسم "طبقات الخريطة" في النص البرمجي، أضِف العبارة التالية التي تضيف طبقة خريطة جديدة تعرض فئات الانتقال:

أداة تعديل الرموز (JavaScript)

Map.setCenter(105.26, 11.2134, 9);     // Mekong River Basin, SouthEast Asia
Map.addLayer({
  eeObject: transition,
  name: 'Transition classes (1984-2015)',
});

عند تشغيل النص البرمجي، سيتم عرض طبقة الانتقال.

فئات انتقال المياه السطحية
الشكل 10: لقطة شاشة لدلتا نهر ميكونغ، تُظهر تباينًا كبيرًا في انتقالات فئات المياه السطحية.

مفتاح الخريطة لفئات الانتقال هو:

القيمة الرمز التصنيف
0 ليست مياه
1 نهائية
2 محتوى دائم جديد
3 فقدان دائم
4 موسمي
5 محتوى موسمي جديد
6 محتوى موسمي مفقود
7 من وظيفة موسمية إلى وظيفة دائمة
8 من دائم إلى موسمي
9 مؤقتة دائمة
10 محتوى موسمي مؤقت

تلخيص المساحة حسب فئة الانتقال

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

في هذا المثال، سنرسم مضلّعًا جديدًا داخل دلتا نهر ميكونغ.

Transition Classes with ROI
الشكل 11: دلتا نهر ميكونغ في فيتنام، مع منطقة اهتمام تم إنشاؤها باستخدام أداة رسم المضلّعات في "أداة تعديل الرموز".

لحساب المساحة التي تغطيها أجزاء من الصورة، سنضيف نطاقًا إضافيًا إلى عنصر صورة الانتقال يحدّد حجم كل بكسل بالمتر المربع باستخدام طريقة ee.Image.pixelArea.

أداة تعديل الرموز (JavaScript)

var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);

كائن الصورة الناتج (area_image_with_transition_class) هو صورة ذات نطاقَين، حيث يحتوي النطاق الأول على معلومات المساحة بوحدات المتر المربع (التي تنتجها الطريقة ee.Image.pixelArea )، ويحتوي النطاق الثاني على معلومات فئة الانتقال.

بعد ذلك، نلخّص عمليات الانتقال بين الفئات ضمن منطقة اهتمام (roi) باستخدام طريقة ee.Image.reduceRegion و مُختزِل مجمَّع يعمل على جمع المساحة ضمن كل فئة انتقال:

أداة تعديل الرموز (JavaScript)

var reduction_results = area_image_with_transition_class.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'transition_class_value',
  }),
  geometry: roi,
  scale: 30,
  bestEffort: true,
});
print('reduction_results', reduction_results);

تعرض الآن علامة التبويب "وحدة التحكّم" reduction_results. يُرجى العِلم أنّه عليك توسيع الشجرة بضعة مستويات للاطّلاع على بيانات ملخّص المنطقة.

نتائج الاختزال المجمّعة
الشكل 12: نتيجة علامة التبويب "وحدة التحكّم" (Console)، والتي تعرض نتائج عملية الاختزال المجمّعة

على الرغم من أنّ عنصر reduction_results يحتوي على معلومات عن المنطقة التي تغطيها كل فئة انتقال، إلا أنّه ليس من السهل قراءتها. في القسم التالي، سنسهّل عليك عرض النتائج.

إنشاء رسم بياني ملخّص

في هذا القسم، سنقوم بعمل مخطط لتلخيص النتائج بشكل أفضل. للبدء، نستخرج أولاً قائمة فئات الانتقال مع المناطق على النحو التالي:

أداة تعديل الرموز (JavaScript)

var roi_stats = ee.List(reduction_results.get('groups'));

نتيجة أداة الاختزال المجمّعة (reduction_results) هي قاموس يحتوي على قائمة بالقواميس. هناك قاموس واحد في القائمة لكل فئة انتقال. تستخدم هذه العبارات طريقة ee.Dictionary.get لاستخراج نتائج الاختزال المجمّعة من ذلك القاموس وتحويل النتائج إلى نوع بيانات ee.List، حتى نتمكّن من الوصول إلى القواميس الفردية.

للاستفادة من دوال الرسوم البيانية في "أداة تعديل الرموز"، سننشئ FeatureCollection يحتوي على المعلومات اللازمة. للقيام بذلك، نقوم أولاً بإنشاء قاموسين للبحث ودالتين مساعدتين. يمكن وضع الرمز الذي ينشئ قواميس البحث في أعلى قسم "Calculations" (العمليات الحسابية) على النحو التالي:

أداة تعديل الرموز (JavaScript)

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// Create a dictionary for looking up names of transition classes.
var lookup_names = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_names')
);
// Create a dictionary for looking up colors of transition classes.
var lookup_palette = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_palette')
);

يربط قاموس lookup_names قيم فئات الانتقال بأسمائها، بينما يربط قاموس lookup_palette قيم فئات الانتقال بتعريفات الألوان.

يمكن وضع الدالتَين المساعدتَين في قسم جديد من الرمز البرمجي باسم "الدوال المساعدة".

أداة تعديل الرموز (JavaScript)

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a feature for a transition class that includes the area covered.
function createFeature(transition_class_stats) {
  transition_class_stats = ee.Dictionary(transition_class_stats);
  var class_number = transition_class_stats.get('transition_class_value');
  var result = {
      transition_class_number: class_number,
      transition_class_name: lookup_names.get(class_number),
      transition_class_palette: lookup_palette.get(class_number),
      area_m2: transition_class_stats.get('sum')
  };
  return ee.Feature(null, result);   // Creates a feature without a geometry.
}

// Create a JSON dictionary that defines piechart colors based on the
// transition class palette.
// https://developers.google.com/chart/interactive/docs/gallery/piechart
function createPieChartSliceDictionary(fc) {
  return ee.List(fc.aggregate_array("transition_class_palette"))
    .map(function(p) { return {'color': p}; }).getInfo();
}

// Convert a number to a string. Used for constructing dictionary key lists
// from computed number objects.
function numToString(num) {
  return ee.Number(num).format();
}

تأخذ الدالة createFeature قاموسًا (يحتوي على المنطقة وفئة انتقال المياه) وتعرض عنصرًا مناسبًا لإنشاء الرسم البياني. تنشئ الدالة createPieChartSliceDictionary قائمة بالألوان التي تتوافق مع فئات الانتقال، باستخدام التنسيق المتوقّع للرسم البياني الدائري.

بعد ذلك، سنطبّق الدالة createFeature على كل قاموس في القائمة (roi_stats)، باستخدام ee.List.map لتطبيق الدالة المساعِدة على كل عنصر في القائمة.

أداة تعديل الرموز (JavaScript)

var transition_fc = ee.FeatureCollection(roi_stats.map(createFeature));
print('transition_fc', transition_fc);

بعد أن أصبح لدينا FeatureCollection يحتوي على السمات التي نريد عرضها على الرسم البياني، يمكننا إنشاء عنصر رسم بياني وطباعته في وحدة التحكّم.

أداة تعديل الرموز (JavaScript)

// Add a summary chart.
var transition_summary_chart = ui.Chart.feature.byFeature({
    features: transition_fc,
    xProperty: 'transition_class_name',
    yProperties: ['area_m2', 'transition_class_number']
  })
  .setChartType('PieChart')
  .setOptions({
    title: 'Summary of transition class areas',
    slices: createPieChartSliceDictionary(transition_fc),
    sliceVisibilityThreshold: 0  // Don't group small slices.
  });
print(transition_summary_chart);

يؤدي الخيار slices إلى تلوين شرائح الرسم البياني الدائري بحيث تستخدم لوحة الألوان التلقائية المحدّدة لفئات الانتقال (الموضّحة سابقًا في جدول مفتاح الخريطة). يمنع الخيار sliceVisibilityThreshold تجميع الشرائح الصغيرة معًا في فئة "أخرى". يجب أن يكون المخطط الناتج مشابهًا للمخطط الموضح في الشكل 13.

الرسم البياني لملخّص فئة انتقال المياه
الشكل 13: رسم بياني يلخّص الحجم النسبي لفئات انتقال المياه

النص النهائي

النص الكامل لهذا القسم هو:

أداة تعديل الرموز (JavaScript)

//////////////////////////////////////////////////////////////
// Asset List
//////////////////////////////////////////////////////////////

var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var occurrence = gsw.select('occurrence');
var change = gsw.select("change_abs");
var transition = gsw.select('transition');
var roi = ee.Geometry.Polygon(
        [[[105.531921, 10.412183],
          [105.652770, 10.285193],
          [105.949401, 10.520218],
          [105.809326, 10.666006]]]);
//////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////

var VIS_OCCURRENCE = {
    min: 0,
    max: 100,
    palette: ['red', 'blue']
};
var VIS_CHANGE = {
    min: -50,
    max: 50,
    palette: ['red', 'black', 'limegreen']
};
var VIS_WATER_MASK = {
  palette: ['white', 'black']
};

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a feature for a transition class that includes the area covered.
function createFeature(transition_class_stats) {
  transition_class_stats = ee.Dictionary(transition_class_stats);
  var class_number = transition_class_stats.get('transition_class_value');
  var result = {
      transition_class_number: class_number,
      transition_class_name: lookup_names.get(class_number),
      transition_class_palette: lookup_palette.get(class_number),
      area_m2: transition_class_stats.get('sum')
  };
  return ee.Feature(null, result);   // Creates a feature without a geometry.
}

// Create a JSON dictionary that defines piechart colors based on the
// transition class palette.
// https://developers.google.com/chart/interactive/docs/gallery/piechart
function createPieChartSliceDictionary(fc) {
  return ee.List(fc.aggregate_array("transition_class_palette"))
    .map(function(p) { return {'color': p}; }).getInfo();
}

// Convert a number to a string. Used for constructing dictionary key lists
// from computed number objects.
function numToString(num) {
  return ee.Number(num).format();
}

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// Create a dictionary for looking up names of transition classes.
var lookup_names = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_names')
);
// Create a dictionary for looking up colors of transition classes.
var lookup_palette = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_palette')
);

// Create a water mask layer, and set the image mask so that non-water areas
// are transparent.
var water_mask = occurrence.gt(90).mask(1);

// Generate a histogram object and print it to the console tab.
var histogram = ui.Chart.image.histogram({
  image: change,
  region: roi,
  scale: 30,
  minBucketWidth: 10
});
histogram.setOptions({
  title: 'Histogram of surface water change intensity.'
});
print(histogram);

// Summarize transition classes in a region of interest.
var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);
var reduction_results = area_image_with_transition_class.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'transition_class_value',
  }),
  geometry: roi,
  scale: 30,
  bestEffort: true,
});
print('reduction_results', reduction_results);

var roi_stats = ee.List(reduction_results.get('groups'));

var transition_fc = ee.FeatureCollection(roi_stats.map(createFeature));
print('transition_fc', transition_fc);

// Add a summary chart.
var transition_summary_chart = ui.Chart.feature.byFeature({
    features: transition_fc,
    xProperty: 'transition_class_name',
    yProperties: ['area_m2', 'transition_class_number']
  })
  .setChartType('PieChart')
  .setOptions({
    title: 'Summary of transition class areas',
    slices: createPieChartSliceDictionary(transition_fc),
    sliceVisibilityThreshold: 0  // Don't group small slices.
  });
print(transition_summary_chart);

//////////////////////////////////////////////////////////////
// Initialize Map Location
//////////////////////////////////////////////////////////////

// Uncomment one of the following statements to center the map on
// a particular location.
// Map.setCenter(-90.162, 29.8597, 10);   // New Orleans, USA
// Map.setCenter(-114.9774, 31.9254, 10); // Mouth of the Colorado River, Mexico
// Map.setCenter(-111.1871, 37.0963, 11); // Lake Powell, USA
// Map.setCenter(149.412, -35.0789, 11);  // Lake George, Australia
Map.setCenter(105.26, 11.2134, 9);     // Mekong River Basin, SouthEast Asia
// Map.setCenter(90.6743, 22.7382, 10);   // Meghna River, Bangladesh
// Map.setCenter(81.2714, 16.5079, 11);   // Godavari River Basin Irrigation Project, India
// Map.setCenter(14.7035, 52.0985, 12);   // River Oder, Germany & Poland
// Map.setCenter(-59.1696, -33.8111, 9);  // Buenos Aires, Argentina
// Map.setCenter(-74.4557, -8.4289, 11);  // Ucayali River, Peru

//////////////////////////////////////////////////////////////
// Map Layers
//////////////////////////////////////////////////////////////

Map.addLayer({
  eeObject: water_mask,
  visParams: VIS_WATER_MASK,
  name: '90% occurrence water mask',
  shown: false
});
Map.addLayer({
  eeObject: occurrence.updateMask(occurrence.divide(100)),
  name: "Water Occurrence (1984-2015)",
  visParams: VIS_OCCURRENCE,
  shown: false
});
Map.addLayer({
  eeObject: change,
  visParams: VIS_CHANGE,
  name: 'occurrence change intensity',
  shown: false
});
Map.addLayer({
  eeObject: transition,
  name: 'Transition classes (1984-2015)',
});

بهذا نكون قد انتهينا من البرنامج التعليمي حول مجموعة بيانات Global Surface Water. يُرجى العِلم أنّ هذا البرنامج التعليمي قد أوضح كيفية العمل مع ثلاث طبقات بيانات فقط (الحدوث، وكثافة التغيير، والانتقال) المتوفّرة في مجموعة بيانات المياه السطحية العالمية. يمكنك الاطّلاع على مزيد من المعلومات حول طبقات البيانات الأخرى المتوفّرة في دليل مستخدمي البيانات (الإصدار 2).

نتمنى لك تحليلًا ممتعًا!