클라이언트와 서버 비교

PythonJavaScript용 Earth Engine 클라이언트 라이브러리는 복잡한 지리정보 분석을 Earth Engine 요청으로 변환합니다. 클라이언트 라이브러리용으로 작성한 코드에는 클라이언트 측 객체 참조와 서버 측 객체를 나타내는 변수가 혼합되어 있을 수 있습니다.

Earth Engine 객체를 코드에 있을 수 있는 다른 Python 또는 JavaScript 객체 또는 프리미티브와 구분하는 것이 중요합니다. 스크립트에서 클라이언트 측 '프록시' 객체를 조작하여 서버의 객체를 조작할 수 있습니다. 프록시 객체는 ee로 시작하는 모든 것으로 인식할 수 있습니다. 이러한 Earth Engine 프록시 객체는 실제 데이터를 포함하지 않으며 서버의 객체에 대한 핸들일 뿐입니다. 시작하려면 프록시 객체가 아닌 클라이언트 측 문자열 객체를 고려해 보세요.

코드 편집기 (JavaScript)

var clientString = 'I am a String';
print(typeof clientString);  // string

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

client_string = 'I am a String'
print(type(client_string))  # str

출력에서 클라이언트 (웹브라우저 또는 노트북)가 이 코드를 해석하고 실행하여 변수가 string 유형임을 확인한 것을 확인합니다. 이제 Earth Engine에서 이 문자열로 작업을 실행할 수 있다고 가정해 보겠습니다. 이렇게 하려면 문자열을 적절한 컨테이너로 래핑하여 Google에 전송해야 합니다. 이 컨테이너가 프록시 객체입니다. 예를 들면 다음과 같습니다.

코드 편집기 (JavaScript)

var serverString = ee.String('I am not a String!');
print(typeof serverString);  // object
print('Is this an EE object?',
    serverString instanceof ee.ComputedObject);  // true

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

server_string = ee.String('I am not a String!')
print(type(server_string))  # ee.ee_string.String
print(
    'Is this an EE object?', isinstance(server_string, ee.ee_string.String)
)  # True

출력에서 ee.Stringstring가 아닌 object임을 확인합니다. 더 구체적으로는 ee.computedObject이며, 이는 서버의 항목에 대한 프록시 객체임을 의미합니다. ee.Thing는 Google에 전송하기 위해 항목을 컨테이너에 넣는 방법이라고 생각하면 됩니다. 클라이언트는 컨테이너에 무엇이 있는지 알 수 없지만 다음과 같이 인쇄하여 내용물을 확인할 수 있습니다.

코드 편집기 (JavaScript)

print(serverString);  // I am not a String

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

print(server_string.getInfo())  # I am not a String

컨테이너 자체가 어떻게 표시되는지 확인하려면 객체의 문자열 표현을 출력합니다.

코드 편집기 (JavaScript)

print(serverString.toString());  // ee.String("I am not a String!")

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

print(server_string)  # ee.String({"constantValue": "I am not a String!"})

어떤 이유로든 클라이언트에서 실행되는 Python 또는 JavaScript를 사용하여 컨테이너에 있는 항목을 조작해야 하는 경우 getInfo()를 사용하여 컨테이너의 콘텐츠를 가져와 변수에 할당합니다.

코드 편집기 (JavaScript)

var someString = serverString.getInfo();
var strings = someString + '  Am I?';
print(strings);  // I am not a String!  Am I?

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

some_string = server_string.getInfo()
strings = some_string + '  Am I?'
print(strings)  # I am not a String!  Am I?

연속 재생

클라이언트는 서버 측 ee.Thing 객체에 무엇이 있는지 알 수 없으므로 조건문 및 for 루프와 같은 클라이언트 측 작업은 서버 측 ee.Thing 객체에서 작동하지 않습니다. 따라서 getInfo()의 동기 호출을 방지하려면 최대한 서버 함수를 사용하세요. 예를 들어 다음 두 가지 목록 생성 방법을 고려해 보겠습니다.

권장하지 않음: 클라이언트 측 for 루프

코드 편집기 (JavaScript)

var clientList = [];
for(var i = 0; i < 8; i++) {
  clientList.push(i + 1);
}
print(clientList);

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

client_list = []
for i in range(8):
  client_list.append(i + 1)
print(client_list)

권장: 서버 측 매핑

코드 편집기 (JavaScript)

