AI-generated Key Takeaways
- 
          
Earth Engine typically handles map projections automatically, determining the computation projection based on the output.
 - 
          
The output projection can be set by function parameters, map objects, or a
reproject()call. - 
          
Image projections and their nominal scale can be checked using the
projection()andnominalScale()methods. - 
          
Image collections reduced into composites or mosaics with different projections will have a default WGS84 projection with a 1-degree scale.
 - 
          
The
reproject()method can be used to force computations in a specific projection, but should be used cautiously as it can lead to errors or multiple rejections. 
Earth Engine is designed so that you rarely have to worry about map projections when
      doing computations.  As with scale, the projection in which computations take place is
      determined on a "pull" basis.  Specifically, inputs are requested in the output
      projection.  The output may be determined from a function parameter (e.g. crs),
      Code Editor and geemap map objects (which have a maps
      mercator (EPSG:3857) projection), or with a reproject() call.  When you
      display images in the Code Editor or geemap, inputs are requested in
      maps mercator.  Consider the
      following simple operation on a MODIS image, which has a
      sinusoidal projection:
Code Editor (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
The order of operations for this code sample is diagrammed in Figure 1. Note that the projection of the input is determined by the output, specifically the maps mercator projection of the map display in the Code Editor. This projection propagates back through the sequence of operations such that the inputs are requested in maps mercator, at a scale determined by the zoom level of the map.
      In Earth Engine, projections are specified by a Coordinate Reference System (CRS or
      the crs parameter of many methods). You can check the projection of an
      image by calling projection() on it:
Code Editor (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())
Note that by calling nominalScale() on the ee.Projection returned
      by projection(), you can determine the native resolution of the image.  The
      native resolution is the nominal pixel scale in meters of the lowest level of the
      image pyramid.  Because each band of an image can have a
      different scale and/or projection, if you call projection() on an image
      with at least one band that doesn't have the same projection as the others, you may see an
      error like:
The default projection
Unless you need your computation to occur in a specific projection, there is generally
      no need to specify a projection.  Only for output that's ambiguous will Earth Engine
      require you to specify a projection and/or scale.  Ambiguity can result from
      reducing an ImageCollection containing images with different projections
      (i.e. creating a composite).  An image which is a
      composite or mosaic of input images with different projections will have the default
      projection, which is WGS84 with 1-degree scale.
      For example:
Code Editor (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())
If you try to use an image like this in a computation, you may see an error like:
Generally, an aggregation at 1-degree scale is not desired or intended, so Earth Engine gives this friendly reminder to provide a complete specification for the output.
Users often find this behavior confusing and worry about the "lost" projection information, but the pixels aren't actually computed until they're needed (learn more), and at that point, there's always an output projection that accompanies the request that specified how to compute the composite.
In the vast majority of use cases, having no projection is not a problem and is actually a valuable optimization, as it allows previewing the results at any zoom level without having to wait for the full resolution computation to complete. But it does mean that the output can appear different at different zoom levels.
If the optimized display image somehow isn't sufficient, computation in a specific projection can be forced by reprojecting the output as described in the following section.
Reprojecting
You can force operations to be performed in a specific projection with the
      reproject() method.  Using reproject() results in the inputs
      being requested in the projection specified in the reproject() call.
      Computations in your code before the reproject() call will be done
      in the specified projection.  For example, to force a composite to be produced in a
      specific projection:
Code Editor (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)
A few cases that require a fixed projection include:
- Computing gradients (e.g. 
ee.Terrain.gradientoree.Terrain.slope). reduceResolution, for when you want to aggregate higher resolution pixels into lower resolution. (Learn more about reducing resolution).
There are several reasons you should avoid using reproject() unless you
      absolutely need to.  Suppose, for example, you reproject something and add it to the
      map.  If the scale you specified in the reproject() call is much smaller
      than the zoom level of the map, Earth Engine will request all the inputs at very small
      scale, over a very wide spatial extent.  This can result in much too much data being
      requested at once and lead to an error.
If the eventual output is in a different projection from that specified in the
     reproject() call, that will result in another reprojection.  This is
     another reason to be cautious about using reproject() in your code.  Consider
     the following example, which forces the MODIS image to first be reprojected to
     WGS84, then reprojected to
     maps mercator for display in the Code Editor map:
Code Editor (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
Figure 2 diagrams the flow of operations corresponding to this simple reprojection
      example.  Note that the first reprojection is explicit, as specified in the
      reproject() call.  The second reprojection is implicit, performed by
      Earth Engine automatically in order to display the result on the map.  Also observe that the
      information about what projection to use propagates back from the request to the input.