물 발생 (1984~2015년)

GSW 데이터 세트에는 다양한 방식으로 지표수 데이터를 표시하는 여러 데이터 레이어가 포함되어 있습니다. 먼저 1984년 3월부터 2015년 10월까지의 전체 기간 동안 지표수가 발생한 위치와 빈도를 요약하는 수자원 발생 레이어를 시각화합니다.

이 튜토리얼 섹션에서는 다음을 수행합니다.

  1. 지표수 발생을 시각화하는 지도 레이어를 추가하고,
  2. 지도 레이어의 값을 쿼리하는 방법,
  3. 맞춤 스타일을 추가하여 시각화를 개선하고,
  4. 기준점을 사용하여 바이너리 수역 마스크 레이어를 만들고,
  5. 전 세계의 흥미로운 부분을 지도의 중앙에 배치하고
  6. 스크립트를 더 읽기 쉽고 유지보수하기 쉽게 리팩터링하는 방법을 보여줘.

기본 시각화 만들기

먼저 다음 문을 코드 편집기에 복사합니다.

코드 편집기(JavaScript)

var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var occurrence = gsw.select('occurrence');
Map.addLayer(occurrence);

첫 번째 문은 GSW 데이터 세트의 Earth Engine 이미지 객체를 참조하고 gsw라는 변수에 저장합니다. 두 번째 문은 GSW 데이터 세트의 단일 레이어를 선택하고 occurrence라는 변수에 저장합니다. 세 번째 문은 코드 편집기의 대화형 지도에 발생 이미지를 추가합니다.

코드 편집기의 '실행' 버튼을 클릭하면 몇 초 후에 그림 1과 같이 해안선을 따라 회색으로 표시된 지도가 표시됩니다.

기본 시각화
그림 1. 전 세계 지표수 발생 데이터 레이어의 기본 시각화

대부분의 지역에서 GSW 데이터 세트는 투명하게 표시됩니다. Landsat 이미지가 수집되지 않은 위치 (예: 해양 지역) 또는 32년 동안 관측에서 물이 감지되지 않은 위치는 마스킹되기 때문입니다.

값 검사

수면 발생 레이어의 값을 탐색하기 위해 코드 편집기의 검사기 탭을 사용합니다. 먼저 검사기 탭을 클릭한 다음 지도를 클릭하여 위치를 선택합니다. 검사기 탭에는 클릭한 위치에 있는 각 레이어에 관한 정보가 표시됩니다.

검사기 탭
그림 2. 검사기 탭 출력 예시

위의 예에서 value이라는 레이어의 값은 98입니다. 단위는 백분율 포인트이므로 해당 위치가 물로 덮인 것으로 분류된 시간은 약 98% 입니다. 이 값은 각 월별 지표수 발생 값의 평균으로, 데이터 사용자 가이드 (v2) 에 설명된 대로 계절적 변동에 따라 정규화됩니다.

코드 개선을 위한 리팩터링

스크립트에는 두 개의 문만 포함되어 있지만, 최종 스크립트를 더 쉽게 읽고 유지관리할 수 있도록 코드를 리팩터링할 수 있습니다. 현재 Map.addLayer() 문은 지도에 표시하려는 Earth Engine 이미지 객체인 단일 인수 occurrence를 전달합니다. 그러나 Map.addLayer() 메서드를 사용하면 추가 인수를 전달할 수도 있습니다. 사용 가능한 인수를 빠르게 확인하려면 여는 괄호 뒤에 커서를 놓고 '코드 추천 표시' 키보드 단축키를 눌러 addLayer 메서드의 도움말 문서를 표시합니다. (키보드 단축키는 도움말 -> 단축키 메뉴를 선택하여 볼 수 있습니다.)

Map.addLayer 인수
그림 3. addLayer 메서드의 인수를 보여주는 스크린샷

키보드 단축키는 Map.addLayer에 전달할 수 있는 인수가 eeObject, visParams, name, shown, opacity의 5가지임을 보여줍니다. 현재 스크립트에서는 첫 번째 인수 eeObject로 해석되는 단일 변수 occurrence를 전달하고 있습니다. 변수 객체와 레이어 이름을 지정하는 추가 인수를 모두 전달하려면 아래와 같이 JSON 데이터 구조 내에서 메서드에 전달되는 '명명된 인수' (eeObject 및 name)를 사용하도록 코드를 리팩터링하면 됩니다.

코드 편집기(JavaScript)

Map.addLayer({eeObject: occurrence, name: 'Water Occurrence (1984-2015)'});

코드를 다시 실행하여 리팩터링 변경 후에도 계속 작동하는지 확인합니다. 결과 지도는 변경되지 않은 상태로 유지됩니다.

