รูปภาพที่ประกอบImageCollection
สามารถแสดงเป็นภาพเคลื่อนไหวหรือชุดภาพขนาดย่อที่เรียกว่า "แถบสไลด์" วิธีการเหล่านี้ช่วยให้ประเมินเนื้อหาของImageCollection
ได้อย่างรวดเร็วและเป็นสื่อที่มีประสิทธิภาพในการแสดงให้เห็นถึงการเปลี่ยนแปลงเชิงพื้นที่และเวลา (รูปที่ 1)
getVideoThumbURL()
สร้างชุดรูปภาพเคลื่อนไหวgetFilmstripThumbURL()
สร้างชุดรูปภาพขนาดย่อ
ส่วนต่อไปนี้อธิบายวิธีเตรียม ImageCollection
สำหรับการนำเสนอข้อมูลเป็นภาพ แสดงตัวอย่างโค้ดสำหรับวิธีการนำเสนอข้อมูลเป็นภาพของแต่ละคอลเล็กชัน และครอบคลุมเทคนิคภาพเคลื่อนไหวขั้นสูงหลายเทคนิค
รูปที่ 1 ภาพเคลื่อนไหวแสดงความคืบหน้าของพายุเฮอร์ริเคนแอตแลนติกในช่วง 3 วันในเดือนกันยายน 2017
การเตรียมคอลเล็กชัน
กรอง คอมโพส เรียง และจัดสไตล์รูปภาพภายในคอลเล็กชันเพื่อแสดงเฉพาะรูปภาพที่น่าสนใจหรือเน้นปรากฏการณ์ ImageCollection
ใดก็ได้ที่ระบุเป็นอินพุตให้กับฟังก์ชันการแสดงภาพ แต่คอลเล็กชันที่มีการดูแลจัดการโดยพิจารณาจากช่วงวันที่ทั้งภายในและภายนอกปี ช่วงเวลาการสังเกต ขอบเขตระดับภูมิภาค คุณภาพ และการแสดงผลจะให้ผลลัพธ์ที่ดีกว่า
การกรอง
กรองคอลเล็กชันรูปภาพให้รวมเฉพาะข้อมูลที่สอดคล้องซึ่งสนับสนุนวัตถุประสงค์ของการแสดงภาพ พิจารณาวันที่ ขอบเขตเชิงพื้นที่ คุณภาพ และพร็อพเพอร์ตี้อื่นๆ ที่เฉพาะเจาะจงสำหรับชุดข้อมูลหนึ่งๆ
เช่น กรองคอลเล็กชันการสะท้อนแสงพื้นผิวของ Sentinel-2 ตามข้อมูลต่อไปนี้
ช่วงวันที่เดียว
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01');
ช่วงวันของปีแบบอนุกรม
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));
พื้นที่สนใจ
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2));
หรือพร็อพเพอร์ตี้รูปภาพ
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));
วางตัวกรองหลายรายการต่อกัน
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .filter('CLOUDY_PIXEL_PERCENTAGE < 50');
การคอมโพส
รวมช่วงวันที่ภายในและระหว่างปีเพื่อลดจำนวนรูปภาพในคอลเล็กชันและปรับปรุงคุณภาพ ตัวอย่างเช่น สมมติว่าคุณต้องการสร้างการแสดงภาพ NDVI รายปีสําหรับแอฟริกา ตัวเลือกหนึ่งคือเพียงแค่กรองคอลเล็กชัน NDVI 16 วันของ MODIS เพื่อรวมการสังเกตการณ์ทั้งหมดในปี 2018
เครื่องมือแก้ไขโค้ด (JavaScript)
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2') .filterDate('2018-01-01', '2019-01-01') .select('NDVI');
ภาพรวมหลายปีตามตัวกรองและลด
ภาพแสดงผลของชุดข้อมูลข้างต้นแสดงให้เห็นสัญญาณรบกวนจำนวนมากในภูมิภาคที่เป็นป่าซึ่งมีเมฆปกคลุมหนาแน่น (รูปที่ 2ก) การแสดงผลที่ดีขึ้นทำได้โดยการลดช่วงวันที่ตามลำดับตามค่ามัธยฐานของทุกปีในคอลเล็กชัน MODIS
เครื่องมือแก้ไขโค้ด (JavaScript)
// Make a day-of-year sequence from 1 to 365 with a 16-day step. var doyList = ee.List.sequence(1, 365, 16); // Import a MODIS NDVI collection. var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI'); // Map over the list of days to build a list of image composites. var ndviCompList = doyList.map(function(startDoy) { // Ensure that startDoy is a number. startDoy = ee.Number(startDoy); // Filter images by date range; starting with the current startDate and // ending 15 days later. Reduce the resulting image collection by median. return ndviCol .filter(ee.Filter.calendarRange(startDoy, startDoy.add(15), 'day_of_year')) .reduce(ee.Reducer.median()); }); // Convert the image List to an ImageCollection. var ndviCompCol = ee.ImageCollection.fromImages(ndviCompList);
ภาพเคลื่อนไหวที่ได้จากคอลเล็กชันนี้จะมีสัญญาณรบกวนน้อยกว่า เนื่องจากแต่ละภาพแสดงค่ามัธยฐานของ NDVI แบบคอมโพสิต 16 วันสำหรับข้อมูลมากกว่า 20 ปี (รูปภาพ 1ข) ดูข้อมูลเพิ่มเติมเกี่ยวกับภาพเคลื่อนไหวนี้ได้ในบทแนะนำนี้
![]() |
![]() |
---|---|
รูปที่ 2ก. NDVI รายปีที่ไม่มีการคอมโพสภาพหลายปี | รูปที่ 2ข. NDVI รายปีที่มีการคอมโพสภาพหลายปี |
คอมโพสิตภายในปีตามตัวกรองและลด
ตัวอย่างก่อนหน้านี้ใช้การคอมโพสภาพระหว่างปี นอกจากนี้ยังเป็นประโยชน์ในการรวมชุดการสังเกตการณ์ภายในปี ตัวอย่างเช่น ข้อมูล Landsat จะรวบรวมทุก 16 วันสำหรับฉากหนึ่งๆ ต่อเซ็นเซอร์ แต่บ่อยครั้งที่ภาพบางส่วนถูกบดบังด้วยเมฆ การปกปิดเมฆและการจัดวางองค์ประกอบหลายรูปภาพจากฤดูกาลเดียวกันอาจทำให้ภาพมีความชัดเจนมากขึ้น พิจารณาตัวอย่างต่อไปนี้ซึ่งภาพ Landsat 5 จากเดือนกรกฎาคมและสิงหาคมได้รับการคอมโพสโดยใช้ค่ามัธยฐานของแต่ละปีตั้งแต่ปี 1985 ถึง 2011
เครื่องมือแก้ไขโค้ด (JavaScript)
// Assemble a collection of Landsat surface reflectance images for a given // region and day-of-year range. var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2') .filterBounds(ee.Geometry.Point(-122.9, 43.6)) .filter(ee.Filter.dayOfYear(182, 243)) // Add the observation year as a property to each image. .map(function(img) { return img.set('year', ee.Image(img).date().get('year')); }); // Define a function to scale the data and mask unwanted pixels. function maskL457sr(image) { // Bit 0 - Fill // Bit 1 - Dilated Cloud // Bit 2 - Unused // Bit 3 - Cloud // Bit 4 - Cloud Shadow var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2); var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0); // Replace the original bands with the scaled ones and apply the masks. return image.addBands(opticalBands, null, true) .addBands(thermalBand, null, true) .updateMask(qaMask) .updateMask(saturationMask); } // Define a list of unique observation years from the image collection. var years = ee.List(lsCol.aggregate_array('year')).distinct().sort(); // Map over the list of years to build a list of annual image composites. var lsCompList = years.map(function(year) { return lsCol // Filter image collection by year. .filterMetadata('year', 'equals', year) // Apply cloud mask. .map(maskL457sr) // Reduce image collection by median. .reduce(ee.Reducer.median()) // Set composite year as an image property. .set('year', year); }); // Convert the image List to an ImageCollection. var lsCompCol = ee.ImageCollection.fromImages(lsCompList);
คอมโพสิตภายในปีตามการรวมและลด
โปรดทราบว่าวิธีการคอมโพส 2 วิธีก่อนหน้านี้จะจับคู่กับList
วันและปีเพื่อกำหนดวันที่ใหม่เพื่อกรองและคอมโพสเพิ่มเติม
การใช้การรวมเป็นอีกวิธีหนึ่งในการดําเนินการนี้ ในข้อมูลโค้ดต่อไปนี้ ระบบจะกำหนดคอลเล็กชันปีที่ไม่ซ้ำกัน จากนั้นจะใช้การรวม saveAll
เพื่อระบุรูปภาพทั้งหมดที่สอดคล้องกับปีนั้นๆ
ระบบจะจัดกลุ่มรูปภาพที่อยู่ในปีหนึ่งๆ ไว้ในออบเจ็กต์ List
ซึ่งจัดเก็บเป็นพร็อพเพอร์ตี้ของตัวแทนปีที่เกี่ยวข้องในคอลเล็กชันปีที่แตกต่างกัน ระบบจะสร้างภาพรวมรายปีจากรายการเหล่านี้โดยการลดImageCollections
ที่กําหนดโดยรายการเหล่านั้นในฟังก์ชันที่แมปกับคอลเล็กชันปีที่แตกต่างกัน
เครื่องมือแก้ไขโค้ด (JavaScript)
// Assemble a collection of Landsat surface reflectance images for a given // region and day-of-year range. var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2') .filterBounds(ee.Geometry.Point(-122.9, 43.6)) .filter(ee.Filter.dayOfYear(182, 243)) // Add the observation year as a property to each image. .map(function(img) { return img.set('year', ee.Image(img).date().get('year')); }); // Make a distinct year collection; one image representative per year. var distinctYears = lsCol.distinct('year').sort('year'); // Define a join filter; one-to-many join on ‘year’ property. var filter = ee.Filter.equals({leftField: 'year', rightField: 'year'}); // Define a join. var join = ee.Join.saveAll('year_match'); // Apply the join; results in 'year_match' property being added to each distinct // year representative image. The list includes all images in the collection // belonging to the respective year. var joinCol = join.apply(distinctYears, lsCol, filter); // Define a function to scale the data and mask unwanted pixels. function maskL457sr(image) { // Bit 0 - Fill // Bit 1 - Dilated Cloud // Bit 2 - Unused // Bit 3 - Cloud // Bit 4 - Cloud Shadow var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2); var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0); // Replace the original bands with the scaled ones and apply the masks. return image.addBands(opticalBands, null, true) .addBands(thermalBand, null, true) .updateMask(qaMask) .updateMask(saturationMask); } // Map over the distinct years collection to build a list of annual image // composites. var lsCompList = joinCol.map(function(img) { // Get the list of images belonging to the given year. return ee.ImageCollection.fromImages(img.get('year_match')) // Apply cloud mask. .map(maskL457sr) // Reduce image collection by median. .reduce(ee.Reducer.median()) // Set composite year as an image property. .copyProperties(img, ['year']); }); // Convert the image List to an ImageCollection. var lsCompCol = ee.ImageCollection(lsCompList);
การคอมโพสวันเดียวกันด้วยการรวมและลด
อีกกรณีหนึ่งสำหรับการจัดองค์ประกอบคือการสร้างภาพโมเสคที่ต่อเนื่องกันในพื้นที่ สมมติว่าพื้นที่ที่คุณสนใจครอบคลุมแถว Landsat 2 แถวในเส้นทางเดียวกัน และวัตถุประสงค์ของคุณคือแสดงภาพโมเสคของ 2 รูปภาพสำหรับแต่ละวงโคจรของ Landsat 8 ในปี 2017 และ 2018 ในส่วนนี้ หลังจากกรองคอลเล็กชันตามเส้นทางและแถวแล้ว ระบบจะใช้การดำเนินการรวมเพื่อวางภาพ Landsat แบบโมเสคจากภาพเดียวกัน ซึ่งกำหนดโดยวันที่รับภาพ
เครื่องมือแก้ไขโค้ด (JavaScript)
var lsCol = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2017-01-01', '2019-01-01') .filter('WRS_PATH == 38 && (WRS_ROW == 28 || WRS_ROW == 29)') .map(function(img) { var date = img.date().format('yyyy-MM-dd'); return img.set('date', date); }); var distinctDates = lsCol.distinct('date').sort('date'); var filter = ee.Filter.equals({leftField: 'date', rightField: 'date'}); var join = ee.Join.saveAll('date_match'); var joinCol = join.apply(distinctDates, lsCol, filter); var lsColMos = ee.ImageCollection(joinCol.map(function(col) { return ee.ImageCollection.fromImages(col.get('date_match')).mosaic(); }));
การจัดเรียง
จัดเรียงคอลเล็กชันตามเวลาเพื่อให้แน่ใจว่าลำดับตามลำดับเวลาถูกต้อง หรือจัดเรียงตามพร็อพเพอร์ตี้ที่ต้องการ โดยค่าเริ่มต้น ชุดเฟรมการแสดงภาพจะจัดเรียงตามลําดับตามธรรมชาติของคอลเล็กชัน การจัดเรียงชุดหนังสือสามารถเปลี่ยนแปลงได้โดยใช้วิธีการรวบรวม sort
ซึ่งจะเลือกพร็อพเพอร์ตี้ Image
เพื่อจัดเรียงตามลําดับจากน้อยไปมากหรือมากไปน้อย เช่น หากต้องการจัดเรียงตามเวลาของการสังเกต ให้ใช้พร็อพเพอร์ตี้ system:time_start
ที่พบได้ทุกที่
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('system:time_start');
หรืออาจกำหนดลำดับตามระดับความขุ่นของเมฆที่เพิ่มขึ้น เช่น ในกรณีของภาพ Sentinel-2 นี้
เครื่องมือแก้ไขโค้ด (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('CLOUDY_PIXEL_PERCENTAGE');
นอกจากนี้ ลำดับยังกำหนดโดยพร็อพเพอร์ตี้ที่ได้จากพร็อพเพอร์ตี้อื่น เช่น NDVI ระดับภูมิภาคเฉลี่ย ในส่วนนี้ ระบบจะเพิ่ม NDVI ระดับภูมิภาคเป็นพร็อพเพอร์ตี้ให้กับรูปภาพแต่ละรูปในฟังก์ชันที่แมปไว้ ตามด้วยการเรียงลําดับพร็อพเพอร์ตี้ใหม่
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an area of interest geometry. var aoi = ee.Geometry.Point(-122.1, 37.2).buffer(1e4); // Filter MODIS NDVI image collection by a date range. var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1') .filterDate('2018-01-01', '2019-01-01') .select('NDVI') // Map over the image collection to calculate regional mean NDVI and add // the result to each image as a property. .map(function(img) { var meanNdvi = img.reduceRegion({ reducer: ee.Reducer.mean(), geometry: aoi, scale: 500}); return img.set('meanNdvi', meanNdvi.get('NDVI')); }) // Sort the collection by descending regional mean NDVI. .sort('meanNdvi', false);
การแสดงภาพ
การแสดงภาพเป็นภาพจะเปลี่ยนตัวเลขให้เป็นสี วิธีควบคุมการแสดงข้อมูลรูปภาพเป็นสีในวิธีการแสดงภาพคอลเล็กชันมี 3 วิธีดังนี้
- ระบุอาร์กิวเมนต์การแสดงภาพไปยัง
getVideoThumbURL
และgetFilmstripThumbURL
โดยตรง - แมปเมธอดรูปภาพ
visualize
กับคอลเล็กชันรูปภาพก่อนใช้getVideoThumbURL
และgetFilmstripThumbURL
- แมปเมธอดรูปภาพ
sldStyle
กับคอลเล็กชันรูปภาพก่อนใช้getVideoThumbURL
และgetFilmstripThumbURL
ดูข้อมูลเพิ่มเติมได้ที่ตัวระบุเลเยอร์ที่มีสไตล์
ตัวอย่างในคู่มือนี้ใช้ตัวเลือกที่ 1 และ 2 ซึ่งแสดงภาพโดยจับคู่แถบภาพ 3 แถบของภาพหลายแถบกับช่องสี ได้แก่ แดง เขียว และน้ำเงิน หรือจัดอันดับค่าของแถบเดียวตามลําดับตามจานสี พารามิเตอร์การแสดงข้อมูลผ่านภาพ ได้แก่
พารามิเตอร์ | คำอธิบาย | ประเภท |
---|---|---|
bands | รายการชื่อย่านความถี่ 3 รายการที่คั่นด้วยคอมมาเพื่อแมปกับ RGB | list |
นาที | ค่าที่จะแมปเป็น 0 | หมายเลขหรือรายการตัวเลข 3 รายการ โดยแต่ละรายการมี 1 หมายเลข |
max | ค่าที่จะแมปเป็น 255 | หมายเลขหรือรายการตัวเลข 3 รายการ โดยแต่ละรายการมี 1 หมายเลข |
gain | ค่าที่จะคูณกับค่าพิกเซลแต่ละค่า | หมายเลขหรือรายการตัวเลข 3 รายการ โดยแต่ละรายการมี 1 หมายเลข |
bias | ค่าที่จะเพิ่มลงใน DN แต่ละรายการ | หมายเลขหรือรายการตัวเลข 3 รายการ โดยแต่ละรายการมี 1 หมายเลข |
gamma | ปัจจัยการแก้ไขแกมมา | หมายเลขหรือรายการตัวเลข 3 รายการ โดยแต่ละรายการมี 1 หมายเลข |
palette | รายการสตริงสีสไตล์ CSS (รูปภาพย่านความถี่เดียวเท่านั้น) | รายการสตริงฐาน 16 ที่คั่นด้วยคอมมา |
ความทึบ | ความทึบแสงของเลเยอร์ (0.0 คือโปร่งแสงทั้งหมดและ 1.0 คือทึบแสงทั้งหมด) | ตัวเลข |
ใช้อาร์กิวเมนต์ bands
เพื่อเลือกย่านความถี่ที่ต้องการแสดงเป็นภาพ ระบุรายชื่อวงดนตรี 1 หรือ 3 วง สำหรับภาพหลายย่านความถี่ ระบบจะเลือกย่านความถี่ 3 ย่านแรกไว้โดยค่าเริ่มต้น ลําดับชื่อแถบจะเป็นตัวกําหนดการกําหนดสี โดยแถบแรก 2 และ 3 ที่แสดงจะแมปกับสีแดง เขียว และน้ำเงินตามลําดับ
การปรับขนาดช่วงข้อมูลเป็นสิ่งสําคัญที่ควรพิจารณาเมื่อแสดงภาพ โดยค่าเริ่มต้น ค่าข้อมูลตัวเลขทศนิยมระหว่าง 0 ถึง 1 (รวมค่าแรกและค่าสุดท้าย) จะปรับขนาดระหว่าง 0 ถึง 255 (รวมค่าแรกและค่าสุดท้าย) ค่าที่อยู่นอกช่วงนี้จะถูกบังคับให้เป็น 0 และ 255 โดยขึ้นอยู่กับว่าค่านั้นน้อยกว่า 0 หรือมากกว่า 1 กัน สำหรับข้อมูลจำนวนเต็ม ความจุเต็มที่กำหนดโดยประเภทจะปรับขนาดระหว่าง 0 ถึง 255 (เช่น ข้อมูล 16 บิตที่มีค่าบวกมีช่วงตั้งแต่ -32,768 ถึง 32,767 ซึ่งปรับขนาดเป็น [0, 255] โดยค่าเริ่มต้น) การยอมรับค่าเริ่มต้นมักส่งผลให้การแสดงภาพมีคอนทราสต์น้อยหรือไม่มีคอนทราสต์ระหว่างองค์ประกอบของรูปภาพ ใช้ min
และ max
เพื่อปรับปรุงคอนทราสต์และเน้นช่วงข้อมูลที่ต้องการ หลักการทั่วไปคือให้ตั้งค่า min
และ max
เป็นค่าที่แสดงถึงเปอร์เซ็นต์ที่ 2 และ 98 ของข้อมูลในขอบเขตความสนใจ ดูตัวอย่างต่อไปนี้ของการคำนวณค่าเหล่านี้สำหรับรูปแบบความสูงเชิงดิจิทัล
เครื่องมือแก้ไขโค้ด (JavaScript)
// Import SRTM global elevation model. var demImg = ee.Image('USGS/SRTMGL1_003'); // Define a rectangular area of interest. var aoi = ee.Geometry.Polygon( [[ [-103.84153083119054, 49.083004219142886], [-103.84153083119054, 25.06838270664608], [-85.64817145619054, 25.06838270664608], [-85.64817145619054, 49.083004219142886] ]], null, false); // Calculate the 2nd and 98th percentile elevation values from rescaled (to // 500m) pixels intersecting the area of interest. A Dictionary is returned. var percentClip = demImg.reduceRegion({ reducer: ee.Reducer.percentile([2, 98]), geometry: aoi, scale: 500, maxPixels: 3e7 }); // Print the regional 2nd and 98th percentile elevation values. Get the // dictionary keys and use them to get the values for each percentile summary. var keys = percentClip.keys(); print('Set vis min to:', ee.Number(percentClip.get(keys.get(0))).round()); print('Set vis max to:', ee.Number(percentClip.get(keys.get(1))).round());
พารามิเตอร์ palette
จะกำหนดสีเพื่อแสดงภาพการแสดงผล 8 บิต ซึ่งใช้ได้กับการแสดงผลแบบแถบเดียวเท่านั้น การระบุค่านี้กับรูปภาพแบบหลายแถบจะทำให้เกิดข้อผิดพลาด
หากข้อมูลเป็นย่านความถี่เดียวหรือคุณต้องการแสดงภาพย่านความถี่เดียวจากรูปภาพหลายย่านความถี่ ให้ตั้งค่าพารามิเตอร์ forceRgbOutput
เป็น true
(ไม่จําเป็นหากระบุอาร์กิวเมนต์ palette
) ใช้พารามิเตอร์ min
และ max
เพื่อกำหนดช่วงของค่าที่จะปรับสเกลแบบเชิงเส้นระหว่าง 0 ถึง 255
ตัวอย่างการแมปฟังก์ชันการแสดงภาพในคอลเล็กชันรูปภาพย่านความถี่เดียวมีดังนี้ ระบบจะนำเข้าคอลเล็กชัน NDVI ของ MODIS, ตั้งค่าอาร์กิวเมนต์การแสดงภาพสำหรับเมธอด visualization
และจับคู่ฟังก์ชันที่เปลี่ยนค่าให้แสดงเป็นภาพ RGB กับคอลเล็กชัน NDVI
เครื่องมือแก้ไขโค้ด (JavaScript)
// Filter MODIS NDVI image collection by a date range. var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1') .filterDate('2018-01-01', '2019-01-01') .select('NDVI'); // Define visualization arguments. var visArgs = { min: 0, max: 9000, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ] }; // Define a function to convert an image to an RGB visualization image and copy // properties from the original image to the RGB image. var visFun = function(img) { return img.visualize(visArgs).copyProperties(img, img.propertyNames()); }; // Map over the image collection to convert each image to an RGB visualization // using the previously defined visualization function. var ndviColVis = ndviCol.map(visFun);
ต่อไปนี้คือตัวอย่างการแมปฟังก์ชันการแสดงภาพในคอลเล็กชันรูปภาพหลายย่านความถี่
เครื่องมือแก้ไขโค้ด (JavaScript)
// Assemble a collection of Sentinel-2 surface reflectance images for a given // region and date range. var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-96.9037, 48.0395)) .filterDate('2019-06-01', '2019-10-01'); // Define visualization arguments. var visArgs = {bands: ['B11', 'B8', 'B3'], min: 300, max: 3500}; // Define a function to convert an image to an RGB visualization image and copy // properties from the original image to the RGB image. var visFun = function(img) { return img.visualize(visArgs).copyProperties(img, img.propertyNames()); }; // Map over the image collection to convert each image to an RGB visualization // using the previously defined visualization function. var s2colVis = s2col.map(visFun);
ในกรณีนี้ จะไม่มีการให้อาร์กิวเมนต์พาเลตเนื่องจากมีการระบุแถบ 3 แถบ ซึ่งกำหนดความเข้มสำหรับเลเยอร์ RGB แต่ละเลเยอร์ โปรดทราบว่าทั้ง 2 ตัวอย่างใช้พารามิเตอร์ min
และ max
เพื่อควบคุมค่าที่จะขยายไปจนถึงขีดจำกัดของข้อมูล RGB 8 บิต
ภาพปกวิดีโอ
ฟังก์ชัน getVideoThumbURL()
จะสร้างภาพเคลื่อนไหวจากรูปภาพทั้งหมดใน ImageCollection
โดยที่แต่ละรูปภาพแสดงเฟรม เวิร์กโฟลว์ทั่วไปในการสร้างภาพเคลื่อนไหวมีดังนี้
- กำหนด
Geometry
ที่มีขอบเขตซึ่งกำหนดขอบเขตระดับภูมิภาคของภาพเคลื่อนไหว - กำหนด
ImageCollection
- ลองใช้การแสดงภาพ: แมปฟังก์ชันการแสดงภาพกับคอลเล็กชัน หรือเพิ่มอาร์กิวเมนต์การแสดงภาพลงในชุดอาร์กิวเมนต์ภาพเคลื่อนไหว
- กำหนดอาร์กิวเมนต์ภาพเคลื่อนไหวและเรียกใช้เมธอด
getVideoThumbURL
ผลลัพธ์ของ getVideoThumbURL
คือ URL พิมพ์ URL ลงในคอนโซล แล้วคลิก URL นั้นเพื่อเริ่มเซิร์ฟเวอร์ Earth Engine สร้างภาพเคลื่อนไหวแบบเรียลไทม์ในแท็บเบราว์เซอร์ใหม่ หรือจะดูภาพเคลื่อนไหวในคอนโซลเครื่องมือแก้ไขโค้ดก็ได้โดยเรียกใช้ฟังก์ชัน ui.Thumbnail
ในคอลเล็กชันและอาร์กิวเมนต์ภาพเคลื่อนไหวที่เกี่ยวข้อง เมื่อผ่านการแสดงผลแล้ว ภาพเคลื่อนไหวจะพร้อมให้ดาวน์โหลดโดยคลิกขวาที่ภาพแล้วเลือกตัวเลือกที่เหมาะสมจากเมนูตามบริบท
ตัวอย่างต่อไปนี้แสดงการสร้างภาพเคลื่อนไหวที่แสดงอุณหภูมิทั่วโลกในช่วง 24 ชั่วโมง โปรดทราบว่าตัวอย่างนี้รวมอาร์กิวเมนต์การแสดงภาพพร้อมกับอาร์กิวเมนต์ภาพเคลื่อนไหว แทนที่จะแมปฟังก์ชันการแสดงภาพกับ ImageCollection
ก่อน เมื่อเรียกใช้สคริปต์นี้ ภาพเคลื่อนไหวที่คล้ายกับรูปที่ 3 ควรปรากฏในคอนโซลเครื่องมือแก้ไขโค้ด
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define arguments for animation function parameters. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 7, crs: 'EPSG:3857', min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Print the animation to the console as a ui.Thumbnail using the above defined // arguments. Note that ui.Thumbnail produces an animation when the first input // is an ee.ImageCollection instead of an ee.Image. print(ui.Thumbnail(tempCol, videoArgs)); // Alternatively, print a URL that will produce the animation when accessed. print(tempCol.getVideoThumbURL(videoArgs));
รูปที่ 3 อุณหภูมิพื้นผิวรายชั่วโมงสำหรับช่วงวันเหมาวันเหนือแสดงเป็นภาพ GIF แบบเคลื่อนไหว
แถบฟิล์ม
ฟังก์ชัน getFilmstripThumbUrl
จะสร้างรูปภาพแบบคงที่รูปเดียวซึ่งแสดงการต่อเชื่อมรูปภาพทั้งหมดใน ImageCollection
เป็นชุดรูปภาพแนวนอน-แนวตั้ง ลำดับของเฟรมฟิล์มสไลด์จะเป็นไปตามลำดับตามธรรมชาติของคอลเล็กชัน
ผลลัพธ์ของ getFilmstripThumbUrl
คือ URL พิมพ์ URL ลงในคอนโซลแล้วคลิก URL ดังกล่าวเพื่อเริ่มเซิร์ฟเวอร์ Earth Engine สร้างรูปภาพในแท็บเบราว์เซอร์ใหม่ เมื่อแสดงผลแล้ว รูปภาพจะพร้อมให้ดาวน์โหลดโดยคลิกขวาที่รูปภาพแล้วเลือกตัวเลือกที่เหมาะสมจากเมนูตามบริบท
ข้อมูลโค้ดต่อไปนี้ใช้คอลเล็กชันเดียวกับตัวอย่างภาพปกวิดีโอด้านบน เมื่อเรียกใช้สคริปต์นี้ แถบแสดงตัวอย่างรูปภาพคล้ายกับรูปที่ 4 ควรปรากฏในคอนโซลเครื่องมือแก้ไขโค้ด
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define arguments for the getFilmstripThumbURL function parameters. var filmArgs = { dimensions: 128, region: aoi, crs: 'EPSG:3857', min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Print a URL that will produce the filmstrip when accessed. print(tempCol.getFilmstripThumbURL(filmArgs));
รูปที่ 4 อุณหภูมิพื้นผิวรายชั่วโมงสำหรับวันเหมาวันเหนือแสดงเป็นภาพ PNG ของแถบสไลด์ โปรดทราบว่าแถบแสดงตัวอย่างรูปภาพแบ่งออกเป็น 4 ส่วนสำหรับแสดงผล ผลลัพธ์ของ getFilmstripThumbURL
จะเป็นชุดรูปภาพคอลเล็กชันชุดเดียวที่เชื่อมต่อกันจากเหนือจรดใต้
เทคนิคขั้นสูง
ส่วนต่อไปนี้จะอธิบายวิธีใช้การครอบตัด ความทึบ และการคอมโพสิตเลเยอร์เพื่อปรับปรุงการแสดงภาพโดยเพิ่มเส้นขอบรูปหลายเหลี่ยม เน้นบริเวณที่น่าสนใจ และเปรียบเทียบรูปภาพภายในคอลเล็กชัน
โปรดทราบว่าตัวอย่างต่อไปนี้ทั้งหมดในส่วนนี้ใช้ฐานเดียวกัน
ImageCollection
ที่กําหนดไว้ที่นี่
เครื่องมือแก้ไขโค้ด (JavaScript)
// Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define visualization arguments to control the stretch and color gradient // of the data. var visArgs = { min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Convert each image to an RGB visualization image by mapping the visualize // function over the image collection using the arguments defined previously. var tempColVis = tempCol.map(function(img) { return img.visualize(visArgs); }); // Import country features and filter to South American countries. var southAmCol = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017') .filterMetadata('wld_rgn', 'equals', 'South America'); // Define animation region (South America with buffer). var southAmAoi = ee.Geometry.Rectangle({ coords: [-103.6, -58.8, -18.4, 17.4], geodesic: false});
การวางซ้อน
คุณสามารถวางซ้อนรูปภาพหลายรูปได้โดยใช้วิธีการ blend
Image
ซึ่งจะผสมผสานพิกเซลที่ซ้อนทับกันจาก 2 รูปภาพตามมาสก์ (ความทึบแสง) ของรูปภาพ
การวางซ้อนเวกเตอร์
การเพิ่มรูปหลายเหลี่ยมของเขตแดนบริหารและรูปเรขาคณิตอื่นๆ ลงในรูปภาพจะให้บริบทเชิงพื้นที่ที่มีคุณค่า ดูภาพเคลื่อนไหวอุณหภูมิพื้นผิวรายวันทั่วโลกด้านบน (รูปที่ 3) ขอบเขตระหว่างพื้นดินและมหาสมุทรมองเห็นได้บ้าง แต่สามารถทำให้ชัดเจนได้โดยการเพิ่มรูปหลายเหลี่ยมที่วางซ้อนกันของทุกประเทศ
ข้อมูลเวกเตอร์ (Features
) จะวาดเป็นรูปภาพโดยใช้วิธีการ paint
คุณวาดองค์ประกอบลงในรูปภาพที่มีอยู่ได้ แต่แนวทางปฏิบัติแนะนำคือวาดลงในรูปภาพเปล่า จัดรูปแบบ แล้วค่อยผสมผสานผลลัพธ์กับเลเยอร์รูปภาพที่มีการจัดรูปแบบอื่นๆ การจัดการแต่ละเลเยอร์ของกองการแสดงภาพอย่างอิสระช่วยให้ควบคุมการจัดสไตล์ได้มากขึ้น
ตัวอย่างต่อไปนี้แสดงการวาดเส้นขอบประเทศในทวีปอเมริกาใต้ลงใน Image
ว่างเปล่า และผสมผสานผลลัพธ์กับ Image
แต่ละรายการของคอลเล็กชันอุณหภูมิรายวันทั่วโลก (รูปที่ 5) เส้นพรมแดนของประเทศที่วางซ้อนกันจะแยกความแตกต่างระหว่างพื้นดินกับน้ำ และระบุบริบทของรูปแบบอุณหภูมิ
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an empty image to paint features to. var empty = ee.Image().byte(); // Paint country feature edges to the empty image. var southAmOutline = empty .paint({featureCollection: southAmCol, color: 1, width: 1}) // Convert to an RGB visualization image; set line color to black. .visualize({palette: '000000'}); // Map a blend operation over the temperature collection to overlay the country // border outline image on all collection images. var tempColOutline = tempColVis.map(function(img) { return img.blend(southAmOutline); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(tempColOutline, videoArgs));
รูปที่ 5 เพิ่มการวางซ้อนเวกเตอร์ลงในรูปภาพในคอลเล็กชันเพื่อให้บริบทเชิงพื้นที่
ภาพที่วางซ้อน
คุณสามารถวางซ้อนรูปภาพหลายรูปเพื่อให้ได้สไตล์ที่ต้องการ สมมติว่าคุณต้องการเน้นภูมิภาคที่น่าสนใจ คุณสามารถสร้างสำเนาภาพแสดงข้อมูลแบบปิดเสียงเป็นเลเยอร์พื้นฐาน แล้ววางซ้อนภาพแสดงข้อมูลเวอร์ชันที่ตัดแล้ว จากตัวอย่างก่อนหน้านี้ สคริปต์ต่อไปนี้จะสร้างรูปที่ 6
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an empty image to paint features to. var empty = ee.Image().byte(); // Paint country feature edges to the empty image. var southAmOutline = empty .paint({featureCollection: southAmCol, color: 1, width: 1}) // Convert to an RGB visualization image; set line color to black. .visualize({palette: '000000'}); // Map a blend operation over the temperature collection to overlay the country // border outline image on all collection images. var tempColOutline = tempColVis.map(function(img) { return img.blend(southAmOutline); }); // Define a partially opaque grey RGB image to dull the underlying image when // blended as an overlay. var dullLayer = ee.Image.constant(175).visualize({ opacity: 0.6, min: 0, max: 255, forceRgbOutput: true}); // Map a two-part blending operation over the country outline temperature // collection for final styling. var finalVisCol = tempColOutline.map(function(img) { return img // Blend the dulling layer with the given country outline temperature image. .blend(dullLayer) // Blend a clipped copy of the country outline temperature image with the // dulled background image. .blend(img.clipToCollection(southAmCol)); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(finalVisCol, videoArgs));
รูปที่ 6 เน้นพื้นที่ที่น่าสนใจด้วยการครอบตัดรูปภาพและวางซ้อนบนสำเนาที่ปิดเสียง
นอกจากนี้ คุณยังผสมข้อมูลรูปภาพกับเลเยอร์ฐานภาพเงาของเนินเขาเพื่อระบุภูมิประเทศและเพิ่มความลึกให้กับภาพ (รูปที่ 7) ได้ด้วย
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define a hillshade layer from SRTM digital elevation model. var hillshade = ee.Terrain.hillshade(ee.Image('USGS/SRTMGL1_003') // Exaggerate the elevation to increase contrast in hillshade. .multiply(100)) // Clip the DEM by South American boundary to clean boundary between // land and ocean. .clipToCollection(southAmCol); // Map a blend operation over the temperature collection to overlay a partially // opaque temperature layer on the hillshade layer. var finalVisCol = tempColVis.map(function(img) { return hillshade .blend(img.clipToCollection(southAmCol).visualize({opacity: 0.6})); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(finalVisCol, videoArgs));
รูปที่ 7 แสดงภูมิประเทศโดยการวางซ้อนข้อมูลรูปภาพที่โปร่งใสบางส่วนในเลเยอร์การแสดงเงาของภูเขา
ทรานซิชัน
ปรับแต่งคอลเล็กชันรูปภาพเพื่อสร้างภาพเคลื่อนไหวที่แสดงความแตกต่างระหว่าง 2 รูปภาพในคอลเล็กชันโดยใช้ทรานซิชันการจาง การสั่นไหว และการเลื่อน ตัวอย่างต่อไปนี้แต่ละรายการใช้การแสดงภาพพื้นฐานเดียวกันซึ่งสร้างขึ้นจากสคริปต์ต่อไปนี้
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection. var temp = ee.ImageCollection('NOAA/GFS0P25') // Define a northern summer solstice temperature image. var summerSolTemp = temp .filterDate('2018-06-21', '2018-06-22') .filterMetadata('forecast_hours', 'equals', 12) .first() .select('temperature_2m_above_ground'); // Define a northern winter solstice temperature image. var winterSolTemp = temp .filterDate('2018-12-22', '2018-12-23') .filterMetadata('forecast_hours', 'equals', 12) .first() .select('temperature_2m_above_ground'); // Combine the solstice images into a collection. var tempCol = ee.ImageCollection([ summerSolTemp.set('season', 'summer'), winterSolTemp.set('season', 'winter') ]); // Import international boundaries feature collection. var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017'); // Define visualization arguments. var visArgs = { min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Convert the image data to RGB visualization images. // The clip and unmask combination sets ocean pixels to black. var tempColVis = tempCol.map(function(img) { return img .visualize(visArgs) .clipToCollection(countries) .unmask(0) .copyProperties(img, img.propertyNames()); });
Flicker
เมื่อมีคอลเล็กชันที่มีรูปภาพเพียง 2 รูปดังในกรณีนี้ ภาพกะพริบจะเป็นการแสดงผลเริ่มต้นสำหรับภาพเคลื่อนไหวของคอลเล็กชัน ปรับอาร์กิวเมนต์ภาพเคลื่อนไหว framesPerSecond
เพื่อเร่งหรือชะลออัตราการกะพริบ อาร์กิวเมนต์การแสดงภาพต่อไปนี้ที่ใช้กับคอลเล็กชันด้านบนจะสร้างรูปที่ 8
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define arguments for animation function parameters. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 2, crs: 'EPSG:3857' }; // Display animation to the Code Editor console. print(ui.Thumbnail(tempColVis, videoArgs));
รูปที่ 8 ตัวอย่างการกะพริบของอุณหภูมิพื้นผิวระหว่างเวลา 12:00 น. GMT สำหรับซีกโลกเหนือและช่วงวันเหมาวันช่วงฤดูหนาว
จาง
การเปลี่ยนเฟดระหว่างเลเยอร์ 2 เลเยอร์ทำได้โดยการลดความทึบแสงของเลเยอร์หนึ่งไปพร้อมๆ กับเพิ่มความทึบแสงของอีกเลเยอร์หนึ่งตามลำดับความทึบแสงที่เพิ่มขึ้นจากเกือบ 0 เป็น 1 (รูปที่ 9)
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define a sequence of decreasing opacity increments. Note that opacity cannot // be 0, so near 1 and 0 are used. Near 1 is needed because a compliment is // calculated in a following step that can result in 0 if 1 is an element of the // list. var opacityList = ee.List.sequence({start: 0.99999, end: 0.00001, count: 20}); // Filter the summer and winter solstice images from the collection and set as // image objects. var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first(); var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first(); // Map over the list of opacity increments to iteratively adjust the opacity of // the two solstice images. Returns a list of images. var imgList = opacityList.map(function(opacity) { var opacityCompliment = ee.Number(1).subtract(ee.Number(opacity)); var winterImgFade = winterImg.visualize({opacity: opacity}); var summerImgFade = summerImg.visualize({opacity: opacityCompliment}); return summerImgFade.blend(winterImgFade).set('opacity', opacity); }); // Convert the image list to an image collection; the forward phase. var fadeForward = ee.ImageCollection.fromImages(imgList); // Make a copy of the collection that is sorted by ascending opacity to // represent the reverse phase. var fadeBackward = fadeForward.sort({property: 'opacity'}); // Merge the forward and reverse phase frame collections. var fadeCol = fadeForward.merge(fadeBackward); // Define animation arguments. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 25, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(fadeCol, videoArgs));
รูปที่ 9 ตัวอย่างการจางระหว่างอุณหภูมิพื้นผิวเวลา 12:00 น. GMT สำหรับช่วงหน้าร้อนและช่วงวันเหมายัน
Slider
การเปลี่ยนภาพในแถบเลื่อนจะแสดงและซ่อนเลเยอร์รูปภาพที่อยู่เบื้องหลังทีละน้อย ซึ่งทำได้โดยการปรับความทึบแสงของรูปภาพที่วางซ้อนกันซ้ำๆ ตลอดช่วงลองจิจูด (รูปที่ 10)
เครื่องมือแก้ไขโค้ด (JavaScript)
// Define a sequence of longitude increments. Start and end are defined by the // min and max longitude of the feature to be provided to the region parameter // of the animation arguments dictionary. var lonSeq = ee.List.sequence({start: -179, end: 179, count: 20}); // Define a longitude image. var longitude = ee.Image.pixelLonLat().select('longitude'); // Filter the summer and winter solstice images from the collection and set as // image objects. var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first(); var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first(); // Map over the list of longitude increments to iteratively adjust the mask // (opacity) of the overlying image layer. Returns a list of images. var imgList = lonSeq.map(function(lon) { lon = ee.Number(lon); var mask = longitude.gt(lon); return summerImg.blend(winterImg.updateMask(mask)).set('lon', lon); }); // Convert the image list to an image collection; concealing phase. var sliderColForward = ee.ImageCollection.fromImages(imgList); // Make a copy of the collection that is sorted by descending longitude to // represent the revealing phase. var sliderColbackward = sliderColForward .sort({property: 'lon', ascending: false}); // Merge the forward and backward phase frame collections. var sliderCol = sliderColForward.merge(sliderColbackward); // Define animation arguments. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 25, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(sliderCol, videoArgs));
รูปที่ 10 ตัวอย่างการเปลี่ยนแบบเลื่อนระหว่างอุณหภูมิพื้นผิวเวลา 12:00 น. GMT สำหรับวันเหมาวันช่วงฤดูร้อนและฤดูหนาว