Earth Engine został zaprojektowany tak, aby podczas wykonywania obliczeń rzadko trzeba było się martwić o projekcje map. Podobnie jak w przypadku skali, projekcja, w której wykonywane są obliczenia, jest określana na podstawie „pobierania”. W szczególności dane wejściowe są wymagane w projekcji wyjściowej. Dane wyjściowe mogą być określane na podstawie parametru funkcji (np. crs), obiektów mapy w edytorze kodu i geemap (które mają projekcję maps
mercator (EPSG:3857)) lub za pomocą wywołania reproject(). Gdy wyświetlasz obrazy w Edytorze kodu lub w bibliotece geemap, dane wejściowe są przesyłane w projekcji Mercatora. Rozważmy tę operację na obrazie MODIS, który ma projekcję sinusoidalną:
Edytor kodu (JavaScript)
// 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');
import ee import geemap.core as geemap
Colab (Python)
# 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
Kolejność operacji w tym przykładowym kodzie przedstawia rysunek 1. Pamiętaj, że rzut danych wejściowych jest określany przez dane wyjściowe, a konkretnie przez rzut maps mercator wyświetlany na mapie w Edytorze kodu. Ta projekcja jest propagowana wstecz przez sekwencję operacji, tak aby dane wejściowe były żądane w projekcji Mercatora, w skali określonej przez poziom powiększenia mapy.
W Earth Engine projekcje są określane przez układ odniesienia przestrzennego (CRS lub parametr crs wielu metod). Projekcję obrazu możesz sprawdzić, wywołując na nim funkcję projection():
Edytor kodu (JavaScript)
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());
import ee import geemap.core as geemap
Colab (Python)
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())
Pamiętaj, że wywołując nominalScale() na obiekcie ee.Projection zwróconym przez projection(), możesz określić natywną rozdzielczość obrazu. Rozdzielczość natywna to nominalna skala pikseli w metrach na najniższym poziomie piramidy obrazu. Każde pasmo obrazu może mieć inną skalę lub projekcję, więc jeśli wywołasz projection() na obrazie z co najmniej 1 pasmem, które nie ma takiej samej projekcji jak pozostałe, może pojawić się błąd podobny do tego:
domyślna projekcja,
Jeśli nie potrzebujesz obliczeń w określonej projekcji, zwykle nie musisz jej podawać. Tylko w przypadku niejednoznacznych danych wyjściowych Earth Engine wymaga określenia projekcji lub skali. Niejednoznaczność może wynikać ze zmniejszenia ImageCollection zawierającego obrazy z różnymi projekcjami (czyli utworzenia kompozycji). Obraz, który jest kompozycją lub mozaiką obrazów wejściowych o różnych rzutach, będzie miał domyślną projekcję, czyli WGS84 w skali 1 stopnia.
Na przykład:
Edytor kodu (JavaScript)
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA'); var mosaic = collection.filterDate('2018-01-01', '2019-01-01').mosaic(); print(mosaic.projection());
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') mosaic = collection.filterDate('2018-01-01', '2019-01-01').mosaic() display(mosaic.projection())
Jeśli spróbujesz użyć takiego obrazu w obliczeniach, może pojawić się błąd podobny do tego:
Zwykle agregacja w skali 1 stopnia nie jest pożądana ani zamierzona, dlatego Earth Engine wyświetla to przypomnienie, aby podać pełną specyfikację danych wyjściowych.
Użytkownicy często są zdezorientowani takim zachowaniem i martwią się o „utracone” informacje o projekcji, ale piksele nie są w rzeczywistości obliczane, dopóki nie są potrzebne (więcej informacji). W takim przypadku zawsze występuje projekcja wyjściowa, która towarzyszy żądaniu i określa sposób obliczania kompozycji.
W większości przypadków brak projekcji nie stanowi problemu, a wręcz jest cenną optymalizacją, ponieważ umożliwia wyświetlanie podglądu wyników na dowolnym poziomie powiększenia bez konieczności czekania na zakończenie obliczeń w pełnej rozdzielczości. Oznacza to jednak, że dane wyjściowe mogą wyglądać inaczej przy różnych poziomach powiększenia.
Jeśli zoptymalizowany obraz wyświetlany jest niewystarczający, można wymusić obliczenia w określonej projekcji, ponownie rzutując dane wyjściowe zgodnie z opisem w następnej sekcji.
Przekształcanie
Możesz wymusić wykonanie operacji w określonej projekcji za pomocą metody reproject(). Użycie reproject() powoduje, że dane wejściowe są wymagane w projekcji określonej w wywołaniu reproject().
Obliczenia w kodzie przed wywołaniem funkcji reproject() zostaną wykonane w określonym rzutowaniu. Jeśli na przykład chcesz wymusić utworzenie kompozycji w określonej projekcji:
Edytor kodu (JavaScript)
// Some projection that is suitable for your area of interest. var proj = ee.Projection(...); var output = collection.reduce(...).reproject(proj);
import ee import geemap.core as geemap
Colab (Python)
# Some projection that is suitable for your area of interest. proj = ee.Projection(...) output = collection.reduce(...).reproject(proj)
Oto kilka przypadków, w których wymagana jest stała projekcja:
- Obliczanie gradientów (np.
ee.Terrain.gradientlubee.Terrain.slope). reduceResolution, gdy chcesz agregować piksele o wyższej rozdzielczości w piksele o niższej rozdzielczości. (Więcej informacji o zmniejszaniu rozdzielczości)
Istnieje kilka powodów, dla których należy unikać używania reproject(), chyba że jest to absolutnie konieczne. Załóżmy na przykład, że przekształcasz coś i dodajesz to do mapy. Jeśli skala określona w wywołaniu reproject() jest znacznie mniejsza niż poziom powiększenia mapy, Earth Engine zażąda wszystkich danych wejściowych w bardzo małej skali na bardzo dużym obszarze. Może to spowodować, że jednocześnie zostanie wysłanych zbyt wiele żądań danych, co doprowadzi do błędu.
Jeśli wynikowy obraz jest w innym odwzorowaniu niż określone w wywołaniu reproject(), spowoduje to kolejne przekształcenie. To kolejny powód, dla którego należy zachować ostrożność podczas używania reproject() w kodzie. Rozważmy ten przykład, który wymusza najpierw ponowne przekształcenie obrazu MODIS do układu WGS84, a następnie do układu maps mercator w celu wyświetlenia na mapie w edytorze kodu:
Edytor kodu (JavaScript)
// 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');
import ee import geemap.core as geemap
Colab (Python)
# 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
Na rysunku 2 przedstawiono diagram przepływu operacji odpowiadających temu prostemu przykładowi ponownego rzutowania. Pamiętaj, że pierwsze ponowne przekształcenie jest jawne, zgodnie z wywołaniem reproject(). Druga reprojekcja jest niejawna i wykonywana automatycznie przez Earth Engine w celu wyświetlenia wyniku na mapie. Zwróć też uwagę, że informacje o tym, jakiej projekcji użyć, są przekazywane z powrotem z żądania do danych wejściowych.