시각화 매개변수 추가

다음으로, 물이 회색으로 표시되는 기본 시각화 매개변수를 개선해 보겠습니다. VIS_OCCURRENCE 변수를 만드는 새 문을 추가하고 이를 addLayer 메서드에 추가 인수로 전달합니다.

코드 편집기(JavaScript)

var VIS_OCCURRENCE = {
  min: 0,
  max: 100,
  palette: ['red', 'blue']
};

코드 편집기(JavaScript)

Map.addLayer({
  eeObject: occurrence.updateMask(occurrence.divide(100)),
  name: 'Water Occurrence (1984-2015)',
  visParams: VIS_OCCURRENCE
});

JSON 구조 VIS_OCCURRENCE에 저장된 시각화 매개변수는 최솟값 0% 에 빨간색을, 최댓값 100%에 파란색을 사용해야 함을 나타냅니다. .updateMask(occurrence.divide(100))를 추가하면 발생 값에 따라 픽셀의 불투명도/투명도가 설정됩니다.

스크립트를 다시 실행하고 스타일 변경으로 수정된 결과를 확인합니다.

지표수 발생
그림 4. 0% 최솟값 엔드포인트에 투명한 빨간색을 사용하고 최댓값 엔드포인트에 단색 파란색을 사용하여 부에노스아이레스 근처 파라나 삼각주의 물 발생을 보여주는 스크린샷

이제 물 영역이 파란색으로 표시됩니다. 이렇게 표시되면 성공적으로 진행하고 있는 것입니다.

임곗값 레이어 만들기

물 발생 이미지에는 0~100%의 값 범위를 사용하여 물이 예상되는 빈도에 관한 정보가 포함됩니다. 하지만 이진수 물 레이어(즉, '물'과 '물 아님')으로 분류하는 데 사용됩니다. 이 간단한 바이너리 레이어를 다른 GSW 레이어를 배치할 수 있는 깔끔한 배경 레이어로 사용합니다. 이 임곗값 레이어는 다음 문을 사용하여 만들 수 있으며, 이 문은 90% 의 임곗값을 사용하여 물과 물이 아닌 것을 구분합니다.

먼저 물 마스크의 스타일 지정 정보를 보관하기 위한 새 시각화 변수 VIS_WATER_MASK를 정의합니다.

코드 편집기(JavaScript)

var VIS_WATER_MASK = {
  palette: ['white', 'black']
};

그런 다음 크거나 같음 비교 연산자 .gt(90)를 사용하여 물 마스크 레이어를 계산한 후 .unmask() 메서드를 사용하여 이전에 마스킹된 영역을 0으로 설정합니다.

코드 편집기(JavaScript)

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

마지막으로 레이어를 지도에 추가합니다. 이 레이어를 다른 모든 레이어 아래에 렌더링하려면 다른 Map.addLayer 문 앞에 다음 문을 배치합니다.

코드 편집기(JavaScript)

Map.addLayer({
  eeObject: water_mask,
  visParams: VIS_WATER_MASK,
  name: '90% occurrence water mask'
});
90% 수역 마스크
그림 5. 부에노스아이레스 인근 파라나 삼각주의 90% 워터 마스크 스크린샷

전 세계의 흥미로운 장소로 이동

화면을 이동하고 확대/축소하여 세상을 탐색하는 것은 재미있지만, 세상은 넓기 때문에 특정 위치로 바로 이동하는 것이 도움이 될 때가 있습니다. 다음은 지표수 측면에서 흥미로운 위치를 보여주는 일련의 문입니다. 한 번에 하나의 문만 주석 처리를 해제하면 스크립트가 실행될 때 해당 위치로 이동합니다.

코드 편집기(JavaScript)

// Uncomment one of the following statements to center the map.
// 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

이는 흥미로운 위치의 일부 샘플에 불과합니다. 원하는 경우 직접 추가해도 됩니다.

다시 리팩터링…

GSW 데이터 세트의 다음 레이어로 이동하기 전에 코드 리팩터링을 조금 더 진행하겠습니다. 구체적으로는 유사한 문을 함께 그룹화하고 코드를 애셋, 상수, 계산, 지도 중앙 정렬, 지도 레이어 추가 섹션으로 나누는 주석을 추가합니다.

최종 리팩터링된 스크립트는 다음과 같습니다.

코드 편집기(JavaScript)

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

var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var occurrence = gsw.select('occurrence');

//////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////

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

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

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

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

// Uncomment one of the following statements to center the map.
// 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
});

다음 섹션에서는 시간이 지남에 따라 물 발생이 어떻게 변화했는지 살펴봅니다.