0

I have a problem with Python API of Google Earth Engine.

I'm trying to create a vector mask of a small area based on NDVI. I take Sentinel-2 data as two bands and pass a rectangle (defined as series of hand-picked coordinates) to constrict the ROI. When I try to run the attached code I get an error message:

  File "C:/files/test.py", line 24, in ndROI
    ndviVectors = ndviMask.reduceToVectors(ROIgeometry, 10, 'label') # At this point the "EEException" is thrown
...

  File "C:\Users\glowa\Miniconda2\lib\site-packages\ee\geometry.py", line 83, in __init__
    raise ee_exception.EEException('Invalid GeoJSON geometry.')

EEException: Invalid GeoJSON geometry.

Apparently the constructor returns an invalid polygon, although when printed it looks fine. How can I make sure, that geometries are correct? What I tried and had no success with were:

  • different CRS and different parameter setup
  • different coordinate declarations (3 levels of brackets and two)
  • different places
  • even replacing Polygon function with Rectangle function (and changing coordinate format accordingly)

all ending up with the same exception

I'm using GEE Python package installed in Miniconda on Windows 10. Below the problematic code.

import ee

ee.Initialize()

# Define function, which produces a NDVI-based vector ROI
def ndROI(imgName,rectROI,diffBand1, diffBand2):

    # Production of rectangle limiting ROI - it's a ee.geometry defined from coordinates and staying in the GEE.
    ROIgeometry = ee.Geometry.Polygon(rectROI, False, 0, True)
    print ROIgeometry
    # Land looks similar to ice - do NDVI from Sentinel 2 to mask away. Get S2 from the latest time, compute ndvi, export. Will do once.
    s1forNDVI = ee.Image(imgName) # Choose nicest scene by hand
    ndvi = s1forNDVI.normalizedDifference([diffBand1, diffBand2]) # select proper bands of sentinel
    ndviMask = ndvi.gte(0.2).updateMask(ndvi.lte(0.2)) # Mask greater-than-0.2, that is plants have 1, water and ice have 0.

    # Vectorise NDVI
    ndviVectors = ndviMask.reduceToVectors(ROIgeometry, 10, 'label') # At this point the "EEException" is thrown
    ndviResultGeometry = ee.FeatureCollection(ndviVectors).geometry(); # convert NDVI product to feature collection and take its geometry
    return ndviResultGeometry

# Define inputs
imgName = 'COPERNICUS/S2/20150817T095016_20160923T153347_T34UDE'
rectROI = [[20.1149, 53.8063], [20.1369, 53.8063], [20.1369, 53.7913], [20.1149, 53.7913], [20.1149, 53.8063]]
diffBand1 = 'B8'
diffBand2 = 'B4'

# Run function
eeNDVIpoly = ndROI(imgName,rectROI,diffBand1, diffBand2)
1

You have to be careful with *args and **kwargs. Your code runs fine after you fix that. Except when constructing the Polygon, in which case I think there is a bug in the API (I reported it to developers).

import ee

ee.Initialize()

# Define function, which produces a NDVI-based vector ROI
def ndROI(imgName,rectROI,diffBand1, diffBand2):

    # Production of rectangle limiting ROI - it's a ee.geometry defined from coordinates and staying in the GEE.
    ROIgeometry = ee.Geometry.Polygon(rectROI, 
                                      # geodesic=False, 
                                      # maxError=0, 
                                      # evenOdd=True
                                     )
    print(ROIgeometry.getInfo())
    # Land looks similar to ice - do NDVI from Sentinel 2 to mask away. Get S2 from the latest time, compute ndvi, export. Will do once.
    s1forNDVI = ee.Image(imgName) # Choose nicest scene by hand
    ndvi = s1forNDVI.normalizedDifference([diffBand1, diffBand2]) # select proper bands of sentinel
    ndviMask = ndvi.gte(0.2).updateMask(ndvi.lte(0.2)) # Mask greater-than-0.2, that is plants have 1, water and ice have 0.

    # Vectorise NDVI
    ndviVectors = ndviMask.reduceToVectors(geometry=ROIgeometry, 
                                           scale=10, 
                                           labelProperty='label')
    ndviResultGeometry = ee.FeatureCollection(ndviVectors).geometry(); # convert NDVI product to feature collection and take its geometry
    return ndviResultGeometry

# Define inputs
imgName = 'COPERNICUS/S2/20150817T095016_20160923T153347_T34UDE'
rectROI = [[20.1149, 53.8063], [20.1369, 53.8063], [20.1369, 53.7913], [20.1149, 53.7913], [20.1149, 53.8063]]
diffBand1 = 'B8'
diffBand2 = 'B4'

# Run function
eeNDVIpoly = ndROI(imgName,rectROI,diffBand1, diffBand2)

If you switch to python3 you could even visualize it.

enter image description here

  • Thank you, it works! I wouldn't think, that this thing would make a difference. I also did not know, that one can set up map for looking up results so easily and that GEE is available for Python 3. Your answer is very informative. – Julian_P Feb 5 at 19:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.