var serverList = ee.List.sequence(0, 7);
serverList = serverList.map(function(n) {
  return ee.Number(n).add(1);
});
print(serverList);

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

server_list = ee.List.sequence(0, 7)
server_list = server_list.map(lambda n: ee.Number(n).add(1))
print(server_list.getInfo())

서버 측 매핑 예시는 ee.List.sequence(1, 8)만으로 동일한 목록을 만들 수 있으므로 약간 어색하지만 몇 가지 중요한 개념을 보여줍니다. 첫 번째 개념은 map()로, 목록의 모든 항목에 동일한 함수를 적용합니다. 이 함수는 서버에서 실행되므로 getInfo()print()와 같은 클라이언트 측 함수는 매핑된 함수에서 작동하지 않습니다. 따라서 i + 1 코드를 상응하는 서버 측 코드인 ee.Number(n).add(1)로 대체해야 합니다. 중요한 점은 n는 서버에만 존재하는 객체라는 것입니다. 함수는 인수의 유형을 알 수 없으므로 ee.Number로 변환해야 합니다.

클라이언트에서 실행되는 함수에 관한 설명은 클라이언트 및 서버 함수 섹션을 참고하세요.

클라이언트 측 기능이 편리한 경우도 있습니다. 예를 들어 이전 for 루프를 사용하여 목록을 빌드하고 서버 측 객체로 래핑할 수 있습니다.

코드 편집기 (JavaScript)

var toServerList = ee.List(clientList);

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

to_server_list = ee.List(client_list)

클라이언트 측 처리는 노트북이나 브라우저, 즉 호스트 머신의 CPU에서 실행되므로 Earth Engine을 사용하여 서버에서 작업하는 것보다 효율성이 떨어질 수 있습니다. 또한 예상치 못한 결과를 방지하려면 스크립트에서 클라이언트 기능과 서버 기능을 혼합하지 않는 것이 좋습니다. 조건문 섹션에서는 의도하지 않은 결과가 발생할 수 있는 예시를 제공합니다.

조건부

서버 측 객체가 클라이언트 측 함수와 반드시 호환되는 것은 아니며 그 반대의 경우도 마찬가지입니다. 예를 들어 서버 측 불리언 변수의 경우를 생각해 보겠습니다.

코드 편집기 (JavaScript)

var myList = ee.List([1, 2, 3]);
var serverBoolean = myList.contains(5);
print(serverBoolean);  // false

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

my_list = ee.List([1, 2, 3])
server_boolean = my_list.contains(5)
print(server_boolean.getInfo())  # False

다음 예와 같이 이 변수는 서버 측 객체이므로 클라이언트 측 조건문에서 작동하지 않습니다. 서버 측 불리언을 올바르게 확인하려면 서버 측 함수를 사용하세요.

권장하지 않음: 클라이언트 측 조건문

코드 편집기 (JavaScript)

var clientConditional;
if (serverBoolean) {
  clientConditional = true;
} else {
  clientConditional = false;
}
print('Should be false:', clientConditional);  // True!

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

if server_boolean:
  client_conditional = True
else:
  client_conditional = False
print('Should be False:', client_conditional)  # True!

권장: 서버 측 조건문

코드 편집기 (JavaScript)

var serverConditional = ee.Algorithms.If(serverBoolean, 'True!', 'False!');
print('Should be false:', serverConditional);  // False!

Python 설정

Python API 및 대화형 개발을 위한 geemap 사용에 관한 자세한 내용은 Python 환경 페이지를 참고하세요.

import ee
import geemap.core as geemap

Colab (Python)

server_conditional = ee.Algorithms.If(server_boolean, 'True!', 'False!')
print('Should be False:', server_conditional.getInfo())  # False!

클라이언트 및 서버 함수

이전 섹션에서는 클라이언트 객체와 서버 객체 및 함수를 혼합하는 것이 비효율적이거나 비논리적인 이유를 여러 가지 설명했습니다. 어떤 객체와 함수가 클라이언트 측이고 서버 측인가요? 일반적으로 ee.Thing로 초기화된 모든 항목은 서버 객체이고 이 객체의 모든 메서드(ee.Thing.method())는 서버 함수입니다. Python 또는 JavaScript 참조에 표시되는 객체와 함수는 클라이언트 측입니다. 앞서 언급한 대로 클라이언트 측 기능을 사용하여 객체를 만든 다음 Earth Engine 생성자(예: ee.String())에 클라이언트 측 객체를 제공하여 래핑할 수 있습니다.