3

I want to use the list of the LMIC countries (Low and medium incomes country) to check if a given AOI is inside this list.

I have created a FeatureCollection (users/bornToBeAlive/lmic) that is listing all these countries.

I wanted to test assertion using a contains method on the geometry of both the aoi and the lmic list.

Problem when I run it (https://code.earthengine.google.com/762caa3fc44d220247e8ffea32762b15):

var lmic = ee.FeatureCollection('users/bornToBeAlive/lmic')
var in_geom = ee.Geometry.BBox(
    -102.73006885614397, 
    22.35983420356853, 
    -100.44491260614397, 
    24.85613968556801
)
lmic.geometry().contains(in_geom) //expected True

I get the following error:

Collection.geometry: Geometry has too many edges (3378987 > 2000000).

I would like to know how I can perform this kind of test?

Note
I have already tested to do it feature by feature but it doesn't serve my purpose as it throw False if the aoi is overlapping on 2 countries (from LMIC list).

1 Answer 1

3

.geometry() has to compute a single large geometry that is a union of the features' geometries. I suggest starting by selecting only the features from lmic that might contribute to containing in_geom:

lmic.filterBounds(in_geom).geometry().contains(in_geom)

That way, any features in lmic that definitely don't intersect in_geom won't be added to the union, keeping it smaller.


You will also need to specify an errorMargin value for contains:

var margin = 1000; // 1 km (for example)
print(lmic.filterBounds(in_geom).geometry().contains(in_geom, margin)) // True
print(lmic.filterBounds(out_geom).geometry().contains(out_geom, margin)) // False
print(lmic.filterBounds(between_geom).geometry().contains(between_geom, margin)) // False

If you need to do this repeatedly, you could write a function to contain the code pattern:

function collectionContains(collection, geometry) {
  return collection.filterBounds(geometry).geometry().contains(geometry, 1000);
}

print(collectionContains(lmic, in_geom));

However, this doesn't quite satisfy your goal of returning true for regions that are covered by two countries, because the adjacent borders won't necessarily be counted as exactly overlapping (due to imprecisions in geometry computation and the original data). In order to fix that, we need to do one more thing: buffer() the collection geometry, which will slightly enlarge it to get the borders to fuse together.

collection
    .filterBounds(geometry)
    .geometry()
    .buffer(margin, margin / 2)
    .contains(g, margin)

Note that the combination of the buffering and the error margin on both operations will mean some AOIs are counted as inside the country when they aren't. You will have to choose a distance at which this is an acceptable error and still feasible to compute.

Note: I've learned that this is a poor strategy, since buffer() is an expensive algorithm. It would be better to use difference() to delete all the countries from the AOI geometry, and then check if any significant area() was left uncovered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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